SXSBJSXYT

保持热爱,奔赴山海

 

关于程序进入HardFault_Handler中的排查方法

1.出现问题的现象

        在用Keil对STM32的程序进行DEBUG时,程序有时候回跑飞,STOP DEBUG会停在HardFault_Handler函数里的死循环while(1)中,这说明STM32出现了硬件错误。

图1.1-HardFault_Handler

        STM32出现HardFault_Handler故障的原因主要有3个方面:

  1. 栈溢出;
  2. 内存非法访问;
  3. 中断异常处理错误;

2.排查措施

2.1方法1:

①主堆栈与进程堆栈的确认

        发生异常后先查看LR寄存器中的值,确定当时使用堆栈为MSP还是PSP。 在Keil菜单栏点击【view】->【Registers Window】打开寄存器窗口,查看 R14(LR) 的值。

  • 若R14(LR) = 0xFFFFFFF9, 查看 MSP(主堆栈指针)的值;
  • 若R14(LR) = 0xFFFFFFFD, 查看 PSP(进程栈指针)的值。
图2.1-EXC_RETURN值(权威手册)
图2.2-内核寄存器组

        上图的R14(LR) = 0xFFFFFFFD,则查看 PSP(进程栈指针)的值。

② 查看堆栈里的内容

        由于异常发生时,内核将R0~R3、R12、R14(LR)、PC、XPRS寄存器依次入栈,其中R14(LR)即为发生异常前PC将要执行的下一条指令地址。(注意:寄存器均是32位、且STM32是小端模式。)

图2.3-入栈序列(CM3内核权威手册)
图2.4-入栈动作(CM3内核权威手册)

        从图2-2可看到SP的值为 0x200019A8,在Keil菜单栏点击【view】->【Memory Windows】->【Memory1】,在【Address】地址栏中输入SP的值 0x200019A8,然后查看堆栈里面的值依次是 R0~R3、R12、R14(LR)、PC、XPRS。

        堆栈后第21个字节到24字节即为LR,上图显示该地址为0x08008263 即为异常前PC将要执行的下一条指令地址。

③ 定位将要执行下一条指令的位置

        在Keil菜单栏中点击【view】->【Disassembly Window】,在【Disassembly Window】窗口中右击,在下拉菜单中选择【Show Disassembly at Address...】。在弹出框【Show Code at Address】的地址框中输入地址 0x08008263 进行搜索,然后就会找到相对应的代码。

2.2方法2:

① 在HardFault_Handler里下断点

② 定位到出错的函数位置

        在Keil菜单栏点击【view】->【Call Stack Window】,弹出【Call Stack + Locals】对话框,右键点击对话框中的【HardFault_Handler】,选择【Show Caller Code】,就会跳到出错的函数位置。


 

posted on 2025-05-20 18:36  SXSBJSXYT  阅读(77)  评论(0)    收藏  举报  来源

导航