在用Keil對STM32的程序進行仿真時程序有時會跑飛,停止仿真程序會停在HardFault_Handler函數里的死循環while(1)中。這說明STM32出現了硬件錯誤。
/**
* @brief This function handles Hard Fault exception.
* @param None
* @retval None
*/
void HardFault_Handler(void)
{
/* Go to infinite loop when Hard Fault exception occurs */
while (1)
{
}
}
STM32出現硬件錯誤可能有以下原因:
(1)數組越界操作;
(2)內存溢出,訪問越界;
(3)堆棧溢出,程序跑飛;
(4)中斷處理錯誤;
遇到這種情況,可以通過以下2種方式來定位到出錯代碼段。
方法1
1.1在硬件中斷函數HardFault_Handler里的while(1)處打調試斷點,程序執行到斷點處時點擊“STOP”停止仿真。
1.2 在Keil菜單欄點擊“View”——“Registers Window”,在寄存器查看窗口查找R14(LR)的值。如果R14(LR) = 0xFFFFFFE9,繼續查看MSP(主堆棧指針)的值,如果R14(LR) = 0xFFFFFFFD,繼續查看PSP(進程棧指針)的值。我的程序R14(LR) = 0xFFFFFFF9,接下來以此為例。
1.3 在Keil菜單欄點擊“View”——“Memory Windows”——“Memory1”,在“Address”地址欄中輸入MSP的值:0x20001288,然后在對應的行里找到地址。地址一般以0x08開頭的32位數。本例中,地址為0x08003CB9。
1.4 在Keil菜單欄點擊“View”——“Disassembly Window”,在“Disassembly”窗口中右擊,在下拉菜單中選擇“Show Disassemblyat Address...”。在彈出框“Show Code atAdress”的地址框中輸入地址0x08003CB9進行搜索,然后就會找到相對應的代碼。這里的代碼就是進入循環中斷之前的情況。仔細查看附近區域的相關代碼來排查錯誤具體原因。
方法2
2.1在硬件中斷函數HardFault_Handler里的while(1)處打調試斷點,程序執行到斷點處時點擊“STOP”停止仿真。
2.2 在Keil菜單欄點擊“View”——“Call Stack Window”彈出“Call Stack + Locals”對話框。然后在對話框中右鍵選擇“Show Caller Code”,就會跳轉到出錯之前的函數處,仔細查看這部分函數被調用或者數組內存使用情況。
方法3
另一種方法:
默認的HardFault_Handler處理方法不是B .這樣的死循環么?樓主將它改成BX LR直接返回的形式。然后在這條語句打個斷點,一旦在斷點中停下來,說明出錯了,然后再返回,就可以返回到出錯的位置的下一條語句那兒
__asm void wait()
{
BX lr
}
void HardFault_Handler(void)
{
/* Go to infinite loop when Hard Fault exception occurs */
wait();
}
在HardFault_Handler函數里加上一行軟中斷:__asm voalite ("BKPT #1");打開編譯器的CALL STACK,全速跑一下,如果進入了軟中斷,查看CALL STACK就知道是哪一個函數進入HardFault_Handler了。
方法4
使用庫:CmBacktrace-master,結合一個小工具可以定位,需要axf文件。