Files
vd_960/vd960DBN/BLE/OnlyUpdateApp_Peripheral/APP/include/fault_diag.h
T
wangfq 9f5102e9e8 feat(vd960DBN): fault_diag — .noinit RAM 现场 + 执行轨迹 marker 定位神秘复位
现象: LUP 帧后复位, RST=0x00000000 (无标志) 且 HardFault 打印缺失
(上次 0x10000000=SFT 确认 HardFault 路径, 这次连打印都没有)
方案: .noinit 段复位不清零, 跨复位留痕
- Link.ld: 新增 .noinit 段 (startup 只清 .bss 不碰)
- fault_diag.h: FaultDiag{magic,mcause,mepc,mtval,marker,boot_cnt} + FAULT_MARKER 轨迹宏
- HardFault_Handler: 纯 RAM 写 mcause/mepc/mtval (官方 __get_MCAUSE/MEPC/MTVAL,
  不依赖 UART/printf, 栈坏也能留痕) + 尽力打印
- main 开头 fault_diag_init(): 打印上次现场 + 递增 boot_cnt
- 轨迹 marker: 主循环 LOOP_TOP/UART_SRV/SIM_SPI/POLL_BLE + LUP 链
  LUP_FRAME/INGEST/EVT_FEED 入口出口, 复位后看 marker 停在哪一步
2026-08-13 15:44:07 +08:00

57 lines
2.8 KiB
C

/********************************** (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 <stdint.h>
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 */