-- ARM中断系统小结 初看ARM中断系统觉得有点乱,写点东西希望对大家有点帮助 中断详细建立过程(1) 首先我们先来看两个东西. ;/* EXCEPTION HANDLER VECTOR TABLE */
^ DRAM_BASE HandleReset # 4 HandleUndef # 4 HandleSwi # 4 HandlePrefetch # 4 HandleAbort # 4 HandleReserv # 4 HandleIrq # 4 HandleFiq # 4 小注: 这里的^是MAP,#是FIELD 也就是在DARM的BANK0里面开始的地方定义了一个中断向量表,用于存放中断程序的入口地址。
ExceptionHandlerTable DCD UserCodeArea DCD SystemUndefinedHandler DCD SystemSwiHandler DCD SystemPrefetchHandler DCD SystemAbortHandler DCD SystemReserv DCD SystemIrqHandler DCD SystemFiqHandler 这个表中存放的是汇编程序中中断处理函数的入口地址,每一项对应一个中断函数。
下面我们从程序的开始处分析: AREA Init, CODE, READONLY ENTRY
B Reset_Handler B Undefined_Handler B SWI_Handler B Prefetch_Handler B Abort_Handler NOP Reserved vector B IRQ_Handler B FIQ_Handler
FIQ_Handler SUB sp, sp, #4 STMFD sp!, {r0} FD满递减堆栈 执行寄存器压栈操作. LDR r0, =HandleFiq 汇编里的处理函数地址,然后跳到C中,在DRAM。 LDR r0, [r0] 中断向量地址给R0. STR r0, [sp, #4] 中断向量地址给 LDMFD sp!, {r0, pc} 在程序的开始处,首先建立了默认的中断调用函数.这个过程大家一定非常熟悉, 首先执行了压栈,然后给出了中断入口地址.这个HandleFiq就是我们前面提到的在DRAM中建立的中断向量其中一个的地址。 在HandleFiq开始的四个字节中,放着汇编中断处理函数的入口地址。
汇编中断处理函数的地址是如何放到DRAM中断向量表里的呢?
我们上面提到的另一个表就发挥作用了。看下面这段程序: EXCEPTION_VECTOR_TABLE_SETUP LDR r0, =HandleReset LDR r1, =ExceptionHandlerTable MOV r2, #8 ExceptLoop LDR r3, [r1], #4 STR r3, [r0], #4 SUBS r2, r2, #1 Down Count BNE ExceptLoop ;; 从表里取出来给了HandleReset后面的空间 这一段把ExceptionHandlerTable里的中断处理函数的地址拷贝给了DRAM里的中断向量表。这样两者就联系起来 在执行程序开始的跳转之后就自然跳到了*******Handler.真正的处理函数之一如下所示:
它实际上只调用了C语言的中断处理函数,其他什么也没做。 SystemFiqHandler IMPORT ISR_FiqHandler STMFD sp!, {r0-r7, lr} BL ISR_FiqHandler LDMFD sp!, {r0-r7, lr} SUBS pc, lr, #4
它实际上只调用了C语言的中断处理函数,其他什么也没做。 void ISR_FiqHandler(void) { IntOffSet = (U32)INTOFFSET; (IntOffSet>>2) (*InterruptHandlers[IntOffSet>>2])(); // Call interrupt service routine }
|