本帖最后由 kai迪皮 于 2023-6-5 10:28 编辑  
 
#申请原创#@21小跑堂  
 
1 前言 
 
最近在使用APM32F407调试程序的过程中发现芯片进入了硬件错误中断,网上有很多资料用于定位异常的点,但是我们发现有一个开源工具能很快定位我们的异常地址及异常问题详情。 
 
这篇文章就跟大家分享一下这个小工具CmBacktrace。 
 
2 硬件错误中断 
 
在开始使用CmBacktrace之前我们先了解一下硬件错误中断:HardFault_Handler。 
 
在程序的运行过程中,我们会对数据读写,可能存在越界等异常问题,从而导致我们的程序进入硬件错误中断。或者我们使用一些高级语言(C语言)进行运算的过程中,没有考虑完全,从而导致的一些异常,使得程序进入硬件错误中断。 
 
在Arm的文档:AN209[Abstract: (keil.com)](https://www.keil.com/appnotes/files/apnt209.pdf)中说明了进入HardFault的一些异常。 
 
 
 
 
Arm的设计过程中用不同的bit指示遇到的错误状态,我们从这些状态中也可以清晰知道遇到了那些问题。CmBacktrace便是基于这个原理来判断异常。 
 
3 CmBacktrace获取 
 
CmBacktrace获取可以直接在其仓库中直接下载:https://github.com/armink/CmBacktrace,我们这里使用的是其“cm_backtrace”文件夹中的内容,我们后续需要将其复制至我们的工程中。 
 
 
 
 
4 移植CmBacktrace 
 
获取到cm_backtrace的源码后,我们需要准备相应的开发板已经一个使用printf输出信息的demo。 
 
我这里是APM32F407IG MINI板,使用他们官方的demo:APM32F4xx_SDK_v1.3\Examples\SysTick\SysTick_TimeBase 
 
1. 先将我们下载好的CmBacktrace源码放在APM32F4xx_SDK_v1.3\Middlewares\CmBacktrace文件夹中 
 
2. 打开我们的APM32F4xx_SDK_v1.3\Examples\SysTick\SysTick_TimeBase工程,添加CmBacktrace源文件及头文件路径。 
 
   源文件添加: 
 
   2. Middlewares\CmBacktrace\cm_backtrace\fault_handler\keil\cmb_fault.S 
   3. Middlewares\CmBacktrace\cm_backtrace\cm_backtrace.c 
 
   头文件路径: 
 
   1. ..\..\..\..\..\Middlewares\CmBacktrace\cm_backtrace 
   2. ..\..\..\..\..\Middlewares\CmBacktrace\cm_backtrace\Languages\zh-CN 
   3. ..\..\..\..\..\Middlewares\CmBacktrace\cm_backtrace\Languages\en-US 
 
3. 在main.c中添加CmBacktrace文件包含及相关宏定义,main函数中初始化 
 
   1. #include "cm_backtrace.h" 
   2. #define HARDWARE_VERSION               "V1.0.0" 
      #define SOFTWARE_VERSION               "V0.1.0" 
   3. cm_backtrace_init("CmBacktrace", HARDWARE_VERSION, SOFTWARE_VERSION); 
 
4. 注释apm32f4xx_int.c文件中的 HardFault_Handler函数,因为此函数会被CmBacktrace接管(在cmb_fault.S)。 
 
- //void HardFault_Handler(void)
 
  
 
5. 修改cmb_cfg.h配置信息如下: 
 
-  /* print line, must config by user */
 
 -    #define cmb_println(...)               printf(__VA_ARGS__);printf("\r\n") /* e.g., printf(__VA_ARGS__);printf("\r\n")  or  SEGGER_RTT_printf(0, __VA_ARGS__);SEGGER_RTT_WriteString(0, "\r\n")  */
 
 -    /* enable bare metal(no OS) platform */
 
 -    #define CMB_USING_BARE_METAL_PLATFORM
 
 -    /* enable OS platform */
 
 -    /* #define CMB_USING_OS_PLATFORM */
 
 -    /* OS platform type, must config when CMB_USING_OS_PLATFORM is enable */
 
 -    /* #define CMB_OS_PLATFORM_TYPE           CMB_OS_PLATFORM_RTT or CMB_OS_PLATFORM_UCOSII or CMB_OS_PLATFORM_UCOSIII or CMB_OS_PLATFORM_FREERTOS or CMB_OS_PLATFORM_RTX5 */
 
 -    /* cpu platform type, must config by user */
 
 -    #define CMB_CPU_PLATFORM_TYPE          CMB_CPU_ARM_CORTEX_M4 /* CMB_CPU_ARM_CORTEX_M0 or CMB_CPU_ARM_CORTEX_M3 or CMB_CPU_ARM_CORTEX_M4 or CMB_CPU_ARM_CORTEX_M7 */
 
 -    /* enable dump stack information */
 
 -    /* #define CMB_USING_DUMP_STACK_INFO */
 
 -    /* language of print information */
 
 -    #define CMB_PRINT_LANGUAGE             CMB_PRINT_LANGUAGE_CHINESE /*CMB_PRINT_LANGUAGE_ENGLISH(default) or CMB_PRINT_LANGUAGE_CHINESE */
 
  
 
   完成以上操作后编译代码,看看有无错误。 
 
5 设置并查找错误 
 
我们前面已经移植完毕CmBacktrace,现在我们尝试一下设置出HardFault看看我们的控制台上会不会输出错误信息。 
 
这里我们设置有一个数据访问异常。 
 
1. 在main函数中定义 
 
- /* 设置硬件错误异常 */
 
 -     volatile uint32_t *p;
 
 -     uint32_t n;
 
 -     p = (uint32_t *)0x11111111;
 
 -     n = *p;
 
 -     (void)n;
 
  
 
2. 然后我们编译下载,使用串口线连接串口1 (PA9/PA10)至PC,使用串口助手查看运行后的结果。 
 
 
 
   串口助手会显示我们错误的地方。 
 
3. 同时进阶的addr2line指令**,感兴趣的小伙伴可以自行了解。 
 
以上便是本次APM32F4平台移植CmBacktrace定位的全部分享,使用好该工具会使得我们更好的定位硬件异常发生的错误现场(这里是demo
 
APM32F4xx_SDK_v1.3_CmBacktrace.zip
(7.85 MB, 下载次数: 16)
,供大家参考)。 
 
 
 
  |