HardFault_Handler棧溢出檢查機制,適用於所有CM3芯片,造成主棧(MSP)溢出的原因有很多,如過多的定義局部變量,遞歸調用,中斷嵌套等都有可能會導致主棧溢出,stm32不具備MPU,沒有對內存進行保護的硬件機制,而軟件檢測棧溢出又有其局限性
STM32出現HardFault_Handler故障的原因主要有兩個方面:
1、內存溢出或者訪問越界。這個需要自己寫程序的時候規范代碼,遇到了需要慢慢排查。
2、堆棧溢出。增加堆棧的大小。大多數是因為中斷嵌套
寄存器均是32位,且STM32是小端模式(參考Cortex-M3權威)
實現原理:1、將主棧的棧底定位在0x20000000處,當主棧溢出時將導致數據被push到低於0x20000000的非法區域,從而觸發HardFault異常
2、由於進入HardFault_Handler后棧有可能已經溢出了,C語言的運行環境可能已不存在,故HardFault_Handler需要改用匯編來實現
在HardFault_Handler中先根據LR的值判斷當前使用的棧是主MSP還是PSP,然后檢查 if(BFSR==0x00000092) if(MMAR==0x1FFFFFFC) if(SP<0x20000000)
這三個條件是否同時滿足,如果同時滿足則可判斷主棧確實溢出了,否則可判斷出不是因為棧溢出而觸發的HardFault異常
出現問題時排查的方法:DEBUG,下斷點單步看程序停在哪
另一種方法:
默認的HardFault_Handler處理方法不是B .這樣的死循環么?樓主將它改成BX LR直接返回的形式。
然后在這條語句打個斷點,一旦在斷點中停下來,說明出錯了,然后再返回,就可以返回到出錯的位置的下一條語句那兒
__asm void wait()
{
BX lr
}
void HardFault_Handler(void)
{
/* Go to infinite loop when Hard Fault exception occurs */
wait();
}