恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
d32 单片机 出现hardfault时,定位崩溃的地址
首页
资讯中心
/
d32 单片机 出现hardfault时,定位崩溃的地址
d32 单片机 出现hardfault时,定位崩溃的地址
发布时间:2026/10/10 1:29:48
出现崩溃当 ARM Cortex-M 系列芯片进入 HardFault 异常可以查看寄存器去排查问题。如下PC寄存器指向的是当前执行的代码的位置。定位堆栈指针在进入hardfault之后我们可以通过查看堆栈的内容去排查问题。堆栈分为两种堆栈一个是主堆栈MSP另一个是线程堆栈PSP。要确定当前堆栈指针是MSP还是PSP我们需要去查看R14(LR)的值。在Cortex_M3权威指南中可以看到如下图所示当LR 0xFFFFFFF9时表示异常发生前处理器正在使用的是主堆栈MSP当LR 0xFFFFFFFD时表示异常发生前处理器正在使用进程栈PSPCortex-M 异常发生时硬件会自动将核心寄存器 “压栈”Push到当前使用的栈这个压栈的内容就是异常栈帧也是 PSP 指向地址存储的核心内容。PSP或MSP 指向的地址及下方 32 字节存储了 R0-R3、R12、LR、PC、xPSR 共 8 个寄存器的异常前值其中 PC 值是定位 HardFault 根因的核心。在上图中我们可以看到LR寄存器中的值是0xFFFFFFFD。次数PSP 寄存器指向的地址里具体存储了哪些内容。因此我应该去看PSP的地址找到该地址的地址然后如下图所示打开内存输入上面找到的寄存器地址0x20003BA0右键选择以long型查看地址如下所示然后查看这个地址向下数六个long地址为什么是6个long地址呢因为由于异常发生时内核将R0~R3R12LRPCXPRS寄存器依次入栈其中LR 的核心功能是保存函数的返回地址PC的值是0说明堆栈出现了异常我们当前只能先通过LR来定位问题了。我们在0x080042B2这里打断点查看具体出错的原因第一次进入这里是发现在第二次进入 这里是如下然后就跑0x0000000的地址了我们在继续具体分析pop命令的作用如下即从SP指向的栈中弹出两个栈顶数据并保存在PRPC中。查看SP执行的栈中的内容可以看到等下PC是被赋值成0x080034AD然后单步运行一下看到程序跑到了0x080034AC疑问为什么不是0x080034AD接着第二次全速运行再次到0x080042B2断点查看SP指向的栈果然全部的数据都是0x00000000这时就要分析为什么数据都是0怀疑是堆栈的问题但是经过检测没有内存的错乱。于是就还怀疑是系统的问题就去查看了系统堆栈的初始函数不看不知道一看就发现FPU开启后系统堆栈的内容是不一样的。百度内容如下开启了FPU后内核会额外保存浮点寄存器的状态查询了一下是如何开启FPU的结果一看果然是开启了FPU。解决方法关闭FPU改变ucosii的入栈读栈方式