STM32F4 Hard Fault調試

    最近移植一個IAR的UVC工程到STM32F4上進行開發,花費了些時間調試了下一個HardFault問題,在此mark下。函數

    現象描述

    Reset上電後直接進入HardFault處理函數,沒法進入C環境的main函數spa

    調試過程

  • 捕獲異常現場

    進入Keil Debug模式Reset程序,等待程序跑飛後按下Stop,此時程序應該會停在HardFault_Handler函數處。查看硬fault狀態寄存器(地址: 0xE000ED2C)確認hard fault類型,以下圖,發現BIT30(FORCED)被置位,手冊指示此hard fault是因爲上訪致使。調試

    繼續查看用法fault狀態寄存器(UFSR,地址: 0xE000ED2A),存儲器管理fault狀態寄存器(MFSR,地址: 0xE000ED28),總線fault狀態寄存器(BFSR,地址: 0xE000ED29)確認異常類型,以下圖,發現UFSR的BIT3(NOCP)置位,手冊解釋爲 「試圖執行協處理器相關指令」,不過貌似仍是一頭霧水,但至少有點眉目。code

  • 尋找異常觸發點

    爲了找到觸發異常的指令,咱們先在異常發生前設置斷點,而後使能usage fault中斷(BIT18,地址:0xE000ED24),點擊RUN,等待程序跑飛,而後STOP程序,不出意外的話會發現PC停在UsageFault_Handler(說明咱們以前的判斷是正確的^_^),查看當前SP的地址,而後根據中斷入棧規則去尋找中斷前的PC值。我這邊的SP是0x20003600,那麼咱們就到該地址去尋找PC值吧。開發

能夠獲取到觸發異常的指令位置在0x80032C4, 異常處理的返回地址在0x800024B,下圖紅色標記處LR的入棧位置,PC比其先入棧。it

經過反彙編窗口發現是因爲VMSR這條指令致使,單步調試下能夠發現這條指令在_fp_init中 class

如今能夠確認是FPU指令致使的Usage Fault上訪爲Hard Faultbug

  • 尋找對策

    知道緣由後找尋解決方法就比較簡單了,FPU指令不可用應該就是FPU相關的有效位沒使能致使的,在SystemInit中追加FPU的初始化操做便可。在最新的CMSIS中已經追加,不清楚爲何我用的庫裏沒有,好無奈,又是一坑程序

void SystemInit(void)
{
  /* FPU settings ------------------------------------------------------------*/
  #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
    SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));  /* set CP10 and CP11 Full Access */
  #endif
  
.............
}

    這個問題還有一個workaround你們能夠試下,就是勾選上" Use MacroLIB ",這是我最開始的對策。方法

相關文章
相關標籤/搜索