如何在MCU工程中启用HardFault硬错误中断
文章目录
- 一、HardFault出现场景
- 二、启动HardFault
- 三、C代码示例
一、HardFault出现场景
HardFault(硬故障) 错误中断是 ARM Cortex-M 系列微控制器中一个较为严重的错误中断,一旦触发,表明系统遇到了无法由其他异常处理机制解决的问题。
HardFault 错误中断常见于以下几种触发情况:
-
内存访问错误- 访问非法地址
当代码尝试访问未映射的内存区域,例如访问一个超出芯片内存范围的地址,就会触发 HardFault。比如,使用了一个未初始化的指针,该指针指向一个随机的无效地址,当对这个地址进行读写操作时,就会产生错误。访问受保护的内存区域也会引发问题。一些内存区域可能被设置为只读或者受特殊权限保护,若代码试图对其进行写操作,就会触发 HardFault。 - 内存对齐错误
ARM Cortex - M 处理器对某些数据类型有内存对齐要求。例如,32 位的数据访问需要在 4 字节对齐的地址上进行。如果代码试图在非对齐的地址上进行 32 位数据的读写操作,就可能触发 HardFault。
- 访问非法地址
-
总线错误- 总线传输错误
在数据通过总线进行传输时,可能会因为电气干扰、信号衰减、硬件故障等原因,导致数据传输错误。比如,在外部存储器读写操作中,由于总线线路故障,数据无法正确传输,就会触发 HardFault。 - 总线仲裁失败
当多个主设备同时请求使用总线时,需要进行总线仲裁。如果仲裁机制出现问题,导致某个主设备无法正常获得总线使用权,就可能引发总线错误,进而触发 HardFault。
- 总线传输错误
-
堆栈溢出或损坏- 堆栈溢出
堆栈用于保存函数调用时的局部变量、返回地址等信息。如果函数调用层次过深或者局部变量占用空间过大,就可能导致堆栈溢出。当堆栈溢出发生时,新的数据会覆盖其他重要的内存区域,从而引发 HardFault。 - 堆栈损坏
代码中对堆栈指针的错误操作,例如意外修改了堆栈指针的值,会导致堆栈结构被破坏。后续的函数调用和返回操作就会出现异常,最终触发 HardFault。
- 堆栈溢出
-
异常处理错误- 异常向量表错误
异常向量表存储了各个异常处理函数的入口地址。如果异常向量表被错误修改,或者其地址设置不正确,当发生异常时,处理器无法正确跳转到相应的异常处理函数,就可能触发 HardFault。 - 异常嵌套错误
在异常处理过程中,如果发生了新的异常,并且异常嵌套处理机制出现问题,例如嵌套层数超过了处理器的限制,就会导致系统混乱,触发 HardFault。
- 异常向量表错误
-
指令执行错误- 未定义指令
当处理器执行到一条未定义的指令时,会触发 HardFault。这可能是由于代码中包含了无效的机器码,或者是在程序加载过程中出现了错误。 - 非法指令访问
某些指令可能需要特定的权限才能执行。如果代码在不具备相应权限的情况下尝试执行这些指令,就会触发 HardFault。
- 未定义指令
-
硬件故障- 时钟故障
处理器的正常运行依赖于稳定的时钟信号。如果时钟源出现故障,例如晶振停振、时钟频率偏移过大,会导致处理器的指令执行和数据处理出现异常,从而触发 HardFault。 - 电源故障
电源电压不稳定、过压或欠压等情况,可能会影响处理器内部电路的正常工作,导致数据处理错误,最终引发 HardFault。
- 时钟故障
二、启动HardFault
1. 打开启动文件(.s文件)

在启动文件中,定义中断向量表,为 HardFault 提供占位符处理程序
__Vectors DCD __initial_sp ; 栈顶指针(Top of Stack)DCD HardFault_Handler ; HardFault 处理程序
__initial_sp 是栈顶指针的初始化值,在复位时由处理器自动加载到 SP 寄存器。
HardFault_Handler 是 HardFault 的中断服务程序,在 CPU 触发 HardFault 时会执行这个函数。
2. 占位符的弱定义
HardFault_Handler\PROCEXPORT HardFault_Handler [WEAK]B .ENDP
EXPORT HardFault_Handler [WEAK] 将 HardFault_Handler 导出,并标记为弱定义(WEAK)。
B . 代表无限循环,相当于死循环,防止处理器进入未知状态。
Tips: 由于该 HardFault_Handler只是一个占位符,用户可以在 C 代码中重新定义 HardFault_Handler,而不会与启动文件冲突。
3. 定义源文件 HardFault 处理程序
在 C 代码中,需要实现 HardFault_Handler 以便进行错误分析和调试。
void HardFault_Handler_t(uint8_t * hardfault_args)
{......while(1);
}
在HardFault 中断中一般可以去查看相关寄存器的数值用于分析错误原因,常见寄存器参考如下:
R0 ~ R3:通用寄存器
R12:特殊寄存器
LR(Link Register):返回地址
PC(Program Counter):导致 HardFault 的指令地址
PSR(Program Status Register):状态寄存器Cortex-M 的故障状态寄存器:
BFAR(Bus Fault Address Register):总线错误的地址
CFSR(Configurable Fault Status Register):配置错误状态寄存器
HFSR(Hard Fault Status Register):硬错误状态寄存器
DFSR(Debug Fault Status Register):调试故障状态寄存器
AFSR(Auxiliary Fault Status Register):辅助故障状态寄存器
4. 汇编代码提取堆栈帧
__asm void hard_fault_handler_asm(void)
{IMPORT HardFault_Handler_tTST LR, #4 ; 检查异常发生时使用的堆栈ITE EQMRSEQ R0, MSP ; 如果是主堆栈,获取 MSPMRSNE R0, PSP ; 如果是进程堆栈,获取 PSPB HardFault_Handler_t
}
TST LR, #4:检查 LR(异常返回指针)的 bit 2,判断异常发生时使用的堆栈:
0:使用主堆栈(MSP)1:使用进程堆栈(PSP)
ITE EQ:条件执行语句
MRSEQ R0, MSP:如果使用 MSP,则将 MSP 传入 R0MRSNE R0, PSP:如果使用 PSP,则将 PSP 传入 R0
B HardFault_Handler_t:跳转到 HardFault_Handler_t,并将 R0 作为参数传递。
综上:
- Cortex-M 发生 HardFault 时,处理器跳转到 HardFault_Handler。
- HardFault_Handler由 startup.s 文件定义,但只是一个占位符。
- hard_fault_handler_asm 通过汇编代码获取当前堆栈指针,并传递给 HardFault_Handler_t。
- HardFault_Handler_t解析故障信息,读取寄存器内容,调试解错。
启动文件 负责 定义中断向量表,并提供一个默认的弱定义 HardFault_Handler,允许用户在 C 代码中覆盖它。
汇编代码 负责 提取故障发生时的堆栈帧 并传递给 C 代码。C 代码 负责 解析寄存器信息并打印故障信息,便于调试和分析故障原因。
三、C代码示例
C代码示例可参考如下:
__asm void hard_fault_handler_asm(void)
{IMPORT HardFault_Handler_tTST LR, #4 ; 检查异常发生时使用的堆栈ITE EQMRSEQ R0, MSP ; 如果是主堆栈,获取 MSPMRSNE R0, PSP ; 如果是进程堆栈,获取 PSPB HardFault_Handler_t
}typedef struct
{uint8_t r0;uint8_t r12;uint8_t lr;uint8_t pc;uint8_t psr;
} hardfault_t;
hardfault_t hardfault;void HardFault_Handler_t(unint8_t * hardfault_args)
{hardfault.stacked_r0 = ((uint32_t) hardfault_args[0]);hardfault.stacked_r12 = ((uint32_t) hardfault_args[4]);hardfault.stacked_lr = ((uint32_t) hardfault_args[5]);hardfault.stacked_pc = ((uint32_t) hardfault_args[6]);hardfault.stacked_psr = ((uint32_t) hardfault_args[7]);printf("HardFault_Handler_t!\r\n");printf("R0 = %x\r\n", hardfault.r0);printf("R12 = %x\r\n", hardfault.r12);printf("LR = %x\r\n", hardfault.lr);printf("PC = %x\r\n", hardfault.pc);printf("PSR = %x\r\n", hardfault.psr);while(1);
}相关文章:
如何在MCU工程中启用HardFault硬错误中断
文章目录 一、HardFault出现场景二、启动HardFault三、C代码示例 一、HardFault出现场景 HardFault(硬故障) 错误中断是 ARM Cortex-M 系列微控制器中一个较为严重的错误中断,一旦触发,表明系统遇到了无法由其他异常处理机制解决…...
MySQL -- 复合查询
数据库的查询是数据库使用中比较重要的环节,前面的基础查询比较简单,不做介绍,可自行查阅。本文主要介绍复合查询,并结合用例进行讲解。 本文的用例依据Soctt模式的经典测试表,可以自行下载,也可以自己创建…...
@EnableWebMvc注解导致的坑-记录
1.添加了EnableWebMvc,需要手动添加相关配置,swagger页面问题,出现Unable to render this definition The provided definition does not specify a valid version field. Please indicate a valid Swagger or OpenAPI version field. Suppor…...
卷积神经网络 - 卷积层(具体例子)
为了更一步学习卷积神经网络之卷积层,本文我们来通过几个个例子来加深理解。 一、灰度图像和彩色图像的关于特征映射的例子 下面我们通过2个例子来形象说明卷积层中“特征映射”的概念,一个针对灰度图像,一个针对彩色图像。 例子 1&#x…...
测试Claude3.7 sonnet画蛋白质
测试Claude3.7 sonnet画蛋白虽然画的很粗糙,但是大致画了出来...
java项目之基于ssm的游戏攻略网站(源码+文档)
项目简介 游戏攻略网站实现了以下功能: 管理员主要负责填充图书和其类别信息,并对已填充的数据进行维护,包括修改与删除,管理员也需要审核老师注册信息,发布公告信息,管理自助租房信息等。 💕…...
本地基于Ollama部署的DeepSeek详细接口文档说明
前文,我们已经在本地基于Ollama部署好了DeepSeek大模型,并且已经告知过如何查看本地的API。为了避免网络安全问题,我们希望已经在本地调优的模型,能够嵌入到在本地的其他应用程序中,发挥本地DeepSeek的作用。因此需要知…...
python NameError报错之导库报错
在日常代码编写中,经常出现如 图1 一样的报错,在代码多时很难找到问题,但翻看代码后就会发现是因为未导库, 图1 报错 代码: time.sleep(0.1) print("time库") 解决方法: 第一步:在代码中添加导库代码 import time #…...
Web3网络生态中数据保护合规性分析
Web3网络生态中数据保护合规性分析 在这个信息爆炸的时代,Web3网络生态以其独特的去中心化特性,逐渐成为数据交互和价值转移的新平台。Web3,也被称为去中心化互联网,其核心理念是将数据的控制权归还给用户,实现数据的…...
【数学建模】模糊综合评价模型详解、模糊集合论简介
模糊综合评价模型详解 文章目录 模糊综合评价模型详解1. 模糊综合评价模型概述2. 模糊综合评价的基本原理2.1 基本概念2.2 评价步骤 3. 模糊综合评价的数学模型3.1 数学表达3.2 模糊合成运算 4. 模糊综合评价的应用领域5. 模糊综合评价的优缺点5.1 优点5.2 缺点 6. 模糊综合评价…...
C++ 语法之数组指针
一维数组: 如果我们定义了一个一维数组,那么这个数组名,就是指向第一个数组元素的地址,也即,是整个数组分配的内存空间的首地址。 比如 int a[3]; 定义了一个包含三个元素的数组。因为一个int占4个字节,那…...
从0到1在windows上用flutter开发android app(环境准备、创建项目、加速构建)
一、项目环境准备 1、设置环境变量 需配置以下两个核心环境变量,以替换官方资源链接为国内镜像: Windows系统(通过PowerShell或系统属性面板设置) # 临时生效(当前会话) $env:PUB_HOSTED_URL = "https://pub.flutter-io.cn" $env:FLUTTER_STORAGE_BA…...
PLY格式文件如何转换成3DTiles格式——使用GISBox软件实现高效转换
一、概述 在三维GIS和数字孪生领域,3DTiles格式已成为主流的数据格式之一。它由Cesium团队提出,专为大规模3D数据可视化设计,能够高效地加载和展示海量模型数据。而PLY格式则是一种常见的三维模型文件格式,主要用于存储点云数据或…...
Java定时任务的三重境界:从单机心跳到分布式协调
《Java定时任务的三重境界:从单机心跳到分布式协调》 本文将以生产级代码标准,揭秘Java定时任务从基础API到分布式调度的6种实现范式,深入剖析ScheduledThreadPoolExecutor与Quartz Scheduler的线程模型差异,并给出各方案的性能压…...
响应压缩导致的接口请求response没有响应体问题排查
目录 一、背景二、排查过程三、解决方法四、学习与思考-响应压缩(一)可能原因(二)深入排查(三)注意 一、背景 接口发布到测试环境,测试同学说没有数据 二、排查过程 1、本地用相同的参数、相…...
【Linux网络】手动部署并测试内网穿透
📢博客主页:https://blog.csdn.net/2301_779549673 📢博客仓库:https://gitee.com/JohnKingW/linux_test/tree/master/lesson 📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正! &…...
java项目之在线购物系统(源码+文档)
项目简介 在线购物系统实现了以下功能: 使用在线购物系统的用户分管理员和用户两个角色的权限子模块。 管理员所能使用的功能主要有:主页、个人中心、用户管理、商品分类管理、商品信息管理、系统管理、订单管理等。 用户可以实现主页、个人中心、我的…...
【设计模式】C++ 单例模式总结与最佳实践
1. 单例模式简介 单例模式(Singleton Pattern) 是软件开发中常见的设计模式之一,主要用于 确保某个类只有一个实例,并提供一个全局访问点。常见的使用场景包括: 日志管理:全局唯一的日志记录器。数据库连…...
OO_Unit1
第一次作业 UML类图 代码复杂度分析 其中Expr中的toString方法认知复杂度比较高,主要源于多层条件嵌套和分散的字符串处理逻辑,重构时可重点关注这两部分的解耦。 代码量分析 1.”通用形式“ 我觉得我的设计的最大特点就是“通用形式”,具…...
重要重要!!fisher矩阵元素有什么含义和原理; Fisher 信息矩阵的形式; 得到fisher矩阵之后怎么使用
fisher矩阵元素有什么含义和原理 目录 fisher矩阵元素有什么含义和原理一、对角线元素( F i , i F_{i,i} Fi,i)的含义与原理二、非对角线元素( F i , j F_{i,j} Fi,j)的含义与原理Fisher 信息矩阵的形式矩阵的宽度有位置权重数量决定1. **模型参数结构决定矩阵维度**2.…...
[已解决]jupyter notebook报错 500 : Internal Server Error及notebook闪退
jupyter notebook出现如上图的报错,可以在黑色窗口中检查是为什么报错。 我检查发现是nbconvert导致的问题,卸载重装nbconvert。 但是这时候出现,jupyter notebook闪退问题。jupyter的黑色窗口出现一秒钟就没了。 在Anaconda Prompt中检查ju…...
2025年渗透测试面试题总结- 某亭-安全研究员(题目+回答)
网络安全领域各种资源,学习文档,以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具,欢迎关注。 目录 一、SQL注入过滤单引号绕过方法 二、MySQL报错注入常用函数 三、报错注入绕WAF 四、MySQL写文件函数…...
Redis分布式锁如何实现——简单理解版
目录 前言 满足条件 加锁之后产生的问题 避免死锁的方法 Lua脚本实现避免释放其他锁 看门狗判断过期 扩展 Lua脚本 Redission 前言 在如今开发的某些项目中,多个进程必须以互斥的方式独占共享资源,这时用分布式锁是最直接有效的,分布式…...
数字化转型驱动卫生用品安全革新
当315晚会上晃动的暗访镜头揭露卫生巾生产车间里漂浮的异物、纸尿裤原料仓中霉变的碎屑时,这一触目惊心的场景无情地撕开了“贴身安全”的遮羞布,暴露的不仅是部分企业的道德缺失,更凸显了当前检测与监管体系的漏洞,为整个行业敲响…...
北京南文观点:品牌如何抢占AI 认知的 “黄金节点“
在算法主导的信息洪流中,品牌正在经历一场隐蔽的认知权争夺战,当用户向ChatGPT咨询"哪家新能源车企技术最可靠"时,AI调取的知识图谱数据源将直接决定品牌认知排序。南文乐园科技文化(北京)有限公司ÿ…...
分布式(一):CAPBASE理论
1 CAP理论 1.1 简介 CAP也就是Consistency(一致性)、Availability(可用性)、Partition Tolenrance(分区容错性)这三个单词首字母组合。 在理论计算机科学中,CAP定理(CAP theorem&…...
自适应柔顺性策略:扩散引导控制中学习近似的柔顺
24年10月来自斯坦福大学和 TRI 的论文“Adaptive Compliance Policy: Learning Approximate Compliance for Diffusion Guided Control”。 柔顺性在操作中起着至关重要的作用,因为它可以在不确定的情况下平衡位置和力的并发控制。然而,当今的视觉运动策…...
python中所有内置类型
文章目录 数值类型序列类型集合类型映射类型布尔类型空类型代码汇总 在 Python 中,数据类型可分为内置数据类型和用户自定义数据类型。内置数据类型是 Python 解释器直接支持的类型 数值类型 整数(int):表示整数,可正…...
「Java-API帮助文档」
「Java-API帮助文档」,链接:https://pan.quark.cn/s/d7ced3b48f33 java.applet提供创建 applet 所必需的类和 applet 用来与其 applet 上下文通信的类。java.awt包含用于创建用户界面和绘制图形图像的所有类。java.awt.color提供用于颜色空间的类。java…...
1204. 【高精度练习】密码
文章目录 题目描述输入输出样例输入样例输出数据范围限制CAC代码 题目描述 人们在做一个破译密码游戏: 有两支密码棒分别是红色和蓝色,把红色密码棒上的数字减去蓝色 密码棒上的数字,就是开启密码锁的密码。 现已知密码棒上的数字位数不超过…...
