- b ResetHandler
- b HandlerUndef ;handler for Undefined mode 0x04
- b HandlerSWI ;handler for SWI interrupt 0x08
- b HandlerPabort ;handler for PAbort 0x0c
- b HandlerDabort ;handler for DAbort 0x10
- b . ;reserved 0x14
- b HandlerIRQ ;handler for IRQ interrupt 0x18
- b HandlerFIQ ;handler for FIQ interrupt 0x1c
程序开始处设置异常中断跳转。跳转后的代码在这儿
- HandlerFIQ HANDLER HandleFIQ
- HandlerIRQ HANDLER HandleIRQ
- HandlerUndef HANDLER HandleUndef
- HandlerSWI HANDLER HandleSWI
- HandlerDabort HANDLER HandleDabort
- HandlerPabort HANDLER HandlePabort
这是一个宏,宏名为HANDLER。遇到类似$HandleLabel HANDLER $HandleLabel的语句则执行宏内指令。宏定义内容是下面这段,也是上面跳转之后运行的代码
- MACRO
- $HandlerLabel HANDLER $HandleLabel
- $HandlerLabel
- sub sp,sp,#4
- stmfd sp!,{r0}
- ldr r0,=$HandleLabel
- ldr r0,[r0]
- str r0,[sp,#4]
- ldmfd sp!,{r0,pc}
- MEND
上面这段的意思是:不改变r0和sp的值,使pc跳转到$HandleLabel标号所指向的地址处。在启动代码最后可以看到跳转到的标号。
- ^ _ISR_STARTADDRESS ; _ISR_STARTADDRESS=0x33FF_FF00
- HandleReset # 4
- HandleUndef # 4
- HandleSWI # 4
- HandlePabort # 4
- HandleDabort # 4
- HandleReserved # 4
- HandleIRQ # 4
- HandleFIQ # 4
"^"=MAP,意思是从_ISR_STARTADDRESS开始定义一个内存表。内存表中为下面标号预留4字节空间。可以看出:当程序进入中断后,pc会跳转到HandleIRQ标号处。但是预留HandleIRQ的空间时,并没有为其写入内容。所以,我们要先为HandleIRQ地址初始化,使其指向一个地址。这样,每有中断发生时,则使pc跳转到指向的地址处。
- ; 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]
这段的意思是将IsrIRQ的地址赋予HandleIRQ。所以,IsrIRQ就是HandleIRQ所指向的地址,也是pc将要跳转到的地址。跳转之后,将执行下面代码:
- 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}
INTOFFSET为中断源偏移量。例如,HandleEINT0偏移量为0,HandleEINT1偏移量为1,HandleEINT4_7偏移量为4,从下表可以看出
- ;@0x33FF_FF20
- HandleEINT0 # 4
- HandleEINT1 # 4
- HandleEINT2 # 4
- HandleEINT3 # 4
- HandleEINT4_7 # 4
- ...
IsrIRQ段的意思:r8为HandleEINT0的地址,r9为中断偏移量,也是相对HandleEINT0的偏移量。结果是将发生中断的中断源的标号地址赋予pc,即表中标号代表的地址。(具体执行需仔细看IsrIRQ段代码)但是,表中的标号的地址中也需要写入内容,以使pc跳转。结合2440addr.h中的
#define pISR_EINT0 (*(unsigned *)(_ISR_STARTADDRESS+0x20))
可以看出,在c编码中的pISR_EINTx = xxx(函数名)中的xxx函数入口地址即是pc将要跳转的地址,而接下来要执行的也就是c中编写的中断服务程序。
阅读(374) | 评论(0) | 转发(0) |