栈回溯之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 编译器;



环境

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.mzph.cn/news/137599.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Matplotlib数据可视化综合应用Matplotlib图形配置在线闯关_头歌实践教学平台

Matplotlib数据可视化综合应用图形配置 第1关 配置颜色条第2关 设置注释第3关 自定义坐标刻度第4关 配置文件与样式表 第1关 配置颜色条 任务描述 本关任务&#xff1a;使用colorbar绘制一个热成像图。 编程要求 在右侧编辑器Begin-End处补充代码&#xff0c;根据输入数据绘制…

P1529 [USACO2.4] 回家 Bessie Come Home 题解

文章目录 题目描述输入格式输出格式样例样例输入样例输出 提示完整代码 题目描述 现在是晚餐时间&#xff0c;而母牛们在外面分散的牧场中。 Farmer John 按响了电铃&#xff0c;所以她们开始向谷仓走去。 你的工作是要指出哪只母牛会最先到达谷仓&#xff08;在给出的测试数…

【数据结构】单链表之--无头单向非循环链表

前言&#xff1a;前面我们学习了动态顺序表并且模拟了它的实现&#xff0c;今天我们来进一步学习&#xff0c;来学习单链表&#xff01;一起加油各位&#xff0c;后面的路只会越来越难走需要我们一步一个脚印&#xff01; &#x1f496; 博主CSDN主页:卫卫卫的个人主页 &#x…

Vue中模板语法与el 和 data 的两种写法

模板语法 标签语法 //在.html文件中 <body><h3>{{name}}</h3> </body> <script>new Vue({el:#root,data:{name:jack,url:网页地址}}) </script> 指令语法 标签语法和指令语法的简单区分&#xff0c;就是指令语法用v-on,v-bind,v-model指…

ubuntu 16.04.5 安装 vivado 2019.1 完整编译AD9361的环境

一、前期安装 1、安装ncurses库&#xff08;已经包含了&#xff0c;其他的os需要安装&#xff09; sudo apt install libncurses5二、安装 sudo ./xsetup使用lic进行激活。 三、安装后 输入指令 sudo gedit ~/.bashrc 末尾添加 source /opt/Xilinx/Vivado/2019.1/setti…

python 在 __init__.py文件中修改某变量的值(非手动)

python的__init__.py文件在Python包被导入或使用时开始执行。 当一个包被导入时&#xff0c;Python会自动执行该包下的__init__.py文件。这意味着__init__.py文件中的代码会在导入包时立即执行。 如果我们的应用程序需要在引入包的时候&#xff0c;对__init__.py文件的变量设…

引用(类名后加符号)和指针的区别

它们的区别&#xff1a; ①从现象上看&#xff0c; 指针在运行时可以改变其所指向的值&#xff0c; 而引用一旦和某个对象绑定后就不再改变。 这句话可以理解为&#xff1a; 指针可以被重新赋值以指向另一个不同的对象。 但是引用则总是指向在初始化时被指定的对象&#x…

无人机航拍技术基础入门,无人机拍摄的方法与技巧

一、教程描述 买了无人机&#xff0c;可是我不敢飞怎么办&#xff1f;禁飞区越来越多&#xff0c;到底哪儿才能飞&#xff1f;我的无人机跟你一样&#xff0c;为什么我拍不出大片&#xff1f;厂家的说明书看不进去&#xff0c;有没有一套无人机的课程&#xff0c;可以快速上手…

ruoyi前后端分离版本开发框架解读---让你快速入门

后端结构 com.ruoyi ├── common // 工具类 │ └── annotation // 自定义注解 │ └── config // 全局配置 │ └── constant // 通用常量 │ └── core …

sqli-labs-1

文章目录 Less-01Less-02Less-03Less-04 Less-01 1.输入不同的id值&#xff0c;可以获取不同的用户信息&#xff1a; 2.在sql后拼接’or11–&#xff0c;并没有获取到所有用户的信息&#xff0c;猜测可能用了limit语句 3.构造错误的sql语句&#xff0c;果然有limit报错: …

《网络协议》03. 传输层(TCP UDP)

title: 《网络协议》03. 传输层&#xff08;TCP & UDP&#xff09; date: 2022-09-04 22:37:11 updated: 2023-11-08 15:58:52 categories: 学习记录&#xff1a;网络协议 excerpt: 传输层、UDP、TCP&#xff08;可靠传输&#xff0c;流量控制&#xff0c;拥塞控制&#xf…

Go采集代理框架

代理服务器在网络爬虫、数据采集和反爬虫等场景中起着重要的作用。通过使用代理服务器&#xff0c;我们可以隐藏客户端的真实IP地址并提高访问速度。Go语言作为一种强大且可靠的编程语言&#xff0c;提供了很多库和工具来实现代理采集框架。在本文中&#xff0c;我们将介绍如何…

汽车标定技术(八)--MPC57xx是如何支持标定的页切换

目录 1.页切换的概念 1.1 标定常量的理解 1.2 页切换 2.MPC57xx的Overlay模块 3.小结 1.页切换的概念 在汽车标定测量中&#xff0c;有一个概念我想很多人都听过&#xff0c;但是实际上在项目里没有用到过&#xff0c;那就是今天要讲的页切换概念。在讲页切换的时候&#…

手机怎么打包?三个方法随心选!

有的时候&#xff0c;电脑不在身边&#xff0c;只有随身携带的手机&#xff0c;这个时候又急需把文件打包发送给同事或者同学&#xff0c;如何利用手机操作呢&#xff1f;下面介绍了具体的操作步骤。 一、通过手机文件管理自带压缩功能打包 1、如果是iOS系统&#xff0c;就在手…

angular+ionic+npm项目运行

angularionicnpm项目运行 错误记录&#xff08;1&#xff09;Downloading binary from https://github.com/sass/node-sass/releases/download/v4.14.1/win32-x64-72_binding.node&#xff08;2&#xff09;The npm warning "A requires a peer of B but none is installe…

【PHP函数封装】分分钟帮你实现数据脱敏处理, 支持手机号码、邮箱、身份证号 中文字符串!

&#x1f680; 个人主页 极客小俊 ✍&#x1f3fb; 作者简介&#xff1a;web开发者、设计师、技术分享博主 &#x1f40b; 希望大家多多支持一下, 我们一起进步&#xff01;&#x1f604; &#x1f3c5; 如果文章对你有帮助的话&#xff0c;欢迎评论 &#x1f4ac;点赞&#x1…

MIPSsim模拟器 使用说明

&#xff08;一&#xff09; 启动模拟器 双击MIPSsim.exe&#xff0c;即可启动该模拟器。模拟器启动时&#xff0c;自动将自己初始化为默认状态。所设置的默认值为&#xff1a; u所有通用寄存器和浮点寄存器为全0&#xff1b; u内存清零&#xff1b; u流水寄存器为全0&#xff…

【ElasticSearch系列-06】Es集群架构的搭建以及集群的核心概念

ElasticSearch系列整体栏目 内容链接地址【一】ElasticSearch下载和安装https://zhenghuisheng.blog.csdn.net/article/details/129260827【二】ElasticSearch概念和基本操作https://blog.csdn.net/zhenghuishengq/article/details/134121631【三】ElasticSearch的高级查询Quer…

P1547 [USACO05MAR] Out of Hay S 题解

文章目录 题目描述输入格式输出格式样例样例输入样例输出 完整代码 题目描述 Bessie 计划调查 N N N&#xff08; 2 ≤ N ≤ 2 000 2 \leq N \leq 2\,000 2≤N≤2000&#xff09;个农场的干草情况&#xff0c;它从 1 1 1 号农场出发。农场之间总共有 M M M&#xff08; 1 ≤…

深入理解ClickHouse跳数索引

一、跳数索引​ 影响ClickHouse查询性能的因素很多。在大多数场景中&#xff0c;关键因素是ClickHouse在计算查询WHERE子句条件时是否可以使用主键。因此&#xff0c;选择适用于最常见查询模式的主键对于表的设计至关重要。 然而&#xff0c;无论如何仔细地调优主键&#xff…