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

相关推荐
计算机毕设定制辅导-无忧学长1 小时前
西门子 PLC 与 Modbus 集成:S7-1500 RTU/TCP 配置指南(一)
服务器·数据库·tcp/ip
程序员柳2 小时前
基于微信小程序的校园二手交易平台、微信小程序校园二手商城源代码+数据库+使用说明,layui+微信小程序+Spring Boot
数据库·微信小程序·layui
梦在深巷、2 小时前
MySQL/MariaDB数据库主从复制之基于二进制日志的方式
linux·数据库·mysql·mariadb
IT乌鸦坐飞机2 小时前
ansible部署数据库服务随机启动并创建用户和设置用户有完全权限
数据库·ansible·centos7
IT_10242 小时前
Spring Boot项目开发实战销售管理系统——数据库设计!
java·开发语言·数据库·spring boot·后端·oracle
祁思妙想3 小时前
八股学习(三)---MySQL
数据库·学习·mysql
惊骇世俗王某人4 小时前
1.MySQL之如何定位慢查询
数据库·mysql
秦歌6664 小时前
向量数据库-Milvus快速入门
数据库·milvus
Edingbrugh.南空6 小时前
Flink SQLServer CDC 环境配置与验证
数据库·sqlserver·flink
码不停蹄的玄黓6 小时前
MySQL分布式ID冲突详解:场景、原因与解决方案
数据库·分布式·mysql·id冲突