S32K328(Arm Cortex-M7)适配CmBacktrace错误追踪

CmBacktrace 相当于重写了hard_fault函数,在hard_fault函数里面去分析SCB寄存器的信息和堆栈信息,然后把这些信息打印出来(或者写到flash);通过使用串口输出产生hard_fault的堆栈信息,然后利用addr2line工具反推出具体的代码执行函数,快速定位hard_fault问题;

1:CmBacktrace获取

看两个git的更新记录,github应该是比较新的;作者都是同一个人

github地址

bash 复制代码
https://github.com/armink/CmBacktrace

gitee地址

bash 复制代码
https://gitee.com/Armink/CmBacktrace

使用说明介绍这个博主讲的挺详细的

bash 复制代码
https://blog.csdn.net/weiqifa0/article/details/120499893

然后大家自行搜索一下 addr2line 工具的说明即可

2:CmBackTrace代码修改适配

cmb_cfg.h 修改

c 复制代码
#ifndef _CMB_CFG_H_
#define _CMB_CFG_H_
#include "mocar_log.h"

#ifdef	CMB_USER_CFG
#include "cmb_user_cfg.h"
#else
/* print line, must config by user */
#define cmb_println(...)    log_print(SLOG_INFO, __VA_ARGS__);            /* 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_FREERTOS    /* CMB_OS_PLATFORM_RTT or CMB_OS_PLATFORM_UCOSII or CMB_OS_PLATFORM_UCOSIII or CMB_OS_PLATFORM_FREERTOS or CMB_OS_PLATFORM_RTX5 or CMB_OS_PLATFORM_THREADX */
/* 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_ENGLISH  /* CMB_PRINT_LANGUAGE_ENGLISH(default) or CMB_PRINT_LANGUAGE_CHINESE or CMB_PRINT_LANGUAGE_CHINESE_UTF8 */
#endif

#endif /* _CMB_CFG_H_ */

cmb_def.h 修改

S32DS默认使用gcc编译器;
注意这里要结合.ld文件去里面的 SECTIONS{...}适配, 不同的.ld文件名称可能不一致;

c 复制代码
......
#elif defined(__GNUC__)
    /* C stack block start address, defined on linker script file, default is _sstack */
    #ifndef CMB_CSTACK_BLOCK_START
    #define CMB_CSTACK_BLOCK_START         __Stack_dtcm_start
    #endif
    /* C stack block end address, defined on linker script file, default is _estack */
    #ifndef CMB_CSTACK_BLOCK_END
    #define CMB_CSTACK_BLOCK_END           __Stack_dtcm_end
    #endif
    /* code section start address, defined on linker script file, default is _stext */
    #ifndef CMB_CODE_SECTION_START
    #define CMB_CODE_SECTION_START         __text_start
    #endif
    /* code section end address, defined on linker script file, default is _etext */
    #ifndef CMB_CODE_SECTION_END
    #define CMB_CODE_SECTION_END           __text_end
    #endif
#else
    #error "not supported compiler"
#endif

task.c修改

c 复制代码
......
/*适配CmBacktrace插件*/
uint32_t *vTaskStackAddr(void)
{
    return (uint32_t)pxCurrentTCB->pxStack;
}

uint32_t vTaskStackSize(void)
{
    return (uint32_t)pxCurrentTCB - (uint32_t)pxCurrentTCB->pxStack - 4;
}

char * vTaskName()
{
    return pxCurrentTCB->pcTaskName;
}

在现场里面自己写了个触发hard_fault的代码;参考例程里面的代码,测试不会产生 HardFault_Handler

c 复制代码
/*cm_backtrace 临时测试产生hardfault的函数 */
#include "C40_Ip.h"
static void tmp_test_create_hardfault(void)
{
    C40_Ip_StatusType c40_erase_status=C40_IP_STATUS_ERROR;

	if (C40_IP_STATUS_SECTOR_PROTECTED == C40_Ip_GetLock(C40_CODE_ARRAY_0_BLOCK_0_S000))
	{
		C40_Ip_ClearLock(C40_CODE_ARRAY_0_BLOCK_0_S000, 0);
	}
    c40_erase_status = C40_Ip_MainInterfaceSectorErase(C40_CODE_ARRAY_0_BLOCK_0_S000, 0);
    if (c40_erase_status == C40_IP_STATUS_SUCCESS)
    {        
        // 擦除之后必须调用该接口,不然会报 EHV 错误; 很容易就busy了...
        c40_erase_status = C40_Ip_MainInterfaceSectorEraseStatus();
    }
}

S32DS代码里面的 exceptions.c里面定义的是弱函数,重写之后自动覆盖了; 担心没有覆盖的话可以屏蔽掉

c 复制代码
//void HardFault_Handler(void)            __attribute__ ((weak));         /* Hard Fault Handler */
......
//void HardFault_Handler(void)
//{
//    while(TRUE){};
//}

其它的再没修改什么通用的代码了,根据自己的工程初始化"cm_backtrace_init"之后,调用 "tmp_test_create_hardfault"函数即可

3:实测验证

代码烧写运行之后串口日志如下

Bus fault is caused by ... 这里的故障原因就是分析 SCB寄存器的出来的

bash 复制代码
1969.12.31-23:59:59]info cm_backtrace_fault lr=0xfffffffd sp=0x2000ffe0
[1969.12.31-23:59:59]info Firmware name: FreeRTOS_S32K328, hardware version: hv_v1.0.0, software version: sv_v1.0.1
[1969.12.31-23:59:59]info Fault on thread TaskManager
[1969.12.31-23:59:59]info ===== Thread stack information =====
[1969.12.31-23:59:59]info stack_info pointer=0x20400ff8 addr=0x20400458 size=12272
[1969.12.31-23:59:59]info   addr: 20400ff8    data: 00000000
[1969.12.31-23:59:59]info   addr: 20400ffc    data: 00000000
[1969.12.31-23:59:59]info   addr: 20401000    data: 20401008
[1969.12.31-23:59:59]info   addr: 20401004    data: 0041ebf1
[1969.12.31-23:59:59]info   addr: 20401008    data: 00a5a5a5
[1969.12.31-23:59:59]info   addr: 2040100c    data: 00000010
[1969.12.31-23:59:59]info   addr: 20401010    data: 00400000
[1969.12.31-23:59:59]info   addr: 20401014    data: 00000000
[1969.12.31-23:59:59]info   addr: 20401018    data: 20401020
[1969.12.31-23:59:59]info   addr: 2040101c    data: 004110e1
[1969.12.31-23:59:59]info   addr: 20401020    data: 20400398
[1969.12.31-23:59:59]info   addr: 20401024    data: 00000002
[1969.12.31-23:59:59]info   addr: 20401028    data: 20401030
[1969.12.31-23:59:59]info   addr: 2040102c    data: 00411141
[1969.12.31-23:59:59]info   addr: 20401030    data: 00000000
[1969.12.31-23:59:59]info   addr: 20401034    data: 00000000
[1969.12.31-23:59:59]info ====================================
[1969.12.31-23:59:59]info =================== Registers information ====================
[1969.12.31-23:59:59]info   R0 : 00000000  R1 : 00000000  R2 : 402ec000  R3 : 00000000
[1969.12.31-23:59:59]info   R12: 0000000a  LR : 004407d3  PC : 004407d6  PSR: 61000000
[1969.12.31-23:59:59]info ==============================================================
[1969.12.31-23:59:59]info Bus fault is caused by instruction access violation
[1969.12.31-23:59:59]info Bus fault is caused by precise data access violation
[1969.12.31-23:59:59]info The bus fault occurred address is 00440810
[1969.12.31-23:59:59]info Show more call stack info by run: addr2line -e FreeRTOS_S32K328.elf -afpiC 004407d6 004407d2 0041ebf0 004110e0 00411140 004066f4 0040936e 

addr2line执行如下;我使用相对路径执行的,没有添加环境变量

bash 复制代码
PS D:\2_gitlab\S32K328\s32k328\FreeRTOS_S32K328\FreeRTOS_S32K328\src\mid\cm_backtrace\exe> .\addr2line.exe -e ..\..\..\..\Debug_FLASH\FreeRTOS_S32K328.elf -afpiC 004407d6 004407d2 0041ebf0 004110e0 00411140 004066f4 0040936e
0x004407d6: SchM_Exit_Mem_43_INFLS_MEM_EXCLUSIVE_AREA_10 at D:\2_gitlab\S32K328\s32k328\FreeRTOS_S32K328\FreeRTOS_S32K328\Debug_FLASH/../RTD/src/SchM_Mem_43_INFLS.c:797
0x004407d2: SchM_Exit_Mem_43_INFLS_MEM_EXCLUSIVE_AREA_10 at D:\2_gitlab\S32K328\s32k328\FreeRTOS_S32K328\FreeRTOS_S32K328\Debug_FLASH/../RTD/src/SchM_Mem_43_INFLS.c:795
0x0041ebf0: C40_Ip_MainInterfaceSectorErase at D:\2_gitlab\S32K328\s32k328\FreeRTOS_S32K328\FreeRTOS_S32K328\Debug_FLASH/../RTD/src/C40_Ip.c:2569      
0x004110e0: tmp_test_create_hardfault at D:\2_gitlab\S32K328\s32k328\FreeRTOS_S32K328\FreeRTOS_S32K328\Debug_FLASH/../src/task/manager/manager.c:243   
0x00411140: task_manage_thread at D:\2_gitlab\S32K328\s32k328\FreeRTOS_S32K328\FreeRTOS_S32K328\Debug_FLASH/../src/task/manager/manager.c:270
0x004066f4: xTaskResumeAll at D:\2_gitlab\S32K328\s32k328\FreeRTOS_S32K328\FreeRTOS_S32K328\Debug_FLASH/../FreeRTOS/Source/tasks.c:4102
0x0040936e: prvTimerTask at D:\2_gitlab\S32K328\s32k328\FreeRTOS_S32K328\FreeRTOS_S32K328\Debug_FLASH/../FreeRTOS/Source/timers.c:777 (discriminator 1)

最后附一张截图

相关推荐
冲,干,闯6 小时前
基于沁恒微电子CH32V307单片机使用
单片机·嵌入式硬件
机器视觉知识推荐、就业指导7 小时前
STM32 外设驱动模块五:DHT11 温湿度传感器
stm32·单片机·嵌入式硬件
广药门徒10 小时前
电脑芯片其实更偏向MPU不是CPU,GPU CPU NPU MPU MCU的区别
单片机·嵌入式硬件
灬若宸12 小时前
14、外部中断
stm32·单片机·嵌入式硬件·系统架构
逼子格14 小时前
【Protues仿真】基于AT89C52单片机的舵机和直流电机控制
单片机·嵌入式硬件·硬件工程·硬件工程师·电机驱动·l298n·直流电机控制
GodKK老神灭14 小时前
STM32 AFIO模块
stm32·单片机·嵌入式硬件
滴啦嘟啦哒17 小时前
【项目复盘】【四轴飞行器设计】驱动开发部分
单片机·面试准备
狂奔的sherry17 小时前
一会儿能ping通一会ping不通解决方案
运维·网络·单片机·嵌入式硬件
qq_4017004117 小时前
单片机驱动继电器接口
单片机·嵌入式硬件