Hard Fault 异常调试方法_go to infinite loop when hard fault exception occu

91 阅读4分钟

[cpp]  view plain  copy

 print ?

  1. /**

  2. * @brief  This function handles Hard Fault exception.

  3. * @param  None

  4. * @retval None

  5. */

  6. void HardFault_Handler(void)

  7. {

  8. /* Go to infinite loop when Hard Fault exception occurs */

  9. if (CoreDebug->DHCSR & 1) {  //check C_DEBUGEN == 1 -> Debugger Connected

  10. __breakpoint(0);  // halt program execution here

  11. }

  12. while (1)

  13. {

  14. }

  15. }

当进入Hard Fault断点后,菜单栏Peripherals >Core Peripherals >Fault Reports打开异常发生的报告,查看发生异常的原因。

  


上面的报告发生了BUS FAULT,并将Fault的中断服务转向Hard Fault。

相对于检测发生了什么异常,定位异常发生位置显得更重要。
(1)打开Call Stack窗口(如下图左侧,断点停在Hard Fault服务程序中)


(2)在Call Stack的HardFault_Handler上右键Show Caller Code(有的Keil版本也可以直接双击)

这时将跳转到发生异常的源代码位置(如上图),异常发生在p->hour=0这一行。这里错误很明显:指针p尚未为成员变量分配内存空间,直接访问未分配的内粗空间肯定出错。

再说明2点:
[1] 在复杂的情况下,即使定位了异常发生位置也很难容易的改正错误,要学会使用Watch窗口对发生错误的指针变量进行跟踪;
[2] 在问题不明晰的情况下,尝试分析反汇编代码,就自己遇到的,部分情况下的异常发生在BL等跳转指令处,BL跳转到了不合法的内存地址产生异常


在没有JTAG的情况下,通过串口打印出堆栈信息:

 1 /\* Private typedef -----------------------------------------------------------\*/
 2 enum { r0, r1, r2, r3, r12, lr, pc, psr};
 3 
 4 /\* Private define ------------------------------------------------------------\*/
 5 /\* Private macro -------------------------------------------------------------\*/
 6 /\* Private variables ---------------------------------------------------------\*/
 7 extern __IO uint16_t ADC_InjectedConvertedValueTab[32];
 8 uint32_t Index = 0;
 9 
 10 /\* Private function prototypes -----------------------------------------------\*/
 11 void Hard\_Fault\_Handler(uint32\_t stack[]);
 12 
 13 /\* Private functions ---------------------------------------------------------\*/
 14 
 15 static void printUsageErrorMsg(uint32\_t CFSRValue)
 16 {
 17     printf("Usage fault: \r\n");
 18     CFSRValue >>= 16; // right shift to lsb
 19 
 20     if((CFSRValue & (1<<9)) != 0) {
 21         printf("Divide by zero \r\n");
 22     }
 23     if((CFSRValue & (1<<8)) != 0) {
 24         printf("Unaligned access \r\n");
 25     }
 26 }
 27 
 28 static void printBusFaultErrorMsg(uint32\_t CFSRValue)
 29 {
 30     printf("Bus fault: \r\n");
 31     CFSRValue = ((CFSRValue & 0x0000FF00) >> 8); // mask and right shift to lsb
 32 }
 33 
 34 static void printMemoryManagementErrorMsg(uint32\_t CFSRValue)
 35 {
 36     printf("Memory Management fault: \r\n");
 37     CFSRValue &= 0x000000FF; // mask just mem faults
 38 }
 39 
 40 static void stackDump(uint32\_t stack[])
 41 {
 42   static char msg[80];
 43   sprintf(msg, "R0 = 0x%08x\r\n", stack[r0]); printf(msg);
 44   sprintf(msg, "R1 = 0x%08x\r\n", stack[r1]); printf(msg);
 45   sprintf(msg, "R2 = 0x%08x\r\n", stack[r2]); printf(msg);
 46   sprintf(msg, "R3 = 0x%08x\r\n", stack[r3]); printf(msg);
 47   sprintf(msg, "R12 = 0x%08x\r\n", stack[r12]); printf(msg);
 48   sprintf(msg, "LR = 0x%08x\r\n", stack[lr]); printf(msg);
 49   sprintf(msg, "PC = 0x%08x\r\n", stack[pc]); printf(msg);
 50   sprintf(msg, "PSR = 0x%08x\r\n", stack[psr]); printf(msg);
 51 }
 52 
 53 void Hard\_Fault\_Handler(uint32\_t stack[])
 54 {
 55   static char msg[80];
 56   //if((CoreDebug->DHCSR & 0x01) != 0) {
 57     printf("\r\nIn Hard Fault Handler\r\n");
 58     sprintf(msg, "SCB->HFSR = 0x%08x\r\n", SCB->HFSR);
 59     printf(msg);
 60     if ((SCB->HFSR & (1 << 30)) != 0) {
 61       printf("Forced Hard Fault\r\n");
 62       sprintf(msg, "SCB->CFSR = 0x%08x\r\n", SCB->CFSR );
 63       printf(msg);
 64       if((SCB->CFSR & 0xFFFF0000) != 0) {
 65         printUsageErrorMsg(SCB->CFSR);
 66       }
 67       if((SCB->CFSR & 0xFF00) != 0) {
 68         printBusFaultErrorMsg(SCB->CFSR);
 69       }
 70       if((SCB->CFSR & 0xFF) != 0) {
 71         printMemoryManagementErrorMsg(SCB->CFSR);
 72       }
 73     }
 74     stackDump(stack);
 75     __ASM volatile("BKPT #01");
 76   //}
 77   while(1);
 78 }
 79 
 80 
 81 __ASM void HardFault_Handler_a(void)
 82 {
 83   IMPORT Hard\_Fault\_Handler
 84 
 85   TST lr, #4
 86   ITE EQ
 87   MRSEQ r0, MSP
 88   MRSNE r0, PSP
 89   B Hard\_Fault\_Handler
 90 }
 91 
 92 /\*\*
 93 \* @brief This function handles Hard Fault exception.
 94 \* @param None
 95 \* @retval None
 96 \*/
 97 void HardFault_Handler(void)
 98 {
 99   /\* Go to infinite loop when Hard Fault exception occurs \*/
100   HardFault\_Handler\_a();
101 }

img img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取