STM32 FreeRTOS断言调试故障代码Cmbacktrace移植
1、背景概述
在freertos系统下编程,自己的某些疏忽导致程序跑飞。尤其是遇见程序会偶然性死机情况,往往复现比较困难,但是对于要量产的产品来说是一个隐患。在这提供一种自动诊断故障出现获得精准故障位置的方法。
开源项目“CmBacktrace: ARM Cortex-M 系列 MCU 错误追踪库”,博主链接:CmBacktrace: ARM Cortex-M 系列 MCU 错误追踪库 (gitee.com)
2、手把手将CmBacktrace移植到自己的freertos工程
2.1 Cmbacktrace资源下载
github目录下载:
GitHub – armink/CmBacktrace: Advanced fault backtrace library for ARM Cortex-M series MCU | ARM Cortex-M 系列 MCU 错误追踪库
gitee目录下载:
CmBacktrace: ARM Cortex-M 系列 MCU 错误追踪库
2.2 自己的工程中添加CmBacktrace文件夹
1.复制目标文件夹
2.粘贴到自己的工程中
3.自己创建的Cmbcktrace中添加.c和.s文件
4.添加文件路径
2.3 工程中配置设置
1.注释HardFault_Handler函数。原因是在使用了cmbacetrace库提供的 cmb_fault.s 汇编文件时,该汇编文件内部已经定义了 HardFault_Handler ,所以如果项目中还有其他地方定义了该函数,则会提示 HardFault_Handler 被重复定义的错误。注释/删除其他文件中定义的 HardFault_Handler 函数,仅保留 cmb_fault.s 中的.
2.重映射一下串口,cmb_cfg.h文件配置所需要使用。
#if 1
#pragma import(__use_no_semihosting)
//标准库需要的支持函数
struct __FILE
{
int handle;
};
FILE __stdout;
//定义_sys_exit()以避免使用半主机模式
void _sys_exit(int x)
{
x = x;
}
//重定义fputc函数
int fputc(int ch, FILE *f)
{
/*“USART2根据自己的硬件要求修改”*/
while((USART2->ISR&0X40)==0);//循环发送,直到发送完毕
USART2->TDR = (uint8_t) ch;
return ch;
}
#endif
3.cmb_cfg.h文件配置设置,根据自己的平台选择对应的宏。
#ifndef _CMB_CFG_H_
#define _CMB_CFG_H_
#include "uart_driver.h"
#ifdef CMB_USER_CFG
#include "cmb_user_cfg.h"
#else
/* print line, must config by user */
#define cmb_println(...) printf(__VA_ARGS__);printf("\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_FREERTOS
/* cpu platform type, must config by user */
#define CMB_CPU_PLATFORM_TYPE CMB_CPU_ARM_CORTEX_M4
/* enable dump stack information */
#define CMB_USING_DUMP_STACK_INFO
/* language of print information */
#define CMB_PRINT_LANGUAGE CMB_PRINT_LANGUAGE_CHINESE
#endif
#endif /* _CMB_CFG_H_ */
4.task.c文件配置修改。因为 FreeRTOS 的 TCB 中没有 StackSize 信息,在 FreeRTOS/tasks.c 中增加了 uxSizeOfStack 字段, 以及 vTaskStackAddr() 、 vTaskStackSize() 、 vTaskName() 函数。直接将一下代码复制到task.c底部即可。
/*-----------------------------------------------------------*/
/*< Support For CmBacktrace >*/
uint32_t * vTaskStackAddr()
{
return pxCurrentTCB->pxStack;
}
uint32_t vTaskStackSize()
{
#if ( portSTACK_GROWTH > 0 )
return (pxNewTCB->pxEndOfStack - pxNewTCB->pxStack + 1);
#else /* ( portSTACK_GROWTH > 0 )*/
return pxCurrentTCB->uxSizeOfStack;
#endif /* ( portSTACK_GROWTH > 0 )*/
}
char * vTaskName()
{
return pxCurrentTCB->pcTaskName;
}
/*-----------------------------------------------------------*/
在typedef struct tskTaskControlBlock添加以下代码。
#if ( portSTACK_GROWTH > 0 )
StackType_t *pxEndOfStack; /*< Points to the end of the stack on architectures where the stack grows up from low memory. */
#else
UBaseType_t uxSizeOfStack; /*< Support For CmBacktrace >*/
#endif /* ( portSTACK_GROWTH > 0 )*/
在static void prvInitialiseNewTask添加如下代码。
pxNewTCB->uxSizeOfStack = ulStackDepth; /*< Support For CmBacktrace >*/
5.FreeRTOS.h文件配置设置。在typedef struct xSTATIC_TCB中添加如下代码。
#if(portSTACK_GROWTH <= 0)
UBaseType_t uxSizeOfStack; /*< Support For CmBacktrace >*/
#endif /* ( portSTACK_GROWTH > 0 )*/
6.最后我们在mian中初始化,即可正常使用。
#define HARDWARE_VERSION "V1.0.0"
#define SOFTWARE_VERSION "V0.1.0"
cm_backtrace_init("OTA", HARDWARE_VERSION, SOFTWARE_VERSION);//主函数中调用初始化
2.4 测试Cmbacktrace效果
1 创建测试任务,任务中调用一个除以0的错误操作函数,看看能否精准定位到错误的具体位置。
2 执行工程,发现程序死机了。通过串口查看打印的信息。但是我们还不能获得精准的故障位置,请继续看2.5addr2line工具使用。
2.5 addr2line工具使用,获取精准故障位置。
1.安装MinGW,参考MinGW下载安装教程 傻瓜式操作【超详细】_mingw-get-setup.exe-CSDN博客
安装后需要配置环境变量,博客中有提到如何配置。我们只需找到mingw64/bin中的addr2line.exe
2.编译你的工程文件,找到.axf文件。我的工程名是OTA所以找到OTA.axf文件夹即可。把上一步addr2line.exe复制到此文件夹中。
3.cmd打开命令串口,把你找到.axf文件路径在命令中打开。并将串口打印的“请运行:”后面的复制过来就可以查看到具体故障位置了。使用 addr2line --help
可以看到使用介绍。
3、完结
如有错误请谅解,接收一切请批评指正。一起学习进步!!!
完结撒花!!!
作者:L一宇航员的嵌入式笔记