遇到hardfault怎么办?

文章目录

  • [HardFault 分析教程](#HardFault 分析教程)
    • [1. 定位HardFault产生的位置](#1. 定位HardFault产生的位置)
      • [1.1 先修基础知识](#1.1 先修基础知识)
      • [1.2 C语言版本](#1.2 C语言版本)
      • [1.3 汇编语言版本](#1.3 汇编语言版本)
      • [1.4 操作方法](#1.4 操作方法)
    • [2. 分析HardFault原因](#2. 分析HardFault原因)
      • [2.1 Chinese version](#2.1 Chinese version)

HardFault 分析教程

Teach you how to locate HardFault and analyze its causes(教你如何定位HardFault,并分析HardFault的原因)

1. 定位HardFault产生的位置

操作方法:把你的void HardFault_Handler(void) 替换成下摆你这段代码,然后在hardfault处打断点,单步执行就可以找到问题原因处

1.1 先修基础知识

参考文档-HardFault定位方法


总结:根据单片机进中断,寄存器压栈情况,压栈时候把LR寄存器值(存储着返回来要执行的程序地址)也压进去了,那只需要在hardfault ISR里边把LR值取出来赋值给PC就可以定位到引发hardfault的地方,如下面操作,不过这个只是定位到了引发hardfault的位置,下一步还需要结合hradfault状态寄存器分析产生的具体原因

1.2 C语言版本

注意!! 下边的MSP值+0X1C为存 LR的值,这个不同核心单片机有区别,M3核的理论上来说加0X14就可以了,但是M0核得+0x1C,实践得出来的结果

c 复制代码
// Return the R13(Stack Pointer)
__ASM unsigned int __Get_SP_Value(void)
{
    mov r0, r13 //R13(SP)
    bx lr
}

void (*f1)(void);
unsigned int result;

void HardFault_Handler(void)
{
    //实际操作Arm Coretex-M0核心的是+0x1C,M3核的是+0X14
    result = __Get_SP_Value()+0x14;
    f1 = *( (unsigned int*)result );
    f1();
    while (1);
}

1.3 汇编语言版本

注意!! 下边的MSP值+0X1C为存 LR的值,这个不同核心单片机有区别,M3核的理论上来说加0X14就可以了,但是M0核得+0x1C,实践得出来的结果

armasm 复制代码
;把你的起始.s文件内的HardFault_Handler代码换成下边这个

HardFault_Handler\
                PROC
                add   r0, sp, #0x14     
                ldr   r1, [r0]          
                blx   r1                
                B       .
                ENDP

1.4 操作方法

当产生了hardfault后,选择上述1.2或者1.3的代码方案后,debug 在hardfult处打断点执行到hardfault ISR处之后再单步执行,就可以找到出问题的地方了


2. 分析HardFault原因

分析产生HardFault的原因(需要具体代码具体分析仔细崩溃处的代码的问题)

hardfault产生的原因有很多,例如访问非法地址了,函数指针变量为NULL,然后直接运行了,总共包含以下几种

  1. 内存访问错误
  • 访问了未映射的内存区域。

  • 对只读内存区域执行写操作。

  • 访问了无效的内存地址(如NULL指针解引用)。

  1. 堆栈溢出:
  • 如果任务或中断的堆栈空间不足,可能导致堆栈溢出,进而破坏内存或触发HardFault。
  1. 未对齐的内存访问:
  • 某些STM32系列要求特定的数据类型在内存中对齐。未对齐的访问可能触发HardFault。
  1. 错误的异常处理:
  • 如果在异常处理程序中再次发生异常,且没有正确处理,可能会导致HardFault。
  1. 中断优先级配置错误:
  • 如果配置了错误的中断优先级,可能导致不可屏蔽中断(NMI)或HardFault。
  1. 非法指令或状态:
  • 执行了未定义的指令。

  • 尝试切换到无效的处理器模式。

  1. 外设配置错误:
  • 错误地配置或使用了外设,如未启用时钟就访问外设寄存器。
  1. 电源问题:
  • 不稳定的电源可能导致处理器行为异常,从而触发HardFault。
  1. 软件错误:
  • 逻辑错误、数组越界、类型转换错误等编程错误也可能导致HardFault。

但是这些太笼统了,太废话了,具体是哪个呢?? 那还得看HardFault状态寄存器(HFSR)以及其他相关的故障状态寄存器,如配置管理故障状态寄存器(CFSR)、内存管理故障状态寄存器(MMFSR)、总线故障状态寄存器(BFSR)和使用故障状态寄存器(UFSR)。

下图是HardFault状态寄存器,引发hardfault了可以看看这个寄存器值,然后再仔细检查下代码


2.1 Chinese version

相关推荐
吠品9 分钟前
PG_GBK 与 PG_UTF8 编码冲突:一次数据导入踩坑复盘
数据库
lld95102716 分钟前
我做了一个 AI Agent Skill 云:用 MCP 在 Claude Code、Codex、OpenCode 之间同步技能
数据库·人工智能
辉灰笔记1 小时前
MySQL8 意外关机/误移data目录导致服务启动失败 PID报错/权限报错 修复文档
linux·数据库·mysql·centos
麦聪聊数据2 小时前
电商大促数据库管控(下):数据需求小时级交付与全链路安全管控
数据库
喜欢的名字被抢了2 小时前
MySQL核心机制:事务、锁与存储引擎
数据库·sql·mysql·教程
JosieBook3 小时前
【数据库】时序数据库通过国测认证,TimechoAI开放体验:工业数据的“存”与“智”如何协同?
数据库·时序数据库
卓怡学长3 小时前
w263基于springboot + vue 健康饮食管理系统
java·数据库·vue.js·spring boot·spring·intellij-idea
阿演5 小时前
DataDjinn v0.2.11:SQL 编辑、AI 协作和表格操作继续打磨
数据库·人工智能·sql
不坑老师6 小时前
Excel总表如何按班级拆分并分别发送?
前端·数据库·人工智能·excel·ppt·office
智脑API平台6 小时前
Codex 国内使用会封号吗?账号安全、中转站和合规边界说明
数据库·redis·缓存