遇到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

相关推荐
nicepainkiller1 小时前
go 分布式redis锁的实现方式
数据库·redis·redis分布式锁
007php0071 小时前
企微审批中MySQL字段TEXT类型被截断的排查与修复实践
大数据·开发语言·数据库·后端·mysql·重构·golang
Elastic 中国社区官方博客1 小时前
使用 Elasticsearch 进行集成测试初始化数据时的注意事项
大数据·数据库·elasticsearch·搜索引擎·集成测试·可用性测试
V+zmm101341 小时前
美食推荐系统的微信小程序+论文源码调试讲解
java·数据库·微信小程序·小程序·毕业设计
SelectDB技术团队2 小时前
Apache Doris 3.0.4 版本正式发布
大数据·数据库·数据分析·doris·存算分离
自不量力的A同学2 小时前
GreptimeDB v0.12 发布,开源 Rust 时序数据库
数据库·开源·时序数据库
老马啸西风2 小时前
聊一聊 IM 如何优化缓存
数据库·缓存·ai·优化·性能·im
文城5213 小时前
第十章 数据库恢复技术
数据库
文弱书生子3 小时前
中间件专栏之MySQL篇——MySQL的索引原理
数据库·mysql·中间件
小林熬夜学编程3 小时前
【MySQL】第十二弹---表连接详解:从内连接到外连接
linux·开发语言·数据库·mysql·算法