查看: 1920|回复: 0
打印 上一主题 下一主题

ARM的中断分析

[复制链接]
跳转到指定楼层
沙发
发表于 2016-5-28 22:01:50 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
ARM的中断分析
对于学习ARM的朋友来说,中断处理是一块硬骨头,尤其是中断向量表以及中断的跳转。下面主要对中断向量表的建立问题及重映射问题进行探讨。近来做一些东西用到中断时,总会出现一些问题。
      各种Bootloader的初始化相关代码摘要,首先来看下面的程序:         ^ DRAM_BASE                     //DRAM的基地址HandleReset # 4                              // 空留4个单元HandleUndef # 4HandleSwi    # 4HandlePrefetch # 4                       //用于填充地址的HandleAbort # 4HandleReserv # 4HandleIrq    # 4HandleFiq # 4  注: 这里的^是RMAP,#是FIELD,分配的意思  就是在SDARM的BANK0开始的地方定义了一个中断向量表,相当于0地址的FLASH。空留单元用于存放中断程序的入口地址。ExceptionHandlerTable                             //实际的映射地址     DCD UserCodeArea     DCD SystemUndefinedHandler     DCD SystemSwiHandler     DCD SystemPrefetchHandler     DCD SystemAbortHandler     DCD SystemReserv     DCD SystemIrqHandler     DCD SystemFiqHandler        这个表中存放的是汇编程序中中断处理函数的入口地址,每一项对应一个中断函数。这次的跳转后就进入了C服务程序。          从初始化程序的开始处来看:(各种Bootloader的初始化代码)  AREA Init, CODE, READONLY     //相当于init进程  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]         中断向量地址给PC     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       //填充8个地址              BNE ExceptLoop   //从表里取出来给了HandleReset后面的空间       这一段把ExceptionHandlerTable里的中断处理函数的地址拷给了SDRAM里的中断向量表。这样两者就联系起来了。     在执行程序开始的跳转之后就自然跳到了*****Handler.真正的处理函数如下:       它实际上只调用了C语言的中断处理函数,其他什么也没做。SystemFiqHandler     IMPORT ISR_FiqHandler     STMFD sp!, {r0-r7, lr}     BL ISR_FiqHandler                    //真正的中断处理服务函数     LDMFD sp!, {r0-r7, lr}     SUBS pc, lr, #4        它实际上只调用了C语言的中断处理函数,其他什么也没做。写中断处理服务程序其实就只写C中相应的处理部分就好了。
void ISR_FiqHandler(void){       IntOffSet = (U32)INTOFFSET;       (IntOffSet>>2)        (*InterruptHandlers[IntOffSet>>2])(); // Call interrupt service routine}
      其实就是将中断向量表重映射,以提高中断的响应速度。代码在SDRAM的运行速度要比在FLASH中运行速度快。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 加入中科因仑

本版积分规则

快速回复 返回顶部 返回列表