HardFault_Handler問題查找方法


出現問題的現象

在用Keil對STM32的程序進行仿真時,程序有時候回跑飛,停止仿真程序會停在HardFault_Handler函數里的死循環while(1)中。這說明STM32出現了硬件錯誤。

------------------------------------- 圖 1 -------------------------------------
STM32出現HardFault_Handler故障的原因主要有兩個方面:

  1. 內存溢出或者訪問越界。
  2. 堆棧溢出。

出現問題后查找問題點的方法

方法1:

① 發生異常后先查看LR寄存器中的值,確定當時使用堆棧為MSP還是PSP。

在Keil菜單欄點擊【view】->【Registers Window】打開寄存器窗口,查看 R14(LR) 的值。
若R14(LR) = 0xFFFFFFE9, 查看 MSP(主堆棧指針)的值;
若R14(LR) = 0xFFFFFFFD, 查看 PSP(進程棧指針)的值。

------------------------------------- 圖 2 -------------------------------------
上圖的R14(LR) = 0xFFFF FFFD,則查看 PSP(進程棧指針)的值。

② 找到相應堆棧的指針,在內存中查看相應堆棧里的內容。

由於異常發生時,內核將R0~R3、R12、R14(LR)、PC、XPRS寄存器依次入棧,其中R14(LR)即為發生異常前PC將要執行的下一條指令地址。
注意:寄存器均是32位、且STM32是小端模式。(參考Cortex_M3權威指南)


------------------------------------- 圖 3 -------------------------------------

從 圖2 可看到SP的值為 0x200019A8,在Keil菜單欄點擊【view】->【Memory Windows】->【Memory1】,在【Address】地址欄中輸入SP的值 0x200019A8,然后查看堆棧里面的值依次是 R0~R3、R12、R14(LR)、PC、XPRS。

------------------------------------- 圖 4 -------------------------------------
顯然堆棧后第21個字節到24字節即為LR,圖4顯示該地址為0x08008263 即為異常前PC將要執行的下一條指令地址。

③ 找到將要執行下一條指令的位置

在Keil菜單欄中點擊【view】->【Disassembly Window】,在【Disassembly Window】窗口中右擊,在下拉菜單中選擇【Show Disassembly at Address...】。在彈出框【Show Code at Address】的地址框中輸入地址 0x08008263 進行搜索,然后就會找到相對應的代碼。

------------------------------------- 圖 5 -------------------------------------

方法2

① 在中斷函數HardFault_Handler里的while(1)處打個斷點


------------------------------------- 圖 6 -------------------------------------

② 返回到出錯的函數位置

在Keil菜單欄點擊【view】->【Call Stack Window】,彈出【Call Stack + Locals】對話框,右鍵點擊對話框中的【HardFault_Handler】,選擇【Show Caller Code】,就會跳到出錯的函數位置。

------------------------------------- 圖 5 -------------------------------------


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM