`
mmdev
  • 浏览: 13244058 次
  • 性别: Icon_minigender_1
  • 来自: 大连
文章分类
社区版块
存档分类
最新评论

【.Net MF深入研究】中断处理机制

 
阅读更多

.Net Micro Framework的中断处理机制相对比较简单,不支持中断嵌套,中断优先级功能的实现由相关硬件提供支持,软件层面仅仅进行相关优先级的设定即可。

下面以TI DM335开发板为例简单介绍一下相关技术细节(这里仅介绍普通中断IRQ)。

1 中断向量表

我们知道中断向量表一般默认的存放在内存0起始地址处。

先让我们在NativeSampleTinyCLR目录中找到Scatterfile_tools_xxx.xml文件,我们会发现在其中都会有如下这么一段文字:

<ExecRegion Name="ER_RAM_RO" Base="0x00000000" Options="ABSOLUTE" Size="0x1A000">

<FileMapping Name="VectorsTrampolines.obj" Options="(+RO, +FIRST)" />

</ExecRegion>

这是一个编译选项,告诉ARM编译器,连接时把VectorsTrampolines.obj的相关内容放在位置0处(我们可以用WinHex查看编译后的Bin文件,我们会发现Bin文件中最开始的内容就是中断向量表的内容)。

下面是VectorsTrampolines.s文件的汇编代码:

;**************************************************************************

IMPORT UNDEF_SubHandler

IMPORT ABORTP_SubHandler

IMPORT ABORTD_SubHandler

IMPORT IRQ_Handler ; from stubs.cpp

EXPORT ARM_Vectors

;**************************************************************************

AREA |.text|, CODE, READONLY

; ARM directive is only valid for ARM/THUMB processor, but not CORTEX

IF :DEF:COMPILE_ARM :LOR: :DEF:COMPILE_THUMB

ARM

ENDIF

ARM_Vectors

; RESET

RESET_VECTOR

b UNDEF_VECTOR

; UNDEF INSTR

UNDEF_VECTOR

ldr pc, UNDEF_SubHandler_Trampoline

; SWI

SWI_VECTOR

DCD 0xbaadf00d

; PREFETCH ABORT

PREFETCH_VECTOR

ldr pc, ABORTP_SubHandler_Trampoline

; DATA ABORT

DATA_VECTOR

ldr pc, ABORTD_SubHandler_Trampoline

; unused

USED_VECTOR

DCD 0xbaadf00d

; IRQ

IRQ_VECTOR

ldr pc, IRQ_SubHandler_Trampoline

; FIQ

; we place the FIQ handler where it was designed to go, immediately at the end of the vector table

; this saves an additional 3+ clock cycle branch to the handler

FIQ_Handler

IF :DEF: FIQ_SAMPLING_PROFILER

ldr pc,FIQ_SubHandler_Trampoline

FIQ_SubHandler_Trampoline

DCD FIQ_SubHandler

ENDIF

UNDEF_SubHandler_Trampoline

DCD UNDEF_SubHandler

ABORTP_SubHandler_Trampoline

DCD ABORTP_SubHandler

ABORTD_SubHandler_Trampoline

DCD ABORTD_SubHandler

; route the normal interupt handler to the proper lowest level driver

IRQ_SubHandler_Trampoline

DCD IRQ_Handler

;**************************************************************************

从中我们可以看出,当硬件触发IRQ中断时,跳转的最终位置为IRQ_Handler

【疑问】中断向量表的内容最开始的时候一定是存放在Flash(或其它存储介质)中,它是如何被转移到内存0处的呢(当然调试时也可以通过调试器把中断向量表直接Download到内存中去)?

【解答】在FirstEntry.s汇编代码中有这么一句代码 bl BootstrapCode”,BootstrapCode是一个子函数,该函数优先于“b BootEntry”执行,在BootstrapCode函数中又调用了一个子函数PrepareImageRegions,在PrepareImageRegions函数中我们就可以看到拷贝中断向量表的相关代码:

UINT32* src = (UINT32*)&LOAD_RAM_RO_BASE;

UINT32* dst = (UINT32*)&IMAGE_RAM_RO_BASE;

UINT32 len = (UINT32 )&IMAGE_RAM_RO_LENGTH + (UINT32)&Image$$ER_RAM_RW$$Length;

Prepare_Copy( src, dst, len );

注:FIQ_SAMPLING_PROFILER选项是没有定义的,所以在DM335开发板上支持FIQ是有问题的。

2 中断函数(IRQ_Handler

中断向量表一经设置,则触发相关中断时,CPU会把PC指针指到相关的入口地址处,对IRQ中断来说,其入口地址就是IRQ_Handler

DM335平台,IRQ_Handler函数的内容如下:

void __irq IRQ_Handler(void)

{

DM335_INTC_Driver::IRQ_Handler();

}

void /*__irq*/DM335_INTC_Driver::IRQ_Handler(void)

{

DM335_INTC &pAic = DM335::INTC();

unsigned int index;

// set before jumping elsewhere or allowing other interrupts

SystemState_SetNoLock(SYSTEM_STATE_ISR);

SystemState_SetNoLock(SYSTEM_STATE_NO_CONTINUATIONS);

while(pAic.IRQENTRY != 0x0)

{

index = (pAic.IRQENTRY>>2) - 1;

if(index < 32)

pAic.IRQ0 |= 1 << index;

else

pAic.IRQ1 |= 1 << (index % 32);

s_IsrTable[index].Handler.Execute(); //执行对应的中断处理函数

}

SystemState_ClearNoLock(SYSTEM_STATE_NO_CONTINUATIONS); // nestable

SystemState_ClearNoLock(SYSTEM_STATE_ISR); // nestable

}

在中断函数执行之前,其实已经执行了中断寄存器的初始工作,比如根据需要打开或关闭(Enable/Disable)相关的中断,对我们的应用来说串口和USB的中断是要打开的,而DMA中断就是关闭的。此外根据你应用的需求,你也可以设置不同中断的优先级(0~7,其中0~1对应快速中断,对我们来说由于快速中断无效,所以中断的优先级最高可设为2)。

相同等级的中断同时来到,是谁来排序呢?

DM335来说,是由硬件完成的,DM335提供一个寄存器IRQENTRYIRQENTRY寄存器中存放的值,就是下一个要执行的中断号(要经过一定的换算),该寄存器就像一个队列的出队口,排好队的中断依次出列,直到IRQENTRY的值为0为止(表示当前队列中没有任何中断被触发)。

(当然我们也可以直接根据IRQ0IRQ1中的值触发二级中断函数,但是这样来做,设定的中断优先级就没有任何意义了。)

这时候我们就可以根据不同的中断号,执行相对应的二级中断函数了。

那中断来了,程序是如何知道该执行那个二级中断函数呢?请看下一节内容就明白了。

3 中断连接函数

CPU_INTC_ActivateInterrupt函数是把硬件的中断号和要执行的中断函数联系起来,其原型是:

BOOL CPU_INTC_ActivateInterrupt(UINT32 Irq_Index, HAL_CALLBACK_FPN ISR, void *ISR_Param)

Irq_Index – 中断号(可根据相关硬件手册进行设定)

ISR – 该中断触发时所要执行的中断函数

ISR_Param –中断函数的入口参数(可以为空)

当然根据需要也可以断开这种连接,或关掉相应的中断,这些函数由于比较好理解,所以这里就不过多介绍了。

我们以USB驱动为例,简单介绍一下CPU_INTC_ActivateInterrupt函数的使用,在USB的初始化函数中,我们添加了如下代码:

CPU_INTC_ActivateInterrupt(DM335_INTC::c_IRQ_Index_USBINT, Global_ISR, NULL);

其中断函数Global_ISR的部分代码如下:

void DM335_USB_Driver::Global_ISR(void *Param)

{

DM335_USB &usb = DM335_USB::Type();

UINT32 endpoint = 0;

UINT32 tmp = usb.Base.INTSRCR;

usb.Base.INTCLRR = usb.Base.INTSRCR;

//在这里面就可以根据USB相关寄存器的值,确定那一个中断被触发了

// … …

}

这样一层一层,由根到枝,按图索骥,获知实际的中断,并最终执行相关的处理代码(如接收数据或发送数据等等)。

4 中断控制

Porting Kit提供的样例代码中,我们会在中断函数中看到不少GLOBAL_LOCK(irq)代码,由于MF目前不支持中断嵌套,所以从某种意义上说,在中端函数中添加代码GLOBAL_LOCK(irq)是没有意义的(对IRQ中断来说,CPU在触发该中断时,就已经关闭了IRQ中断位,除非你在中断函数中又打开了,当然你这样做的目的一般就是支持中断嵌套了,这部分内容暂不在讨论之列)。

GLOBAL_LOCK是一个宏,其实现为:

#define GLOBAL_LOCK(x) SmartPtr_IRQ x

SmartPtr_IRQ类的代码为:

class SmartPtr_IRQ

{

UINT32 m_state;

void* m_context;

public:

SmartPtr_IRQ(void* context=NULL) { m_context = context; Disable(); }

~SmartPtr_IRQ() { Restore(); }

}

void SmartPtr_IRQ::Disable()

{

UINT32 Cp;

UINT32 Cs;

__asm

{

MRS Cp, CPSR

ORR Cs, Cp, #0x80

MSR CPSR_c, Cs

}

m_state = Cp;

}

void SmartPtr_IRQ::Restore()

{

UINT32 Cp = m_state;

if((Cp & DISABLED_MASK) == 0)

{

ASSERT_SYSTEM_IRQ_MODE(Cp);

__asm

{

MRS Cp, CPSR

BIC Cp, Cp, #0x80

MSR CPSR_c, Cp

}

}

}

由以上代码可知,定义SmartPtr_IRQ的实例的同时,就执行了构造函数,也就是执行了Disable函数(关闭IRQ中断)。换句话说,GLOBAL_LOCK(irq)代码的作用就是,在irq的生命周期内关闭IRQ中断。

相信,如果MF的后续版本开始支持中断嵌套,该部分的内容才会变的复杂。

5 补充说明

MF应用程序(C#)中的中断(或事件函数)其实和我们这章内容所说的中断不是一会事,由以上内容我们可以了解到,中断函数串序执行,所以每一个中断函数执行时间尽量短,否则整个系统的效率便会大大降低。所以我们上层的事件函数是不可能直接勾连在中端函数内,因为在实际的应用中,我们非常有可能在事件函数中执行很多耗时的操作的。实际上TinyCLR代码对这两部分进行了一定得隔离处理,等我们有时间在一一剖析相关的实现机理。

除了中断函数被执行外,对嵌入式应用来说剩下的也就是一个Main函数(对MF来说就是ApplicationEntryPoint)和一个while循环了。对于我们的TinyCLR来说其实就是一个在相对简陋的操作系统上的一个精彩应用而已:

void ApplicationEntryPoint()

{

CLR_SETTINGS clrSettings;

memset(&clrSettings, 0, sizeof(CLR_SETTINGS));

clrSettings.MaxContextSwitches = 50;

#if !defined(BUILD_RTM)

clrSettings.PerformGarbageCollection = false;

clrSettings.PerformHeapCompaction = false;

#endif

clrSettings.WaitForDebugger = false;

ClrStartup( clrSettings );

#if !defined(BUILD_RTM)

debug_printf( "Exiting./r/n" );

#else

::CPU_Reset();

#endif

}

分享到:
评论

相关推荐

    .Net MF 模拟器

    通过这个模拟器,开发者可以深入学习.NET MF平台的各个方面,包括编程模型、内存管理、硬件抽象层(HAL)的使用,以及如何设计适应不同硬件环境的软件。此外,它还提供了实践经验,有助于开发者在真实世界项目中解决...

    .Net MF 模拟器 抓图

    源程序是 http://bansky.net/blog/2008/03/jpeg-camera-and-micro-framework/&lt;br&gt;原作者是在 Tahoe development board 实现的,这个不需要使用硬件,直接就可以通过模拟器抓取图像

    Microsoft .NET Micro Framework嵌入式编程(美 汤普逊)

    《Microsoft .NET Micro Framework嵌入式编程》是美国作者汤普逊所著的一本深入探讨.NET Micro Framework(简称.NET MF)技术的专业书籍。这本书旨在帮助读者理解和掌握如何在嵌入式系统中应用.NET Micro Framework...

    Apress - Expert .NET Micro Framework (Apr 2008)

    《精通.NET Micro Framework》是一本深入探讨.NET Micro Framework(以下简称.NET MF)的专业书籍,由Apress出版社于2008年4月发行。这本书详细介绍了这个小型化、资源优化的.NET框架,它专为嵌入式设备和物联网(IoT...

    《玩转.NET Micro Framework移植-基于STM32F10x处理器》源程序.rar

    《玩转.NET Micro Framework移植-基于STM32F10x处理器》这本书的主题聚焦于将.NET Micro Framework(简称.NET MF)应用到STM32F10x系列微控制器上,这是一个涉及嵌入式系统开发、C#编程以及硬件平台集成的重要技术...

    Windows Embedded从入门到精通系列课程(18):.NET Micro Framework——用模拟器零成本体验MF开发

    《Windows Embedded从入门到精通系列课程(18):.NET Micro Framework——用模拟器零成本体验MF开发》 在Windows Embedded技术领域中,.NET Micro Framework(简称.NET MF)是一个专门为小型设备和嵌入式系统设计的...

    .NET Micro Framework开发板使用手册(红牛开发板)

    .NET Micro Framework(简称.NET MF)是微软公司推出的一个嵌入式操作系统平台,...通过深入学习.NET MF的原理和API,以及熟练掌握开发工具的使用,你将能够充分发挥红牛开发板的潜力,创造出各种创新的物联网应用。

    基于,NET Micro framework的简单项目

    这样的项目对于学习嵌入式开发和.NET MF技术非常有帮助,可以深入理解硬件与软件的交互,以及如何在有限的资源下实现高效能的应用。同时,通过使用高级语言编程,可以降低入门难度,提高开发效率。

    ASP.NET资产管理系统源码.zip

    5. **身份验证与授权**:系统可能包含登录注册功能,使用ASP.NET的身份认证和授权机制,确保只有授权用户可以访问特定资源。 6. **错误处理与日志记录**:良好的错误处理和日志记录是任何系统的关键部分。源码可能...

    基于ASP.NET医生健康问答咨询平台源码.zip

    为确保系统稳定性,开发者通常会在ASP.NET应用中加入异常处理机制,捕获和处理可能出现的错误。此外,日志记录是调试和监测系统状态的重要工具,ASP.NET提供了一些内置的日志组件,如System.Diagnostics.Trace类,...

    .net micro framework file

    .NET Micro Framework(简称.NET MF)是微软开发的一个轻量级.NET框架,主要针对嵌入式设备和物联网(IoT)应用。它提供了基础的.NET编程模型,使得开发者能够使用C#、VB.NET或其他.NET语言来编写高效能的嵌入式程序。...

    .NET Micro Frameowork在物联网行业应用的前景

    .NET Micro Framework(以下简称.NET MF)是由微软开发的一款用于小型嵌入式设备的软件平台。它为物联网设备提供了运行.NET代码的能力,使得开发者能够在资源有限的设备上实现复杂的功能。.NET MF支持C#编程语言,...

    Microsoft .NET Micro Framework 2.5 SDK

    - **类库与API**:.NET Micro Framework提供了一系列预定义的类库,如GDI+(图形设备接口)和.NET Compact Framework的子集,使得开发人员可以方便地处理I/O操作、网络通信和UI设计。 - **资源管理**:由于目标硬件...

    MF00015-.net仓库进销存ERP小程序源码.zip

    开发环境为Visual Studio 2012,数据库为SQL SERVER2012R2,使用.net 4.5开发。 一、源码介绍 所有行业的ERP系统/进销存/仓库系统,该系统为vs2012 .net+MsSQL版,目前标准版功能简 单明了、满足公司正常使用,已...

    毕业设计-ASP.NET

    【ASP.NET技术详解】 ASP.NET是微软公司推出的一种用于构建Web应用程序的开发框架,它基于.NET Framework,提供了丰富的功能和高...通过这样的项目,开发者不仅可以深入学习ASP.NET技术,还能提升软件工程的整体素养。

    基于ASP.net手机配件进销存管理系统源码.zip

    7. **错误处理和调试**:学会如何在ASP.net环境中设置错误处理机制,使用Visual Studio进行调试和代码优化。 8. **性能优化**:了解如何通过缓存、批量处理、减少数据库查询等方式提升系统的性能。 9. **部署与...

    基于ASP.net的企业文件管理系统源码.zip

    对于学习者或开发者来说,这是一个极好的资源,可以深入理解ASP.NET如何应用于企业级文件管理系统的实现,以及如何利用C#(ASP.NET的主要编程语言)来设计和实现文件管理功能。 【标签】:“毕业设计 C# Java PHP”...

    MF00939-asp.net电子会签系统源码.zip

    源代码是软件开发的核心,通过分析和研究,可以深入理解ASP.NET平台下构建此类系统的具体实现方法。 【标签】虽然没有提供具体的标签,但我们可以根据标题推测出以下几个关键标签: 1. ASP.NET:这是一个由微软开发...

    MF00889- ASP.NET简易库存管理源码.zip

    这个"MF00889- ASP.NET简易库存管理源码"是一个实用的学习资源,可以帮助开发者了解如何在ASP.NET环境下实现一个简单的库存管理系统。下面我们将深入探讨这个源码可能包含的关键知识点。 1. **ASP.NET Web Forms**...

Global site tag (gtag.js) - Google Analytics