当前位置:   article > 正文

单片机Hard fault 产生原因和错误跟踪的方法_单片机进hardfault原因

单片机进hardfault原因

一、单片机 Hard fault产生的原因

Hard fault产生的原因有两方面,硬件方面和软件方面。

①硬件方面常见原因: 

电源设计有错误,造成器件供电不稳; 

电源质量不好,纹波,噪声过大; 

器件接地不良; 

对于带有 Vcap 引脚的器件,管脚处理不当; 

电路中有强干扰源,对器件造成干扰; 

②软件方面常见原因: 

使用了空指针; 

对地址偏移量的计算有误; 

数组越界导致程序出错; 

动态内存使用不当,导致访问了已释放的内存地址; 

通过地址访问了已失效的局部变量; 

一般因为硬件造成 Hard Fault 错误的可能性较低,大多数都是软件原因造成的。所以遇到硬件中断错误,基本就是通过软件来排查。

二、CmBacktrace软件包

CmBacktrace (Cortex Microcontroller Backtrace)是一款针对 ARM Cortex-M 系列 MCU 的错误代码自动追踪、定位,错误原因自动分析的开源库。主要特性如下:

①支持的错误包括:断言(assert) 故障(Hard Fault, Memory Management Fault, Bus Fault, Usage Fault, Debug Fault)

②故障原因自动诊断 :可在故障发生时,自动分析出故障的原因,定位发生故障的代码位置,而无需再手动分析繁杂的故障寄存器;

③输出错误现场的 函数调用栈(需配合 addr2line 工具进行精确定位),还原发生错误时的现场信息,定位问题代码位置、逻辑更加快捷、精准。也可以在正常状态下使用该库,获取当前的函数调用栈;

④支持裸机及以下操作系统平台:RT-Thread UCOS FreeRTOS(需修改源码)

⑤根据错误现场状态,输出对应的 线程栈 或 C 主栈;

⑥故障诊断信息支持多国语言(目前:简体中文、英文);

⑦适配 Cortex-M0/M3/M4/M7 MCU;

⑧支持 IAR、KEIL、GCC 编译器; 

如何移植 

准备工作 

①查看 \demos 目录下有没有合适自己的 Demo ,如有类似,则建议在其基础上修改 ;

②明确操作系统/裸机平台及 CPU 平台 ;

③将 \src 下的全部源文件添加至产品工程中,并保证源码目录被添加至头文件路径 ;

④cmb_fault.s 汇编文件(点击查看)可以选择性添加至工程,添加后需要把项目原有的 HardFault_Handler 注释掉 

⑤把 cm_backtrace_init 函数放在项目初始化地方执行 

⑥将 cm_backtrace_assert 放在项目的断言函数中执行,具体使用方法参照下面的 API 说明 

⑦如果第 4 步骤没有将 cmb_fault.s 汇编文件启用,则需要将 cm_backtrace_fault 放到故障处理函数(例如:HardFault_Handler )中执行,具体使用方法参照下面的 API 说明 配置说明 配置文件名:cmb_cfg.h ,针对不同的平台和场景,用户需要自自行手动配置,常用配置如下:

add48978c5fd86cfac53d19ec4b74ec6.png

注意:以上部分配置的内容可以在 cmb_def.h 中选择,更多灵活的配置请阅读源码。

三、addr2line工具

addr2line (它是标准的 GNU Binutils 中的一部分)是一个可以将指令的地址和可执行映像转换成文件名、函数名和源代码行数的工具。

如何获得 addr2line,Linux 系统一般会集成这个工具,本文重点介绍 Windows 系统下如何获取该工具。方法很多,我这里仅介绍两种方式。

第一种:安装 MinGW(网上教程很多,自行搜索),安装后在其安装目录的 bin 文件夹里会包含 addr2line.exe ,此时只用保证环境变量 path 中包含该路径即可;

第二种(XP 平台除外):在本项目的 tools 文件夹中已存放 addr2line.exe ,可以将其直接拷贝至 C:\Windows 下,或者将 CmBacktrace 仓库的 tools 文件夹路径添加至到环境变量 path 中,这样都能保证命令行工具能正常使用 addr2line 命令。

四、实际测试

基于rt-thread的bsp工程测试。使用env工具添加软件包,如下图

66843bb2ed28dc314a6f87caa6f89f7a.png

重新生成工程,看到软件包已经添加。

ca3aa0a3b46f1c616b53dba867543472.png

使用方法,系统自动初始化了函数int rt_cm_backtrace_init(void),也可以不使用自动初始化函数改为手动调用初始化。

直接编译,无错误,下载到测试板进行测试,测试指令

cmb_test DIVBYZERO
  1. [2023-06-20 09:41:46.648]
  2. TX:cmb_test DIVBYZERO
  3. [2023-06-20 09:41:47.852]
  4. RX:cmb_test DIVBYZERO
  5. thread pri status sp stack size max used left tick error
  6. -------- --- ------- ---------- ---------- ------ ---------- ---
  7. tshell 20 running 0x00000098 0x00001000 04% 0x00000007 000
  8. tidle0 31 ready 0x00000048 0x00000400 10% 0x00000009 000
  9. main 10 suspend 0x00000084 0x00000800 12% 0x00000013 000
  10. Firmware name: rtthread, hardware version: 1.0, software version: 1.0 Fault on thread tshell ===== Thread stack information ===== addr: 20002bf0 data: 00000000 addr: 20002bf4 data: 00000008 addr: 20002bf8 data: 20001b6a addr: 20002bfc data: 08002f41 addr: 20002c00 data: 00000000 addr: 20002c04 data: 20001b6a addr: 20002c08 data: 20001b73 addr: 20002c0c data: 00000000 addr: 20002c10 data: 00000000 addr: 20002c14 data: 00000000 addr: 20002c18 data: 00000000 addr: 20002c1c data: 00000000 addr: 20002c20 data: 00000000 addr: 20002c24 data: 00000000 addr: 20002c28 data: 00000000 addr: 20002c2c data: 20001b6a addr: 20002c30 data: 00000012 addr: 20002c34 data: deadbeef addr: 20002c38 data: deadbeef addr: 20002c3c data: deadbeef addr: 20002c40 data: deadbeef addr: 20002c44 data: 08006437 addr: 20002c48 data: 00000000 addr: 20002c4c data: 0000000d addr: 20002c50 data: 200005c0 addr: 20002c54 data: 08004ba5 addr: 20002c58 data: 23232323 ==================================== =================== Registers information ==================== R0 : 00000000 R1 : 08003fe8 R2 : 08003fe8 R3 : 80808000 R12: 01010101 LR : 08003f37 PC : 08003f36 PSR: 61000000 ============================================================== Usage fault is caused by Indicates a divide by zero has taken place (can be set only if DIV_0_TRP is set) Show more call stack info by run: addr2line -e rtthread.axf -a -f 08003f36 08003f36 08002f40 08006436 08004ba4

测试结果,如上。

使用powershell输入指令,将目录切换到工程输出的可执行文件下。

ffe03696a6ba7547f86bd3ccff54f297.png

再执行addr2line指令

addr2line -e rt-thread.axf -a -f 08003f36 08003f36 08002f40 08006436 08004ba4

87d54c338182b6d9e1085c08912cbb94.png

根据提示可查看相应的代码即可。

欢迎关注个人公众号:嵌入式学习与实践

参考:

  1. https://www.gd32mcu.com/data/documents/userManual/AN028_CN_Rev1.0.pdf
  2. https://www.gd32mcu.com/data/documents/userManual/AN020_CN_Rev1.0.pdf
  3. https://gitee.com/RT-Thread-Mirror/CmBacktrace
  4. https://www.bilibili.com/video/BV1LB4y1Q78a/?vd_source=f58225e38b5a8bc42ab3351918ec20e5
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/50615
推荐阅读
相关标签
  

闽ICP备14008679号