新闻  |   论坛  |   博客  |   在线研讨会
ARM中断系统小结
yanqin | 2009-04-16 19:10:03    阅读:1506   发布文章


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

*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
推荐文章
最近访客