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

这篇具有很好参考价值的文章主要介绍了单片机Hard fault 产生原因和错误跟踪的方法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、单片机 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 ,针对不同的平台和场景,用户需要自自行手动配置,常用配置如下:

单片机进hardfault原因,单片机,嵌入式硬件

注意:以上部分配置的内容可以在 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工具添加软件包,如下图

单片机进hardfault原因,单片机,嵌入式硬件

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

单片机进hardfault原因,单片机,嵌入式硬件

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

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

cmb_test DIVBYZERO
[2023-06-20 09:41:46.648]
TX:cmb_test DIVBYZERO


[2023-06-20 09:41:47.852]
RX:cmb_test DIVBYZERO
thread   pri  status      sp     stack size max used left tick  error
-------- ---  ------- ---------- ----------  ------  ---------- ---
tshell    20  running 0x00000098 0x00001000    04%   0x00000007 000
tidle0    31  ready   0x00000048 0x00000400    10%   0x00000009 000
main      10  suspend 0x00000084 0x00000800    12%   0x00000013 000
 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输入指令,将目录切换到工程输出的可执行文件下。

单片机进hardfault原因,单片机,嵌入式硬件

再执行addr2line指令

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

单片机进hardfault原因,单片机,嵌入式硬件

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

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

参考:文章来源地址https://www.toymoban.com/news/detail-769927.html

https://www.gd32mcu.com/data/documents/userManual/AN028_CN_Rev1.0.pdf


https://www.gd32mcu.com/data/documents/userManual/AN020_CN_Rev1.0.pdf


https://gitee.com/RT-Thread-Mirror/CmBacktrace


https://www.bilibili.com/video/BV1LB4y1Q78a/?vd_source=f58225e38b5a8bc42ab3351918ec20e5

到了这里,关于单片机Hard fault 产生原因和错误跟踪的方法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 烧坏两块单片机,不知道原因?

    烧坏两块单片机,不知道原因?

    没有看你的原理图,以下是造成烧毁芯片的几个环节: 1. 最大的可能性是你的单片机电机控制输出与电机驱动电路没有隔离。 我的经验,使用STM32控制电机,无论是直流电机脉宽调制,还是步进电机控制,控制电路与电机驱动电路一定要隔离,使用光耦。如果你觉得一般光耦

    2024年04月25日
    浏览(9)
  • STM32 单片机重启(查看上次重启原因)

            STM32启动后可以识别本次启动是对应哪一种复位源,从而可以根据复位源的状态,做一些特殊处理。 HAL库的复位源识别         以下代码,识别是那种方式进行复位的,只需要将自己在那种方式复位运行的程序添加进去即刻,在这里面尽量进行一些事件更改,

    2024年01月18日
    浏览(8)
  • 单片机卡死的八大原因和解决方法

    在微控制器上,程序卡住(即停止执行)可能有多种原因。下面我将列举一些常见的原因,并提供一些可能导致程序卡住的示例情况。请注意,这里只是一些示例,并不能穷尽所有可能的情况。 1. 死循环(Infinite Loop):在程序中存在无法跳出的循环结构,导致程序无法继续

    2024年02月15日
    浏览(42)
  • 单片机设计_自动追光系统、光源跟踪系统(AT89C51 光敏电阻 步进电机)

    单片机设计_自动追光系统、光源跟踪系统(AT89C51 光敏电阻 步进电机)

    想要更多项目私wo!!!          51 单片机双轴自动追光系统主要由 STC89C52RC + 5516 光敏电阻 + ADC0832 + ULN2803 + 步进电机 + LCD1602 显示屏组成。         1.通过子电路板的上、下、左、右四个光敏电阻来感受四个方向的光强,自 动寻找光强最强的方向。四个光敏电阻的分压电

    2024年02月11日
    浏览(8)
  • 为什么单片机可以直接烧录程序的原因是什么?

    为什么单片机可以直接烧录程序的原因是什么?

    单片机(Microcontroller)可以直接烧录程序的原因主要有以下几点: 集成性:单片机是一种高度集成的芯片,内部包含了处理器核心(CPU)、存储器(如闪存、EEPROM、RAM等)、输入/输出接口(如GPIO、UART、SPI、I2C等)以及时钟电路等功能模块。这种高度集成的设计使得单片机能

    2024年02月16日
    浏览(45)
  • 电力电子课设|数控产生PWM波|使用51单片机输出占空比可调PWM波(按钮控制、数码管显示)速成教程

    电力电子课设|数控产生PWM波|使用51单片机输出占空比可调PWM波(按钮控制、数码管显示)速成教程

    我们学校电气专业开始做电力电子的课设了,小组选了一项制作硬件电路的任务,里面有要求采用 数控方式 实现DC-DC电压变换的输出电压调节,数控在电路中的体现就是用单片机输出可调占空比的PWM波作用于IRF520模块,实现电压的变化,作用于SG3525芯片的2引脚。考虑到可能

    2024年02月16日
    浏览(17)
  • 基于STC系列单片机实现定时器0扫描数码管显示定时器/计数器1作为计数器1产生频率的功能
  • 单片机LED指示灯限流电阻一般470Ω以上尽量大于1KΩ的原因分析

    我也来最简单解释一下: 1.先了解一下LED最基本特性/指标:        点亮电压 (一般红色约1.5V蓝绿2.5V白2.6-2.8V就可点亮,点亮以后电压越高越亮,注意一般都是高过点亮电压0.5V以上就要烧毁了!)...LED亮度场合一般就二种:指示灯用/照明用。 2.如何调整合适亮度?        就是怎么控

    2024年02月12日
    浏览(9)
  • 宽带连接错误代码678介绍、产生原因和解决方法

    宽带错误代码678怎么回事? 分析一下宽带错误代码678是什么原因. 简介 宽带ADSL拨号上网用户经常会碰到“错误678”的故障提示:一直上网正常,但某一天突然上不了了,拨号连接时出现“错误678”等提示,一般用户对这种故障是束手无策,有的还怀疑是不是密码被盗了? 原因

    2024年02月07日
    浏览(11)
  • 嵌入式开发中断全解(2)Hard Fault的诊断

    嵌入式开发中断全解(2)Hard Fault的诊断

    承接上次的文章,讲几个大家应该都看过下面的几个 中断 ,有的是在启动文件中或者是.c文件中。 注意:上述是ST公司的Stm32芯片 这里的GD32芯片是国产芯片,和stm32类似的操作,代码可以兼容。 1、void NMI_Handler(void) 不可屏蔽中断 。主要是两方面触发,一个是外设触发,一个

    2024年02月05日
    浏览(9)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包