ARM Cortex-M 系列 MCU 错误追踪库 --- CmBacktrace

一、CmBacktrace简介
一款针对 ARM Cortex-M 系列 MCU 的错误代码自动追踪、定位,错误原因自动分析的开源库。主要特性如下:

  • 支持的错误包括:
    • 断言(assert)
    • 故障(Hard Fault, Memory Management Fault, Bus Fault, Usage Fault, Debug Fault)
  • 故障原因 自动诊断 :可在故障发生时,自动分析出故障的原因,定位发生故障的代码位置,而无需再手动分析繁杂的故障寄存器;
  • 输出错误现场的 函数调用栈(需配合 addr2line 工具进行精确定位),还原发生错误时的现场信息,定位问题代码位置、逻辑更加快捷、精准。也可以在正常状态下使用该库,获取当前的函数调用栈;
  • 支持 裸机 及以下操作系统平台:
  • 根据错误现场状态,输出对应的 线程栈 或 C 主栈;
  • 故障诊断信息支持多国语言(目前:简体中文、英文);
  • 适配 Cortex-M0/M3/M4/M7 MCU;
  • 支持 IAR、KEIL、GCC 编译器;
    更多详情大家可以到GITHUB开源的这个网址查看:CmBacktrace开源代码

二、移植环境
系统:WIN7
MDK:keil v5.26
开发板:GD32F303C-EVAL
固件库:V1.0.2
FreeRTOS版本:V10.4.0
CmBacktrace Release 1.4.0
三、开始移植
1> 下载源码,解压,如下图:
在这里插入图片描述
cm_backtrace这个文件夹下就是核心文件,就是我们移植需要用到的。
2>将核心文件添加到工程中,将1中cm_backtrace整个文件夹复制到工程,添加文件和头文件路径到工程。
在这里插入图片描述
3> 将gd32f30x_it.c文件中断硬件中断入口函数屏蔽掉,因为cmb_fault.S中重构了这个函数,重复了。当然了也可以有另外的一种方式,详情可以参考源代码中移植说明。
在这里插入图片描述
4>写断言函数
因为GD的库中很少用到指针形参,与ST的标准库有很大区别,所以不像ST库里面用到了断言函数。所以只能自己写一个。参考如下:

void assert_failed(uint8_t* file, uint32_t line)
{
    /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
    /* Infinite loop */
    cm_backtrace_assert(cmb_get_sp());
    SEGGER_RTT_printf(0,"assert failed at %s:%d \n", file, line);
//	printf("assert failed at %s:%d \n", file, line);
    while (1) {
    }
}
/**
  * @brief  The assert_param macro is used for function's parameters check.
  * @param expr: If expr is false, it calls assert_failed function
  *   which reports the name of the source file and the source
  *   line number of the call that failed. 
  *   If expr is true, it returns no value.
  * @retval : None
  */
#define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__,(uint32_t) __LINE__))

这里还需要将cmb_cfg.h中进行如下修改,为了方便打印信息
在这里插入图片描述
代码开发完成后,可以将断言函数和打印信息关掉,节省代码空间。
5>配置说明,配置文件是cmb_cfg.h


#ifndef _CMB_CFG_H_
#define _CMB_CFG_H_

/* print line, must config by user */
//#define cmb_println(...)               printf(__VA_ARGS__);printf("\r\n");
#define cmb_println(...)               SEGGER_RTT_printf(0,__VA_ARGS__);SEGGER_RTT_printf(0,"\r\n");/* e.g., 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_RTT or CMB_OS_PLATFORM_UCOSII or CMB_OS_PLATFORM_UCOSIII or CMB_OS_PLATFORM_FREERTOS */
/* 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_ENGLISH//CMB_PRINT_LANGUAGE_ENGLISH(default) or CMB_PRINT_LANGUAGE_CHINESE 
#endif /* _CMB_CFG_H_ */

6> 添加头文件和初始化函数

#include "cm_backtrace.h"
	/* CmBacktrace initialize */
  cm_backtrace_init("CmBacktrace", HARDWARE_VERSION, SOFTWARE_VERSION);

至此移植完成。
四、测试
这里使用开源代码中提供一个demo进行测试

#include "SEGGER_RTT.h"
#include "cm_backtrace.h"

#define HARDWARE_VERSION               "V1.0.0"
#define SOFTWARE_VERSION               "V0.1.0"

void fault_test_by_div0(void);

void assert_failed(uint8_t* file, uint32_t line)
{
    /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
    /* Infinite loop */
    cm_backtrace_assert(cmb_get_sp());
    SEGGER_RTT_printf(0,"assert failed at %s:%d \n", file, line);
//	printf("assert failed at %s:%d \n", file, line);
    while (1) {
    }
}
/**
  * @brief  The assert_param macro is used for function's parameters check.
  * @param expr: If expr is false, it calls assert_failed function
  *   which reports the name of the source file and the source
  *   line number of the call that failed. 
  *   If expr is true, it returns no value.
  * @retval : None
  */
#define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__,(uint32_t) __LINE__))
int main(void)
{

	delay_init();
	usart0_shell();
	GW_LedInit(LED1);
	/* CmBacktrace initialize */
  cm_backtrace_init("CmBacktrace", HARDWARE_VERSION, SOFTWARE_VERSION);
  SEGGER_RTT_ConfigUpBuffer(0, NULL, NULL, 0, SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL);
	SEGGER_RTT_printf(0,"test start\r\n");
	fault_test_by_div0();
	while(1)
	{
		GW_LedToggle(LED1);
		delay_xms(100);
	}

}
void fault_test_by_div0(void) 
{
    volatile int * SCB_CCR = (volatile int *) 0xE000ED14; // SCB->CCR
    int x, y, z;

    *SCB_CCR |= (1 << 4); /* bit4: DIV_0_TRP. */

    x = 10;
    y = 0;
    z = x / y;
    printf("z:%d\n", z);
}

五、测试结果
在这里插入图片描述
从结果的最后打印信息看出;提示是除0错误导致的,更加详细的就需要打开MAP文件和错误寄存器查看了。

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值