[牛人杂谈] ARM中的中断向量表

[复制链接]
1825|3
 楼主| wahahaheihei 发表于 2016-3-24 21:08 | 显示全部楼层 |阅读模式
中断或异常发生的时候,CPU自动将PC指向一个特定的地址,这个地址就是中断向量表。
在32位ARM系统中,一般都是在中断向量表中放置一条分支指令或PC寄存器加载指令,实现程序跳转到中
断服务例程的功能。例如:
IRQEntry B HandleIRQ ;跳转范围较小
LDR PC,=HandleFIQ     
;LDR伪指令等效生成1条存储读取指令和1条32位常数定义指令。32位常数存储在LDR指令四周的存储单元
中,相对偏移小于4KB。该32位数据就是要跳转到的中断服务程序入口地址。
之所以使用LDR伪指令,是因为ARM的RISC指令为单字指令,不能装载32位的立即数 (常数),无法直接
把一个32位常数数据或地址数据装载到寄存器中。所以我们一般将中断向量按如下方式设置中断向量表
  1. LDR     PC, Reset_Addr             1
  2. LDR     PC, Undefined_Addr
  3. LDR     PC, SWI_Addr
  4. LDR     PC, Prefetch_Addr
  5. LDR     PC, Abort_Addr
  6. NOP                             ; Reserved vector must be remained
  7. LDR     PC, IRQ_Addr
  8. LDR     PC, FIQ_Addr

  9. Vector_Addr_Table

  10. Reset_Addr      DCD     Reset_Handler          9
  11. Undefined_Addr DCD     UndefinedHandler
  12. SWI_Addr        DCD     SWIHandler
  13. Prefetch_Addr   DCD     PrefetchAbortHandler
  14. Abort_Addr      DCD     DataAbortHandler
  15. IRQ_Addr        DCD     IRQHandler
  16. FIQ_Addr        DCD     FIQHandler
上面中断向量表的第9行就是从地址0X00000020开始分配一个字的空间(也就是4字节),这4个字节的内容就是Reset_Handler函数的地址0X00001000。Reset_Addr的值就是这4个字节的首地址0X00000020。
DCD是ARM的伪指令。作用是分配一个字的空间。功能类似于C51里定义一个数组并初始化。
Unsigned char Reset_Addr[4]={0x00,0x00,0x10,0x00};
对比一下就明白了。

再分析第1行。LDR只能在当前PC的4KB范围内跳转,B命令只能在当前PC的32MB范围内调转。
Reset_Handler的地址是0X00001000,已经超出了当前PC的4K范围,所以不能用
LDR     PC, Reset_Handler
这里不好理解,涉及到ARM的寻址方式。
LDR Rn,语句标号
这种表达式里,是相对寻址,基址是程序计数器PC,偏移量是语句标号到PC处的指令条数。
LDR PC,语句标号只能在当前PC的4KB范围内跳转的原因是这条指令译码后,偏移表达式占用指令代码32位的最后12位,也就是2^12=4KB。

完整的分析下,以复位为例。地址0X00000020开始的4字节内容是复位处理函数Reset_Handler的地址0x00001000。Reset_Addr的地址是0X00000020。当产生复位时,PC=0x00000000,跳到第1行语句执行。LDR     PC, Reset_Addr把0X00000020处的一个字的内容送到PC,然后PC跳转到0X00001000处开始执行。
LDR     PC, Reset_Addr是间接寻址,就是把地址Reset_Addr处的一个字送给PC。

huangcunxiake 发表于 2016-3-25 11:47 | 显示全部楼层

  1. ; Vector Table Mapped to Address 0 at Reset
  2.                 AREA    RESET, DATA, READONLY
  3.                 EXPORT  __Vectors
  4.                 EXPORT  __Vectors_End
  5.                 EXPORT  __Vectors_Size

  6. __Vectors       DCD     __initial_sp                   ; Top of Stack
  7.                 DCD     Reset_Handler                  ; Reset Handler
  8.                 DCD     NMI_Handler                    ; NMI Handler
  9.                 DCD     HardFault_Handler              ; Hard Fault Handler
  10.                 DCD     0                              ; Reserved
  11.                 DCD     0                              ; Reserved
  12.                 DCD     0                              ; Reserved
  13.                 DCD     0                              ; Reserved
  14.                 DCD     0                              ; Reserved
  15.                 DCD     0                              ; Reserved
  16.                 DCD     0                              ; Reserved
  17.                 DCD     SVC_Handler                    ; SVCall Handler
  18.                 DCD     0                              ; Reserved
  19.                 DCD     0                              ; Reserved
  20.                 DCD     PendSV_Handler                 ; PendSV Handler
  21.                 DCD     SysTick_Handler                ; SysTick Handler

  22.                 ; External Interrupts
  23.                 DCD     WWDG_IRQHandler                ; Window Watchdog
  24.                 DCD     PVD_IRQHandler                 ; PVD through EXTI Line detect
  25.                 DCD     RTC_IRQHandler                 ; RTC through EXTI Line
  26.                 DCD     FLASH_IRQHandler               ; FLASH
  27.                 DCD     RCC_IRQHandler                 ; RCC
  28.                 DCD     EXTI0_1_IRQHandler             ; EXTI Line 0 and 1
  29.                 DCD     EXTI2_3_IRQHandler             ; EXTI Line 2 and 3
  30.                 DCD     EXTI4_15_IRQHandler            ; EXTI Line 4 to 15
  31.                 DCD     TS_IRQHandler                  ; TS
  32.                 DCD     DMA1_Channel1_IRQHandler       ; DMA1 Channel 1
  33.                 DCD     DMA1_Channel2_3_IRQHandler     ; DMA1 Channel 2 and Channel 3
  34.                 DCD     DMA1_Channel4_5_IRQHandler     ; DMA1 Channel 4 and Channel 5
  35.                 DCD     ADC1_COMP_IRQHandler           ; ADC1, COMP1 and COMP2
  36.                 DCD     TIM1_BRK_UP_TRG_COM_IRQHandler ; TIM1 Break, Update, Trigger and Commutation
  37.                 DCD     TIM1_CC_IRQHandler             ; TIM1 Capture Compare
  38.                 DCD     TIM2_IRQHandler                ; TIM2
  39.                 DCD     TIM3_IRQHandler                ; TIM3
  40.                 DCD     TIM6_DAC_IRQHandler            ; TIM6 and DAC
  41.                 DCD     0                              ; Reserved
  42.                 DCD     TIM14_IRQHandler               ; TIM14
  43.                 DCD     TIM15_IRQHandler               ; TIM15
  44.                 DCD     TIM16_IRQHandler               ; TIM16
  45.                 DCD     TIM17_IRQHandler               ; TIM17
  46.                 DCD     I2C1_IRQHandler                ; I2C1
  47.                 DCD     I2C2_IRQHandler                ; I2C2
  48.                 DCD     SPI1_IRQHandler                ; SPI1
  49.                 DCD     SPI2_IRQHandler                ; SPI2
  50.                 DCD     USART1_IRQHandler              ; USART1
  51.                 DCD     USART2_IRQHandler              ; USART2
  52.                 DCD     0                              ; Reserved
  53.                 DCD     CEC_IRQHandler                 ; CEC
  54.                 DCD     0                              ; Reserved
  55.                
  56. __Vectors_End
上面是一个.s文件的中断向量表,其实仔细看,就是个类似宏的东西,把向量地址起个名字,方便在程序中写中断程序。


E-Kaia 发表于 2016-3-26 23:29 | 显示全部楼层
中断向量表都是用汇编语言写的,比较好理解一些
ofsummer 发表于 2016-3-28 21:03 | 显示全部楼层
那么这种属于什么类型的寻址方式呢
您需要登录后才可以回帖 登录 | 注册

本版积分规则

232

主题

3223

帖子

12

粉丝
快速回复 在线客服 返回列表 返回顶部