news 2026/10/10 1:29:45

d32 单片机 出现hardfault时,定位崩溃的地址

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
d32 单片机 出现hardfault时,定位崩溃的地址

出现崩溃

当 ARM Cortex-M 系列芯片进入 HardFault 异常,可以查看寄存器去排查问题。

如下,PC寄存器指向的是当前执行的代码的位置。

定位堆栈指针

在进入hardfault之后,我们可以通过查看堆栈的内容去排查问题。
堆栈分为两种堆栈,一个是主堆栈MSP,另一个是线程堆栈PSP。
要确定当前堆栈指针是MSP还是PSP,我们需要去查看R14(LR)的值。

在Cortex_M3权威指南中可以看到如下图所示:

当LR = 0xFFFFFFF9时,表示异常发生前,处理器正在使用的是主堆栈(MSP);
当LR = 0xFFFFFFFD时,表示异常发生前,处理器正在使用进程栈(PSP)

Cortex-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~R3,R12,LR,PC,XPRS寄存器依次入栈

其中LR 的核心功能是保存函数的返回地址,PC的值是0,说明堆栈出现了异常,我们当前只能先通过LR来定位问题了。


我们在0x080042B2这里打断点,查看具体出错的原因

第一次进入这里是

发现在第二次进入 这里是如下,然后就跑0x0000000的地址了


我们在继续具体分析

pop命令的作用如下,即从SP指向的栈中弹出两个栈顶数据,并保存在PR,PC中。

查看SP执行的栈中的内容,可以看到等下PC是被赋值成0x080034AD

然后单步运行一下,看到程序跑到了0x080034AC(疑问:为什么不是0x080034AD)


接着第二次全速运行,再次到0x080042B2断点


查看SP指向的栈,果然,全部的数据都是0x00000000,这时就要分析为什么数据都是0


怀疑是堆栈的问题,但是经过检测,没有内存的错乱。

于是就还怀疑是系统的问题,就去查看了系统堆栈的初始函数,不看不知道一看就发现FPU开启后,系统堆栈的内容是不一样的。

百度内容如下,开启了FPU后,内核会额外保存浮点寄存器的状态


查询了一下是如何开启FPU的

结果一看,果然是开启了FPU。


解决方法

  1. 关闭FPU

  2. 改变ucosii的入栈,读栈方式


版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/10 1:28:04

如何在macOS桌面应用集成Highcharts

Highcharts 是一个基于 JavaScript 的 Web 图表库,没有原生 macOS 桌面库。 在 macOS 应用中,常见方式是通过 WKWebView 加载本地网页;如果应用基于 Electron,也可以按普通 Web 应用的方式集成。 SwiftUI WKWebView 将 Highch…

作者头像 李华
网站建设 2026/10/10 1:25:07

深度解析微信小程序及公众号获取code的方法与技巧

在微信小程序和公众号的开发过程中,获取code是进行用户身份验证的关键步骤。本文将详细介绍如何获取code,包括微信小程序和公众号两种场景下的获取方法,以及相关技巧。 一、微信小程序获取code 获取微信提供的用户身份标识,从而使…

作者头像 李华