在开发过程有时候会遇到芯片跑到Hardfault中的情况。
针对HardFault问题的定位,一般是在仿真模式下在HardFault_Handler中打断点,等芯片进入hardfault后,通过追踪寄存器和地址来定位出现hardfault前芯片执行到哪里了。
这种方式比较麻烦,并且不够直观。偶然了解到有一个开源库CmBacktrace可以对Hardfault自动诊断。
开源库地址:https://github.com/armink/CmBacktrace
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 编译器;
开源链接中对移植使用已经有了比较详细的说明,也给出了stm32的几个演示例程,下面就试试将CmBacktrace 移植到APM32的库中测试下是否能兼容使用。
测试使用APM32E103的SDK 《APM32E10x_SDK_V1.2》 , 因为CmBacktrace 需要使用串口的printf或者jlink的SEGGER_RTT_printf来打印诊断数据。
使用直接在SDk中的串口例程基础上进行移植。
首先将CmBacktrace 的文件夹复制到工程目录下,并添加到Keil的工程中。
然后在工程配置中勾选C99 Mode ,并且添加CmBacktrace 的路径。
然后直接编译的话话还是会报很多错,软件还要几个步骤要调整。
1、将apm32e10x_int.c中的HardFault_Handler屏蔽掉。
2、cmb_cfg.h中根据适配的打印方式、裸机还是操作系统、芯片内核、打印语言进行选择
3、在main中增加CmBacktrace 的初始化,增加个测试函数,还有报错就对应补充定义,然后就可以开始测试。
然后接上串口工具就可以看到打印出hardfault的诊断信息。
根据最下面的addr2line -e USART_Interrupt.axf -a -f 08001566 080015ba
就可以使用文件夹里的分析工具来判断或者就通过仿真的地址查找来找到相关的代码。