/********************************** (C) COPYRIGHT ******************************* * File Name : fault_diag.h * Author : wfq * Version : V1.0 * Date : 2026-08-13 * Description : 故障诊断 — .noinit RAM 现场 + 执行轨迹 marker * * 背景: HardFault 时 UART/printf 可能不可用 (栈坏/中断禁用), 打印丢现场; * RST=0x00000000 的复位无任何标志, 无法从 RSTSCKR 判断复位源。 * 方案: 全局记录放 .noinit 段 (复位不清零, 链接脚本已加): * - HardFault_Handler 纯 RAM 写 mcause/mepc/mtval (不依赖 UART) * - 关键路径 FAULT_MARKER() 记录执行轨迹 * - main 开头 fault_diag_init() 打印上次现场 + 递增 boot_cnt * 用法: FAULT_MARKER(MK_XXX) 插在嫌疑路径各阶段; 复位后看 marker 停在哪。 *******************************************************************************/ #ifndef __FAULT_DIAG_H #define __FAULT_DIAG_H #include typedef struct { uint32_t magic; /* 0xFA57FA57 = 现场有效 */ uint32_t mcause; /* RISC-V 异常原因 (5/7=野指针 2=非法指令 4/6=未对齐) */ uint32_t mepc; /* 异常指令 PC (对照 .map 反查函数) */ uint32_t mtval; /* 错误访问地址 */ uint32_t marker; /* 最后执行位置标记 */ uint32_t boot_cnt; /* 复位计数 */ } FaultDiag; /* 定义在 ch32v20x_it.c (.noinit 段) */ extern FaultDiag g_fault_diag; /* main 开头调用: 打印上次现场 + 重置 + boot_cnt++ */ void fault_diag_init(void); /* 执行轨迹标记 */ #define FAULT_MARKER(s) (g_fault_diag.marker = (s)) #define MK_MAIN_ENTRY 0xA0000001UL /* main 入口 */ #define MK_INIT_DONE 0xA0000002UL /* 初始化完成, 进主循环前 */ #define MK_LOOP_TOP 0xA0000010UL /* 主循环 while 开头 */ #define MK_UART_SRV_IN 0xA0000011UL /* uart_srv 调用前 */ #define MK_UART_SRV_OUT 0xA0000012UL /* uart_srv 返回后 */ #define MK_SIM_SPI_IN 0xA0000013UL /* sim_snap_spi 调用前 */ #define MK_POLL_BLE_IN 0xA0000014UL /* poll_dbn_ble 调用前 */ #define MK_LUP_FRAME_IN 0xA0000020UL /* lup_process_frame 入口 */ #define MK_LUP_FRAME_OUT 0xA0000021UL /* lup_process_frame 出口 */ #define MK_INGEST_IN 0xA0000030UL /* iot_sensor_ingest 入口 */ #define MK_INGEST_OUT 0xA0000031UL /* iot_sensor_ingest 出口 */ #define MK_EVT_FEED_IN 0xA0000032UL /* iot_evt_feed 入口 */ #define MK_EVT_FEED_OUT 0xA0000033UL /* iot_evt_feed 出口 */ #define MK_EVT_CB_IN 0xA0000034UL /* iot_evt_sensor_cb 入口 */ #define MK_EVT_CB_OUT 0xA0000035UL /* iot_evt_sensor_cb 出口 */ #endif /* __FAULT_DIAG_H */