[应用相关] 快速追踪 和定位HardFaultHardler

[复制链接]
477|0
MCU学习帮 发表于 2025-11-14 11:02 | 显示全部楼层 |阅读模式
前言
这篇应用笔记描述了怎么使用CmBacktrace库,快速追踪和定位产生HardFault原因的方法。
注:本应用笔记对应的代码是基于雅特力提供V2.x.x 板级支持包(BSP)而开发,对于其他版本BSP,需要注意使用上的区别。
支持型号列表:AT32全系列

分享此文档的目的是仅供有需要的伙伴们参考,如需源文档或者更详细的操作信息及步骤,图示(关于如何快速追踪和定位HardFaultHardler),请访问雅特力官网网站获取详细资料: https://www.arterytek.com/cn/support/index.jsp?index=1
1                 概述
在使用ARM Cortex-M 系列 MCU时(如AT32 MCU),有时会出现程序运行异常。当通过编译器在debug模式查原因时,会发现程序跑到 HardFault_Handler函数中,产生 HardFault,即硬件错误。
本文档主要介绍一种基于CmBacktrace库,快速追踪和定位产生HardFault原因的方法。
2                  HardFault产生原因
常见产生HardFault产生的原因大概有如下几类:
n  数组越界操作;

n  内存溢出,访问越界;
n  堆栈溢出,程序跑飞;
n  中断处理错误。
数组越界
程序中使用了静态数组,而在动态传参时数组赋值溢出。或者动态分配内存太小,导致程序异常。
内存溢出
重点检查RAM区域,程序编译后执行的RAM数据量大小为多少是否可能越界。一般不要设置到极致的情况,程序中的一些动态数组传参时会导致异常。
堆栈溢出
这在使用操作系统的代码中尤其容易发生,在操作系统中,任务的变量均分配放置在任务所申请的堆栈空间中。
例如FreeRTOS中调用xTaskCreate来创建任务,该函数以参数usStackDepth指定任务堆栈的大小,如果指定的堆栈太小,则会堆栈申请不足,进入HardFault。
中断处理异常
程序中开启了某些中断,例如USART,TIMER,RTC等。

但在程序执行中,满足中断条件,但并未能查找到该部分对应的中断服务函数,则可能会出现该异常。
3                  HardFault分析方法
常见的分析方法是:发生异常之后可首先查看LR寄存器中的值,确定当前使用堆栈为MSP或PSP,然后找到相应堆栈的指针,并在内存中查看相应堆栈里的内容。由于异常发生时,内核将R0~R3、R12Returnaddress、PSR、LR寄存器依次入栈,其中Returnaddress即为发生异常前PC将要执行的下一条指令地址。
但以上方法要求对ARM内核比较熟悉,且操作较为繁琐。
以下重点介绍采用开源库CmBacktrace作为快速分析的方法。
3.1           基于CmBacktrace库分析方法
CmBacktrace(CortexMicrocontroller Backtrace)是一款针对 ARM Cortex-M 系列MCU 的错误代码自动追踪、定位,错误原因自动分析的开源库。主要特性如下:
n  支持的错误包括:
1)     断言(Assert)
2)     故障(HardFault, Memory Management Fault, Bus Fault, Usage Fault, Debug Fault)
n  故障原因自动诊断 :可在故障发生时,自动分析出故障的原因,定位发生故障的代码位置,而无需再手动分析繁杂的故障寄存器;
n  适配Cortex-M0/M3/M4/M7 MCU;
n  支持 IAR、KEIL、GCC编译器;
n  支持FreeRTOS、UCOSII、UCOSIII、RT-Thread等OS;
3.2           基于MDKCmBacktrace库使用流程
基于MDK的移植方法按如下步骤进行:

步骤一 添加cm_backtrace库文件到MDK
把cm_backtrace文件夹复制到我们的工程目录下,并添加至keil工程中。

步骤二 添加头文件、勾选C99模式
步骤三 编译和调试

首先,cmb_cfg.h文件按以下提示配置修改。
这时候编译有一个错误,这是因为cmb_fault.c与at32f4xx_int.c中的HardFault_Handler函数重复定义:
需要把at32f4xx_int.c中的HardFault_Handler函数屏蔽掉。

步骤四 测试与查看
这时候就可以编译通过了。下面测试这个库的功能。

然后在主函数中调用cm_backtrace_init();来初始化cm_backtrace,并调用该测试函数:
下载运行程序,PC端接收串口信息:

可以看到,列出了出错原因(非对齐)和一条命令。运行这个命令需要用到addr2line.exe工具,该工具在tools文件夹中:

有32bit和64bit两个版本,根据环境选择,并拷贝到keil工程目录下的.axf文件所在的文件夹中,如demo中所附工程,则拷贝到如下目录:AN0028_SourceCode_V2.0.0\utilities\AN0028_demo\non_os\mdk_v5\objects

进入到cmd窗口,转到上述文件夹位置,运行串口助手中的那条命令:
addr2line -e CmBacktrace(此处要依据用户的工程名修改).axf -a -f 080019c6 08001ae9
如demo中工程名为printf,命令则应修改为addr2line-e printf.axf -a -f 080019c6 08001ae9

可以看到addr2line.exe工具定位出了错误相关的代码行号,查看对应行的代码:
可见,对应的行号正是出错的地方,使用这个CmBacktrace 库能帮助用户有效、快速地定位到HardFault之类的错误。

3.3            案例展示
案例一 OS非对齐访问错误
工程位置:AN0028_SourceCode_V2.0.0\utilities\AN0028_demo\non_os
测试内容:在裸机上除零错误
案例二 FreeRTOS上非对齐访问错误
工程位置:AN0028_SourceCode_V2.0.0\utilities\AN0028_demo\os\freertos
测试内容:在FreeROTOS上除零错误,需注意tasks.c中有注释/*<Support For CmBacktrace >*/的三处为针对CmBacktrace做出的修改
案例三USOCⅢ上非对齐访问错误
工程位置:AN0028_SourceCode_V2.0.0\utilities\AN0028_demo\os\ucosiii
测试内容:在UCOSⅢ上非对齐访问错误,需注意os_cfg.h中#defineOS_CFG_DBG_EN 为 1u


您需要登录后才可以回帖 登录 | 注册

本版积分规则

17

主题

17

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部