2440中断解析
$HandlerLabel HANDLER $HandleLabel
$HandlerLabel
sub sp,sp,#4 ;decrement sp(to store jump address)
stmfd sp!,{r0} ;PUSH the work register to stack(lr does not push because it return to original address)
ldr
ldr
str
ldmfd
MEN
将sp减少一个字节,使其在堆栈高端留出存储返回地址,因为pc在寄存器组 中的位置大于r0,出栈时装入的是栈的高端的内容
保存r0
装载中断处理函数的指针
装载中断处理函数的地址
将中断处理函数的地址存入刚才预留的位置,r0的上面
出栈后,pc指向的既是中断处理函数的地址
以上是个宏,用于把中断服务程序的首地址装载到pc中,我称它为“加载程序”。
本初始化程序定义了一个数据区(在文件最后),34个字空间,存放相应中断服务程序的首地址。每个字空间都有一个标号,以Handle***命名。
在向量中断模式下使用“加载程序”来执行中断服务程序。
下面是每个中断源的“加载程序”
HandlerFIQ HANDLER HandleFIQ
HandlerIRQ HANDLER HandleIRQ
HandlerUndef HANDLER HandleUndef
HandlerSWI HANDLER HandleSWI
HandlerDabort HANDLER HandleDabort
HandlerPabort HANDLER HandlePabort
下面这段程序的首地址将要被放到HandleIRQ中,在非向量中断模式下发生IRQ中断时,执行此程序来判断中断源以执行相应的中断服务程序。
IsrIRQ
sub sp,sp,#4
stmfd sp!,{r8-r9}
ldr r9,=INTOFFSET
ldr r9,[r9]
ldr r8,=HandleEINT0
add r8,r8,r9,lsl #2
ldr r8,[r8]
str r8,[sp,#8]
ldmfd sp!,{r8-r9,pc}
下面就是把IsrIRQ的首地址装载到HandleIRQ的代码
; Setup IRQ handler
ldr r0,=HandleIRQ ;This routine is needed
ldr r1,=IsrIRQ ;if there is not subs pc,lr,#4 at 0x18, 0x1c
str r1,[r0]
ALIGN
AREA RamData, DATA, READWRITE
异常向量表
^
HandleReset #
HandleUndef #
HandleSWI #
HandlePabort
HandleDabort
HandleReserved
HandleIRQ #
HandleFIQ #
中断向量表
;Do not use the label IntVectorTable,
;The value of IntVectorTable is different with the address you think it may be.
;IntVectorTable
;@0x33FF_FF20
HandleEINT0 #
HandleEINT1 #
HandleEINT2 #
HandleEINT3 #
HandleEINT4_7 #
HandleEINT8_23 #
HandleCAM #
HandleBATFLT #
HandleTICK #
HandleWDT #
HandleTIMER0 #
HandleTIMER1 #
HandleTIMER2 #
HandleTIMER3 #
HandleTIMER4 #
HandleUART2
;@0x33FF_FF60
HandleLCD #
HandleDMA0 #
HandleDMA1 #
HandleDMA2 #
HandleDMA3 #
HandleMMC #
HandleSPI0 #
HandleUART1 #
HandleNFCON #
HandleUSBD #
HandleUSBH #
HandleIIC #
HandleUART0 #
HandleSPI1 #
HandleRTC #
HandleADC #
;@0x33FF_FFA0
END
本程序的初始化中断部分实现的很巧妙,基于34个字单元将向量中断和非向量中断的实现结合在一起。
向量中断直接使用“加载程序”,把相应的中断服务程序首地址(存放于Handle***)加载到PC。
非向量中断通过执行IsrIRQ判断中断源,并同时计算出相应Handle***的地址,再将此地址的内容加载到PC。
我有两个问题:
问题一,非向量中断有个缺点,它始终从优先级最低的中断源开始识别,且是通过过分析I_ISPR寄存器的每一位来识别,但是尽管有多个中断同时发生,I_ISPR只有一位置1。如此一来,频繁发生低优先级中断是否会屏蔽其他中断?
我有过一次试验,设置两个中断INT_TICK和INT_TIMER5,两个中断服务程序都使用串口打印一串字符。当TIMER5以频率为1KHz(每毫秒一次)中断时,TICK中断服务程序毫无反应。
问题二,本代码
2440中断解 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)