Cortex M4 中断向量设置

发布时间 2023-07-24 19:49:45作者: LogicBai

Cortex M4 中断向量设置

Keywords: Cortex M4 CM4 Vector table 中断

前言

本文叙述了因Vector table设置错误导致进入hardfault中断的问题,现象就是APP运行卡死。

起因

今天同事在app前面加了固定大小的校验,然后将新的程序烧录之后,bootloader无法正常启动app,我对此问题比较感兴趣就做了一个简单的尝试,发现一样卡死了,遂进行解bug。
在keil中调试可以发现能够进入APP,然后开启一个外设的中断之后就进入了hardfault,目测是中断设置的错误。

解法

引发进入hardfault的原因是,那个固定大小的校验区域的size设置的不合适,链接之后vector table坐落的地址不正确。
在这个情况下校验区的大小应该设置成0x200的整数倍。

解释

翻阅Cortex-M4 Devices Generic User Guide可见如下要求。

When setting TBLOFF, you must align the offset to the number of exception entries in the vector table. The minimum alignment is 32 words, enough for up to 16 interrupts. For more interrupts, adjust the alignment by rounding up to the next power of two. For example, if you require 21 interrupts, the alignment must be on a 64-word boundary because the required table size is 37 words, and the next power of two is 64. See your vendor documentation for the alignment details of your device.

重点在于这两句话

you must align the offset to the number of exception entries in the vector table

For more interrupts, adjust the alignment by rounding up to the next power of two.

CM4要求vector table必须按照异常的数目来对齐,而这个数目要求是2次幂(数目不满足就向上取整)。

在启动的汇编中有表格__Vectors, 表格的固定的区域如下所示,该区域的大小是16 words。
而额外的可配置的区域如下所示,该区域的大小是82 words。

固定区域和可配置区域加起来一共是92 words,按照2次幂取整就是128 words,128 words就是512字节

计算出来偏移的字节长度之后,将app最前面的校验区域大小设置为0x200之后,重新配置bootloader和app中的相关参数之后,程序得以正常运行,bug解除。

固定区域:

__Vectors       DCD     __initial_sp                      ; Top of Stack
                DCD     Reset_Handler                     ; Reset Handler
                DCD     NMI_Handler                       ; NMI Handler
                DCD     HardFault_Handler                 ; Hard Fault Handler
                DCD     MemManage_Handler                 ; MPU Fault Handler
                DCD     BusFault_Handler                  ; Bus Fault Handler
                DCD     UsageFault_Handler                ; Usage Fault Handler
                DCD     0                                 ; Reserved
                DCD     0                                 ; Reserved
                DCD     0                                 ; Reserved
                DCD     0                                 ; Reserved
                DCD     SVC_Handler                       ; SVCall Handler
                DCD     DebugMon_Handler                  ; Debug Monitor Handler
                DCD     0                                 ; Reserved
                DCD     PendSV_Handler                    ; PendSV Handler
                DCD     SysTick_Handler                   ; SysTick Handler

可配置区域:

;               /* external interrupts handler */
                DCD     WWDGT_IRQHandler                  ; 16:Window Watchdog Timer
                DCD     LVD_IRQHandler                    ; 17:LVD through EXTI Line detect
                DCD     TAMPER_STAMP_IRQHandler           ; 18:Tamper and TimeStamp through EXTI Line detect
                DCD     RTC_WKUP_IRQHandler               ; 19:RTC Wakeup through EXTI Line
                DCD     FMC_IRQHandler                    ; 20:FMC
                DCD     RCU_CTC_IRQHandler                ; 21:RCU and CTC
                DCD     EXTI0_IRQHandler                  ; 22:EXTI Line 0
                DCD     EXTI1_IRQHandler                  ; 23:EXTI Line 1
                DCD     EXTI2_IRQHandler                  ; 24:EXTI Line 2
                DCD     EXTI3_IRQHandler                  ; 25:EXTI Line 3
                DCD     EXTI4_IRQHandler                  ; 26:EXTI Line 4
                DCD     DMA0_Channel0_IRQHandler          ; 27:DMA0 Channel0
                DCD     DMA0_Channel1_IRQHandler          ; 28:DMA0 Channel1
                DCD     DMA0_Channel2_IRQHandler          ; 29:DMA0 Channel2
                DCD     DMA0_Channel3_IRQHandler          ; 30:DMA0 Channel3
                DCD     DMA0_Channel4_IRQHandler          ; 31:DMA0 Channel4
                DCD     DMA0_Channel5_IRQHandler          ; 32:DMA0 Channel5
                DCD     DMA0_Channel6_IRQHandler          ; 33:DMA0 Channel6
                DCD     ADC_IRQHandler                    ; 34:ADC
                DCD     CAN0_TX_IRQHandler                ; 35:CAN0 TX
                DCD     CAN0_RX0_IRQHandler               ; 36:CAN0 RX0
                DCD     CAN0_RX1_IRQHandler               ; 37:CAN0 RX1
                DCD     CAN0_EWMC_IRQHandler              ; 38:CAN0 EWMC
                DCD     EXTI5_9_IRQHandler                ; 39:EXTI5 to EXTI9
                DCD     TIMER0_BRK_TIMER8_IRQHandler      ; 40:TIMER0 Break and TIMER8
                DCD     TIMER0_UP_TIMER9_IRQHandler       ; 41:TIMER0 Update and TIMER9
                DCD     TIMER0_TRG_CMT_TIMER10_IRQHandler ; 42:TIMER0 Trigger and Commutation and TIMER10
                DCD     TIMER0_CC_IRQHandler              ; 43:TIMER0 Capture Compare
                DCD     TIMER1_IRQHandler                 ; 44:TIMER1
                DCD     TIMER2_IRQHandler                 ; 45:TIMER2
                DCD     TIMER3_IRQHandler                 ; 46:TIMER3
                DCD     I2C0_EV_IRQHandler                ; 47:I2C0 Event
                DCD     I2C0_ER_IRQHandler                ; 48:I2C0 Error
                DCD     I2C1_EV_IRQHandler                ; 49:I2C1 Event
                DCD     I2C1_ER_IRQHandler                ; 50:I2C1 Error
                DCD     SPI0_IRQHandler                   ; 51:SPI0
                DCD     SPI1_IRQHandler                   ; 52:SPI1
                DCD     USART0_IRQHandler                 ; 53:USART0
                DCD     USART1_IRQHandler                 ; 54:USART1
                DCD     USART2_IRQHandler                 ; 55:USART2
                DCD     EXTI10_15_IRQHandler              ; 56:EXTI10 to EXTI15
                DCD     RTC_Alarm_IRQHandler              ; 57:RTC Alarm
                DCD     USBFS_WKUP_IRQHandler             ; 58:USBFS Wakeup
                DCD     TIMER7_BRK_TIMER11_IRQHandler     ; 59:TIMER7 Break and TIMER11
                DCD     TIMER7_UP_TIMER12_IRQHandler      ; 60:TIMER7 Update and TIMER12
                DCD     TIMER7_TRG_CMT_TIMER13_IRQHandler ; 61:TIMER7 Trigger and Commutation and TIMER13
                DCD     TIMER7_CC_IRQHandler              ; 62:TIMER7 Capture Compare
                DCD     DMA0_Channel7_IRQHandler          ; 63:DMA0 Channel7
                DCD     EXMC_IRQHandler                   ; 64:EXMC
                DCD     SDIO_IRQHandler                   ; 65:SDIO
                DCD     TIMER4_IRQHandler                 ; 66:TIMER4
                DCD     SPI2_IRQHandler                   ; 67:SPI2
                DCD     UART3_IRQHandler                  ; 68:UART3
                DCD     UART4_IRQHandler                  ; 69:UART4
                DCD     TIMER5_DAC_IRQHandler             ; 70:TIMER5 and DAC0 DAC1 Underrun error
                DCD     TIMER6_IRQHandler                 ; 71:TIMER6
                DCD     DMA1_Channel0_IRQHandler          ; 72:DMA1 Channel0
                DCD     DMA1_Channel1_IRQHandler          ; 73:DMA1 Channel1
                DCD     DMA1_Channel2_IRQHandler          ; 74:DMA1 Channel2
                DCD     DMA1_Channel3_IRQHandler          ; 75:DMA1 Channel3
                DCD     DMA1_Channel4_IRQHandler          ; 76:DMA1 Channel4
                DCD     ENET_IRQHandler                   ; 77:Ethernet
                DCD     ENET_WKUP_IRQHandler              ; 78:Ethernet Wakeup through EXTI Line
                DCD     CAN1_TX_IRQHandler                ; 79:CAN1 TX
                DCD     CAN1_RX0_IRQHandler               ; 80:CAN1 RX0
                DCD     CAN1_RX1_IRQHandler               ; 81:CAN1 RX1
                DCD     CAN1_EWMC_IRQHandler              ; 82:CAN1 EWMC
                DCD     USBFS_IRQHandler                  ; 83:USBFS
                DCD     DMA1_Channel5_IRQHandler          ; 84:DMA1 Channel5
                DCD     DMA1_Channel6_IRQHandler          ; 85:DMA1 Channel6
                DCD     DMA1_Channel7_IRQHandler          ; 86:DMA1 Channel7
                DCD     USART5_IRQHandler                 ; 87:USART5
                DCD     I2C2_EV_IRQHandler                ; 88:I2C2 Event
                DCD     I2C2_ER_IRQHandler                ; 89:I2C2 Error
                DCD     USBHS_EP1_Out_IRQHandler          ; 90:USBHS Endpoint 1 Out
                DCD     USBHS_EP1_In_IRQHandler           ; 91:USBHS Endpoint 1 in
                DCD     USBHS_WKUP_IRQHandler             ; 92:USBHS Wakeup through EXTI Line
                DCD     USBHS_IRQHandler                  ; 93:USBHS
                DCD     DCI_IRQHandler                    ; 94:DCI
                DCD     0                                 ; 95:Reserved
                DCD     TRNG_IRQHandler                   ; 96:TRNG
                DCD     FPU_IRQHandler                    ; 97:FPU

__Vectors_End