您可以添加到网摘 让更多人关注此文章:
S3C2410(IRQ)中断处理过程:
在此要注意的是区别中断向量表和异常向量表。中断发生后总是从IRQ 或者FIQ 异常入口处进入,然后跳转到相应的异常处理程序处执行,这个异常处理程序一般都是进行查找中断向量表的操作,然后调用中断处理程序。
以下是在应用中中断处理实现的过程:从中不难体会到中断的处理过程。
定义中断向量表的物理地址:
代码 .equ pISR_DABORT , (_ISR_STARTADDRESS+0x10) .equ pISR_RESERVED, (_ISR_STARTADDRESS+0x14) .equ pISR_IRQ , (_ISR_STARTADDRESS+0x18) .equ pISR_FIQ , (_ISR_STARTADDRESS+0x1c) //异常向量表 …………………………………………………………………… .equ pISR_EINT0 , (_ISR_STARTADDRESS+0x20) //中断向量表 .equ pISR_EINT1 , (_ISR_STARTADDRESS+0x24) .equ pISR_EINT2 , (_ISR_STARTADDRESS+0x28) .equ pISR_EINT3 , (_ISR_STARTADDRESS+0x2c) 将中断处理程序入口地址放入中断向量表: 代码 pISR_EINT0 = (unsigned int)isrEINT0; // isrEINT0 中断处理程序 pISR_EINT1 = (unsigned int)isrEINT1; 定义中断处理程序: 代码 .extern Interrupt_Rbutton .global isrEINT0 isrEINT0: IRQHandle Interrupt_Rbutton 定义异常向量表: 代码 b HandlerUndef /* handler for Undefined mode */ b HandlerSWI /* handler for SWI interrupt */ b HandlerPabort /* handler for PAbort */ b HandlerDabort /* handler for DAbort */ .long FileIDTable /* id */ b HandlerIRQ /* handler for IRQ interrupt */ b HandlerFIQ 定义异常处理函数: 代码 HandlerFIQ: HANDLER HandleFIQ HandlerIRQ: HANDLER HandleIRQ HandlerUndef: HANDLER HandleUndef HandlerSWI: HANDLER HandleSWI HandlerDabort: HANDLER HandleDabort HandlerPabort: HANDLER HandlePabort 异常处理宏HANDLER的定义: 代码 .macro HANDLER HandleLabel sub sp,sp,#4 /* decrement sp(to store jump address) */ stmfd sp!,{r0} /* PUSH the work register to stack(lr does't push bec ause 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) */ .endm 定义IRQ 中断处理宏IRQHandle: 代码 .macro IRQHandle isrHandle: stmdb sp!, {r0-r11, ip, lr} /* save r0-r11, ip, lr */ ldr r0, =isrHandle mov lr, pc bx r0 /* jump to user_handle(void) */ ldmia sp!, {r0-r11, ip, lr} /* restore r0, ip, lr */ subs pc, r14, #4 /* return from interrupt */ .endm 申明IRQ 异常的服务程序为:IsrIRQ,即,发生IRQ 异常时,执行“b HandlerIRQ”即是 运行IsrIRQ代码: 代码 ldr r0,=HandleIRQ @ This routine is needed ldr r1,=IsrIRQ @ if there isn't 'subs pc,lr,#4' at 0x18, 0x1c str r1,[r0] IRQ 异常处理程序: 代码 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} 由上可以知道,当一个IRQ 中断发生时,CPU将从0X18(IRQ 异常入口地址)取指执行,在这一步PC 的跳转是有硬件实现的。在入口0x18 地址处放的是一条跳转指令,这条指令将跳到IRQ 异常处理程序运行,IRQ 异常处理程序主要是根据中断源查找中断向量表。获得中断入口地址后,接着CPU 跳转中断处理程序运行。 在嵌入式系统中异常向量表和中断向量表都是存于FLASH起始的一段空间中。而异常处理和中断处理程序都是运行在RAM中的。
|