搜遍全网都找不到一个靠谱的RT1052可用的移植方法,自己弄了一个分享出来,禁止一切形式未经许可的转载复制。
文章目录
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 编译器;
移植CmBacktrace
前期准备
- CmBacktrace源码
- 任意RT1052+FreeRTOS V10的keil工程(所有i.MX RT系列都可以)
移植过程
添加CmBacktrace到工程
把下载到的cm_backtrace文件夹复制到工程目录下,我这里为了方便,直接用官方sdk里的demo工程做演示了😆。实际情况以实际工程为准,步骤是一样的。
打开工程,在工程里添加源文件和包含路径
右键点击工程界面左边添加好的cmb_fault.S,点击Options for File ‘cmb_fault.S’,在Asm选项卡按照图中选择
; 配置CmBacktrace
需要配置的有cmb_cfg.h和cmb_def.h两个文件。
先打开工程目录下的cmb_cfg.h,这个文件用来配置CmBacktrace,每个配置项的具体含义如下:
配置项功能说明cmb_println(…)输出诊断信息必须配置CMB_USING_BARE_METAL_PLATFORM使能裸机平台配置在裸机上用就开这个宏CMB_USING_OS_PLATFORM使能RTOS平台配置在rtos上用就开这个宏CMB_OS_PLATFORM_TYPE选择RTOS类型在rtos上用必须配置CMB_CPU_PLATFORM_TYPE选择MCU内核类型必须配置CMB_USING_DUMP_STACK_INFO使能Dump堆栈信息功能需要时配置CMB_PRINT_LANGUAGE选择输出语言需要时配置,默认英文
表格的第1、3、4、5、7行是我们需要配置的项,具体配置如下:
#ifndef _CMB_CFG_H_
#define _CMB_CFG_H_
#include "fsl_debug_console.h"
#define cmb_println(...) PRINTF(__VA_ARGS__);PRINTF("\r\n")
#define CMB_USING_OS_PLATFORM
#define CMB_OS_PLATFORM_TYPE CMB_OS_PLATFORM_FREERTOS
#define CMB_CPU_PLATFORM_TYPE CMB_CPU_ARM_CORTEX_M7
#define CMB_PRINT_LANGUAGE CMB_PRINT_LANGUAGE_ENGLISH
#endif
然后是cmb_def.h,需要把栈节区和代码节区的名字改一下,这里不受具体工程配置的影响,也就是说不管代码和堆栈实际放在哪里,只要名字和分散加载里的定义的一样就能用,代码节区名字一定要和分散加载文件保持一致,具体改成下面这样:
#if defined(__ARMCC_VERSION)
#ifndef CMB_CSTACK_BLOCK_NAME
#define CMB_CSTACK_BLOCK_NAME Image$$ARM_LIB_STACK$$ZI
#endif
#ifndef CMB_CODE_SECTION_NAME
#define CMB_CODE_SECTION_NAME ER_m_text
#endif
接着到cm_backtrace.c,找到587行的cmb_println,在下图位置加一个空格。
适配FreeRTOS
配置好CmBacktrace以后,还需要改一下FreeRTOS的源码,不用担心不用怕,只是加几行获取任务栈信息的函数而已😊,并不会影响原本FreeRTOS的功能。
首先打开FreeRTOSConfig.h把下图这个宏关掉,不然会影响到实际使用效果,这个是FreeRTOS自带的任务调试功能,可以打印任务信息。
然后打开task.c,在文件最末尾加入下面的代码
uint32_t * vTaskStackAddr()
{
return pxCurrentTCB->pxStack;
}
uint32_t vTaskStackSize()
{
#if ( portSTACK_GROWTH > 0 )
return (pxNewTCB->pxEndOfStack - pxNewTCB->pxStack + 1);
#else
return pxCurrentTCB->uxSizeOfStack;
#endif
}
char * vTaskName()
{
return pxCurrentTCB->pcTaskName;
}
#if ( ( portSTACK_GROWTH > 0 ) || ( configRECORD_STACK_HIGH_ADDRESS == 1 ) )
StackType_t *pxEndOfStack;
#else
UBaseType_t uxSizeOfStack;
#endif
#else
pxNewTCB->uxSizeOfStack = ulStackDepth;
#endif
这个时候编译就没有错了。
使用CmBacktrace追踪错误
初始化CmBacktrace
在自己喜欢的地方添加宏定义:
#define APPNAME "cmbacktrace_test"
#define HARDWARE_VERSION "V1.0.0"
#define SOFTWARE_VERSION "V0.1.0"
在main函数中调用初始化函数;
写一个除零错误的函数模拟hard fault;
创建一个任务调用除零函数模拟任务中错误的情况,main函数完整代码如下:
int main(void)
{
BOARD_ConfigMPU();
BOARD_InitBootPins();
BOARD_InitBootClocks();
BOARD_InitDebugConsole();
cm_backtrace_init("CmBacktrace", HARDWARE_VERSION, SOFTWARE_VERSION);
if (xTaskCreate(hello_task, "Hello_task", configMINIMAL_STACK_SIZE + 100, NULL, hello_task_PRIORITY, NULL) !=
pdPASS)
{
PRINTF("Task creation failed!.\r\n");
while (1)
;
}
if (xTaskCreate(test_task, "test_task", configMINIMAL_STACK_SIZE + 100, NULL, test_task_PRIORITY, NULL) !=
pdPASS)
{
PRINTF("Task creation failed!.\r\n");
while (1)
;
}
vTaskStartScheduler();
for (;;)
;
}
static void hello_task(void *pvParameters)
{
for (;;)
{
PRINTF("Hello world.\r\n");
vTaskSuspend(NULL);
}
}
void fault_test_by_div0(void) {
volatile int * SCB_CCR = (volatile int *) 0xE000ED14;
int x, y, z;
*SCB_CCR |= (1 << 4);
x = 10;
y = 0;
z = x / y;
PRINTF("z:%d\n", z);
}
static void test_task(void *pvParameters)
{
fault_test_by_div0();
for (;;)
{
PRINTF("cmbacktrace.\r\n");
vTaskDelay(100);
}
}
编译并下载运行,在串口助手中可以看到如下输出信息。
要注意的是,不管是debug工程还是release工程,都需要进入keil的debug界面运行代码才会有输出,目前暂时不清楚为啥。
定位到具体的出错代码
串口打印出了当前发生的是哪种hard fault,定位到具体的代码还需要addr2line工具,工具的可执行文件addr2line.exe就在一开始下载的源码包的 tools\addr2line\win64路径下。
解压addr2line.exe到工程.axf文件所在的文件夹,并在此文件夹下打开命令行工具,墙裂建议安装Windows Terminal,用过最好用的win命令行工具。
打开工具以后,把串口助手最后一行打印的命令复制到命令行工具内,把cmbacktrace.axf替换成自己工程里的文件名。不管后缀是.out还是.axf都是可以的,然后回车就能看到具体的出错代码位置。
Original: https://blog.csdn.net/zzz_xxj/article/details/127810268
Author: ZZZ_XXJ
Title: 亲测可用的RT1052+FreeRTOS10.3移植CmBacktrace方法——2022.11.12
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/659413/
转载文章受原作者版权保护。转载请注明原作者出处!