代码进入HardFault_Handler,如何查找到故障位置
代码进入HardFault_Handler,如何查找到故障位置
先设置成不复位进入调试界面,不能破坏现场,有单独的笔记说明怎么进入调试,这里不赘述。
第一步:找到 HardFault 的核心寄存器
当进入 HardFault 中断服务函数时,CPU 会自动将以下 8 个寄存器压入栈中(如果是 MSP 栈)或部分压入(如果是 PSP 栈)。MSP是默认的,裸机开发,只要没去设置默认就是他。
PSP进程栈在有RTOS时,执行任务函数时使用的是PSP进程栈。
-
R0~R3:函数参数或局部变量。
-
R12:内部调用寄存器(IP)。
-
LR (R14):链接寄存器,通常存储着发生错误时的返回地址(最关键)。
-
PC (R15):程序计数器,存储着发生错误时正在执行的指令地址(最关键)。
-
xPSR:程序状态寄存器。
第二步:判断当前使用的是哪个栈(MSP 还是 PSP)
在 Cortex-M 内核中,有两个栈指针:主栈指针(MSP)和进程栈指针(PSP)。
- MSP:通常用于中断和系统启动。
- PSP:通常用于普通的 C 代码任务(在使用 RTOS 如 FreeRTOS 时,任务默认使用 PSP)。
在 Cortex-M 内核中
-
如果
LR = 0xFFFFFFF1:返回到主栈(MSP)。 -
如果
LR = 0xFFFFFFF9:返回到主栈(MSP)(中断嵌套)。 -
如果
LR = 0xFFFFFFFD:返回到进程栈(PSP)。以上图为例,

LR = 0xFFFFFFFD 进程栈,如果是MSP(裸机)那PC 0800058E 就是出错的位置。但是现在明显使用的是PSP,推测是使用了RTOS ,那此时PC就不是出错的位置了,并且sp的指针也不是PSP,是MSP的因为进入HardFault_Handler中断会切换到MSP。那我们怎么找到PSP当前的值是多少呢
在command命令中输入PSP

然后将这里的PSP值在Memory中查找PSP地址

上面说明了进入HardFault会压栈说明寄存器,不赘述。
以上图可知 (stm32小端存储)
R0 = 0x0000000A R1 = 0x00000000 R2 = 0xFFFFFFFF R3 = 0x00000000
R12 = 0x00000000 LR = 0x08001343 PC = 0x08000613 xPSR = 0x41000000
此时我们获取到了 进入HardFault的寄存器状态了。下一步右键选择

输入PC 地址

找到了是那句导致的错误了。
LR是故障函数的返回地址,xPSR是状态寄存器,我们就更具他们来分析故障了。

浙公网安备 33010602011771号