当前位置: 代码迷 >> 综合 >> arm9-裸机中断过程分析(2012-02-07 11:12)
  详细解决方案

arm9-裸机中断过程分析(2012-02-07 11:12)

热度:66   发布时间:2023-12-08 20:23:49.0
步骤1:发生中断后,跳到地址0的中断向量表;b  HandlerIRQ ;handler for IRQ interrupt
步骤2:然后跳到,中断函数HandlerIRQ ,这个函数就做了并且只是了一件事取出全局变量HandleIRQ 地址上的函数并且使pc跳到该函数,

 //堆栈是满降方式就是说 ,sp指向满的地方,当压栈时,先sp自减4然后存数据到sp所指地址,这里仅仅是取出数据到pc没其他操作

具体实现代码如下:    MACRO
$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''t 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


 

步骤3:因为在系统复位的时候,  全局变量HandleIRQ处被安放了汇编函数IsrIRQ

代码如下:

;===========================================================
; 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函数就是从cpu寄存器里面得到中断偏移,然后根据偏移,和标号HandleEINT0(也就是定义在内存地址_ISR_STARTADDRESS上的HandleEINT0地址)

相加得到具体中断处理函数的地址,然后从这个地址取出中断函数(这个中断函数就是在c语言中用户自己放上去的,比如pISR_TIMER0= (uint32) OSTickISR;pISR_TIMER0就是定义在地址_ISR_STARTADDRESS上的变量),然后跳到中断函数,

 

IsrIRQ
sub	sp,sp,#4       ;reserved for PC
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}


 

  相关解决方案