一.首先,我们先看一下它的中断向量表:
由中断向量表,可知如果有任何一个IRQ中断源产生中断,CPU都会到0x18地址读指令。
二.在启动代码中,下面的指令分别在中断向量地址中: 即0x18地址处是指令 b HandlerIRQ
b ResetHandler
b HandlerUndef ;handler for Undefined mode
b HandlerSWI ;handler for SWI interrupt
b HandlerPabort ;handler for PAbort
b HandlerDabort ;handler for DAbort
b . ;reserved
bHandlerIRQ ;handler for IRQ interrupt
b HandlerFIQ ;handler for FIQ interrupt
3、 HandlerFIQ HANDLER HandleFIQ
HandlerIRQ HANDLER HandleIRQ
HandlerUndef HANDLER HandleUndef
HandlerSWI HANDLER HandleSWI
HandlerDabort HANDLER HandleDabort
HandlerPabort HANDLER HandlePabort
4、
MACRO
$HandlerLabel HANDLER $HandleLabel ;$lable macroname $parameter
;HandlerLabel
$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 r0,=$HandleLabel;load the address of HandleXXX to r0
ldr r0,[r0] ;load the contents(service routine start address) of HandleXXX
;
str r0,[sp,#4] ;store the contents(ISR) of HandleXXX to stack
;
ldmfd sp!,{r0,pc} ;POP the work register and pc(jump to ISR)
MEND
展开为:
HandlerFIQ
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 r0,= HandleFIQ;load the address of HandleXXX to r0
ldr r0,[r0] ;load the contents(service routine start address) of HandleXXX
;
str r0,[sp,#4] ;store the contents(ISR) of HandleXXX to stack
;
ldmfd sp!,{r0,pc} ;POP the work register and pc(jump to ISR)
HandlerIRQ
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 r0,= HandleIRQ;load the address of HandleXXX to r0
ldr r0,[r0] ;load the contents(service routine start address) of HandleXXX
;
str r0,[sp,#4] ;store the contents(ISR) of HandleXXX to stack
;
ldmfd sp!,{r0,pc} ;POP the work register and pc(jump to ISR)
。。。。上面的6次宏调用,会展开为类似上面的代码6段
HandleIRQ # 4
5、 ldr r0,=HandleIRQ ;This routine is needed
ldr r1,=IsrIRQ ;if there is not 'subs pc,lr,#4' at 0x18, 0x1c
str r1,[r0]
6、
IsrIRQ
sub sp, sp, #4 ;reserved for PC ;//
stmfd sp!, {r8-r9}
ldr r9, =INTOFFSET ; //
ldr r9, [r9] ;//14---timer4
ldr r8, =HandleEINT0 ;//
add r8, r8,r9,lsl #2 ;//
ldr r8, [r8] ;//
str r8, [sp,#8]
ldmfd sp!,{r8-r9,pc} ;//
HandleEINT0+INTOFFSET*4 就是发生中断的扩展向量地址,而该地址就是放相应的中断函数名。
在2440init.s中有定义:HandleTIMER4 # 4
在2440addr.h中有定义:#define pISR_TIMER4 (*(unsigned *)(_ISR_STARTADDRESS+0x58))
在模块的初始化函数中,有安装中断处理函数:pISR_TIMER4 = (unsigned int)timer4_irq;
具体的的流程如下图:
大致的产生流程就是这样的了.