栈回溯之CmBacktrace

news/2025/1/3 4:23:59/

简介

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 编译器;



环境

IDEKeil 5.30(Windows 11)
MCUSTM32H750(Cortex M7),Cortex M3/M4 MCU都可以
RTOSRT-Thread
源码https://github.com/armink/CmBacktrace



移植源码

  1. 下载源码 git clone https://github.com/armink/CmBacktrace.git
  2. cm_backtrace文件夹复制至工程,并将根目录所有源文件添加至工程
  3. cm_backtrace/fault_handler/keil下的cmb_fault.s 汇编文件添加至工程,添加后需要把项目原有的 HardFault_Handler 注释掉
  4. cm_backtrace文件夹添加至头文件路径



配置说明

配置文件名: cmb_cfg.h ,针对不同的平台和场景,用户需要自自行手动配置,常用配置如下:

配置名称功能备注
cmb_println(…)错误及诊断信息输出必须配置
CMB_USING_BARE_METAL_PLATFORM是否使用在裸机平台使用则定义该宏
CMB_USING_OS_PLATFORM是否使用在操作系统平台操作系统与裸机必须二选一
CMB_OS_PLATFORM_TYPE操作系统平台RTT/UCOSII/UCOSIII/FREERTOS
CMB_CPU_PLATFORM_TYPECPU平台M0/M3/M4/M7
CMB_USING_DUMP_STACK_INFO是否使用 Dump 堆栈的功能使用则定义该宏
CMB_PRINT_LANGUAGE输出信息时的语言CHINESE/ENGLISH

根据环境,我这里的cmb_cfg.h内容如下:

#ifndef _CMB_CFG_H_
#define _CMB_CFG_H_#include <stdio.h>/* print line, must config by user */
#define cmb_println(...)    do{printf(__VA_ARGS__);printf("\r\n");}while (0)/* 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_M7      /* CMB_CPU_ARM_CORTEX_M0 or CMB_CPU_ARM_CORTEX_M3 or CMB_CPU_ARM_CORTEX_M4 or CMB_CPU_ARM_CORTEX_M7 or CMB_CPU_ARM_CORTEX_M33 */
/* enable dump stack information */
#define CMB_USING_DUMP_STACK_INFO
/* language of print information */
#define CMB_PRINT_LANGUAGE     CMB_PRINT_LANGUAGE_CHINESE_UTF8        /*CMB_PRINT_LANGUAGE_ENGLISH(default) or CMB_PRINT_LANGUAGE_CHINESE or CMB_PRINT_LANGUAGE_CHINESE_UTF8 */
#endif /* _CMB_CFG_H_ */



实例测试

初始化

在工程最开始调用初始化函数,三个参数依次为固件名称,硬件版本,软件版本

固件名称最好和Options(魔术棒)> Output > Name of Executable一致,方便后续使用addr2line 工具

cm_backtrace_init("STM32H750VB-RTT", "V1.0.0", "V0.0.1");



测试源码

调用关系main() > test2() > test1() > fault_test()

void fault_test() 
{volatile int *SCB1 = (volatile int *) 0xFEEEEEEE;*SCB1 |= 0x10;printf("SCB1: %d\r\n", *SCB1);
}void test1()
{printf("test 1 start\r\n");fault_test();printf("test 1 end\r\n");
}void test2()
{printf("test 2 start\r\n");test1();printf("test 2 end\r\n");
}int main(void)
{//......test2();//......
}



日志

由日志可知设备挂掉的原因为非对齐访问

固件名称:STM32H750VB-RTT,硬件版本号:V1.0.0,软件版本号:V0.0.1
在线程(main)中发生错误异常
=========== 线程堆栈信息 ===========addr: 20001040    data: deadbeefaddr: 20001044    data: 2000104caddr: 20001048    data: 20001054addr: 2000104c    data: 0800a9e3addr: 20001050    data: 200010ccaddr: 20001054    data: 08008e9faddr: 20001058    data: 23232323addr: 2000105c    data: 23232323addr: 20001060    data: 23232323addr: 20001064    data: 23232323addr: 20001068    data: 23232323addr: 2000106c    data: 23232323addr: 20001070    data: 23232323addr: 20001074    data: 23232323addr: 20001078    data: 23232323addr: 2000107c    data: 23232323addr: 20001080    data: 23232323addr: 20001084    data: 23232323addr: 20001088    data: 23232323addr: 2000108c    data: 00000000addr: 20001090    data: deadbeefaddr: 20001094    data: deadbeefaddr: 20001098    data: deadbeefaddr: 2000109c    data: deadbeefaddr: 200010a0    data: deadbeefaddr: 200010a4    data: deadbeefaddr: 200010a8    data: deadbeefaddr: 200010ac    data: deadbeefaddr: 200010b0    data: 200010c4addr: 200010b4    data: 08009247addr: 200010b8    data: deadbeefaddr: 200010bc    data: deadbeefaddr: 200010c0    data: 200010ccaddr: 200010c4    data: 08008f81addr: 200010c8    data: deadbeefaddr: 200010cc    data: 08008155
====================================
========================= 寄存器信息 =========================R0 : feeeeeee  R1 : f0000000  R2 : 00000000  R3 : 08008a0aR12: 0000c000  LR : 0800a9a7  PC : 08008a76  PSR: 61000000
==============================================================
发生用法错误,原因:企图执行非对齐访问
查看更多函数调用栈信息,请运行:addr2line -e STM32H750VB-RTT.axf -afpiC 08008a76 0800a9a6 0800a9e2 08008e9e 08009246 08008f80



调用addr2line

在生成编译结果的目录右键打开终端,运行日志提示的addr2line的命令

没有addr2line的可以在tools文件夹获取,因为我装有MinGW (Minimalist GNU for Windows),所以直接运行:

结果可以很清晰的看到函数调用过程和出错的地方

addr2line -e STM32H750VB-RTT.axf -afpiC 08008a82 0800a9b2 0800a9ee 08008eaa 08009252 08008f8c0x08008a76: fault_test at D:\RT-ThreadStudio\workspace\STM32H750VB-RTT\MDK-ARM/../Core/Src/main.c:21
0x0800a9a6: test1 at D:\RT-ThreadStudio\workspace\STM32H750VB-RTT\MDK-ARM/../Core/Src/main.c:30
0x0800a9e2: test2 at D:\RT-ThreadStudio\workspace\STM32H750VB-RTT\MDK-ARM/../Core/Src/main.c:37
0x08008e9e: main at D:\RT-ThreadStudio\workspace\STM32H750VB-RTT\MDK-ARM/../Core/Src/main.c:83
0x08009246: rt_components_init at D:\RT-ThreadStudio\workspace\STM32H750VB-RTT\MDK-ARM/..\RT-Thread\/src\components.c:127
0x08008f80: main_thread_entry at D:\RT-ThreadStudio\workspace\STM32H750VB-RTT\MDK-ARM/..\RT-Thread\/src\components.c:195

http://www.ppmy.cn/news/1205606.html

相关文章

开发FPS枪战游戏的意义

开发FPS枪战游戏的意义有以下几点&#xff1a; 娱乐性&#xff1a;FPS游戏因其紧张刺激的战斗节奏和独特的玩法&#xff0c;一直受到玩家的喜爱。通过开发这类游戏&#xff0c;可以为玩家提供一种新的、有趣的娱乐方式。锻炼反应能力&#xff1a;FPS游戏需要玩家快速做出反应&…

将MSSQL字段类型由text改为ntext

-- 修改数据字段类型DECLARE DATATYPE nvarchar(128) SET DATATYPE (SELECT DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME your-table-name AND COLUMN_NAME your-column-name) IF DATATYPE text BEGIN-- 注意 text和ntext互转要先转为中间类型ALTER TABL…

Python高级语法----Python的元编程

文章目录 装饰器元类反射使用 `__getattr__`, `__setattr__`, 和 `__delattr__`元编程是一种编程技术,它允许程序员在运行时修改、增加或操作程序的结构。在Python中,元编程通常涉及到对类和函数的动态创建和修改,这是通过使用诸如装饰器、元类和反射等高级功能来实现的。 …

RV1126双摄调试记录

RV1126双摄调试记录 IMX577驱动dts修改:排错分析整理思路继续分析结论解决解决方案一解决方案二 硬件方案: 双12M IMX577 分辨率 4048x3040 bayer 大约18MB(视频处理中会多次以该大小分配内存块) IMX577驱动 imx577 sensor 驱动可从rk3588中移植修改来用。 主要修改以下3点: …

Python 中 Selenium 的 send_keys() 函数

我们将介绍 Selenium Python 中的 send_keys() 函数并演示其用法。 任何应用程序在进入市场之前都需要经过一些测试。 应用程序应首先满足与其名称相关的所有要求。 我们应该全面测试应用程序&#xff0c;因为没有人能够预测给予应用程序的确切输入。 Python Selenium 可以帮…

STM32MPU6050角度的读取(STM32驱动MPU6050)

注&#xff1a;文末附STM32驱动MPU6050代码工程链接&#xff0c;需要的读者请自取。 一、MPU6050介绍 MPU6050是一款集成了三轴陀螺仪和三轴加速度计的传感器芯片&#xff0c;由英国飞利浦半导体&#xff08;现为恩智浦半导体&#xff09;公司生产。它通过电子接口&#xff08…

Hikyuu 1.3.0 发布,高性能量化交易研究框架

Hikyuu 是一款基于 C/Python 的高性能开源量化交易研究框架&#xff0c;用于快速策略分析及回测。与其他量化平台或回测软件相比&#xff0c;具备&#xff1a; 超快的回测速度&#xff1b;对完整的系统交易理念进行抽象&#xff0c;并分解为不同的组件&#xff0c;通过重用不同…

7 Go的指针

概述 在上一节的内容中&#xff0c;我们介绍了Go的切片&#xff0c;包括&#xff1a;声明切片、初始化切片、切片的切割、切片的添加、切片的删除、切片的复制、切片的遍历、多维切片等。在本节中&#xff0c;我们将介绍Go的指针。Go语言中的指针是一种特殊的数据类型&#xff…