test(vd960DBN): 实验D — 栈空间诊断 + load_cfg/output_cfg 触发点验证 (2026-08-17)

新证据: BOOT_CNT@0x2000f854 = .noinit 被推到 RAM 顶, 栈顶(0x20010000)
之下仅 ~1.9KB → .bss≈46KB (BLE/WCHNET/SPI_FLASH_BUF 等大数组挤占)。
栈溢出 → 覆盖 .noinit(g_boot_count 恒1/g_fault_diag 消失) + 覆盖返回地址
→ PC 跑飞跳回 0 → 循环。快照延后无效因为问题不是快照 SPI 而是栈空间。

- BOOT_CNT 打印加 _end(堆起点, 反推.bss大小) + 当前 SP(栈深)
- load_cfg/output_cfg #if 0 (EXPD 标记): 稳定→触发点确认; 仍崩→更晚
- 待用户提供编译后 .map 确认 .bss 组成
This commit is contained in:
wangfq
2026-08-17 11:00:03 +08:00
parent 8cf01544f6
commit 452ff68bae
@@ -315,9 +315,18 @@ int main(void)
每次上电必打, 区分看门狗死锁 vs 掉电 vs 外部复位 */ 每次上电必打, 区分看门狗死锁 vs 掉电 vs 外部复位 */
PRINT("RST_REASON: 0x%08lx\n", (unsigned long)OFFLOG_RCC_RSTSCKR); PRINT("RST_REASON: 0x%08lx\n", (unsigned long)OFFLOG_RCC_RSTSCKR);
g_boot_count++; g_boot_count++;
PRINT("BOOT_CNT: %lu @0x%08lx\n", (unsigned long)g_boot_count, (unsigned long)&g_boot_count); {
/* 地址判读: >= _ebss(约0x2000612c) 且在 .noinit 段 → 复位不清零, 递增应>1; extern char _end[]; /* 堆起点 = .bss 末尾 (Link.ld) */
BOOT_CNT 恒=1 → RAM 被清 (掉电级) 或 g_boot_count 落 .bss */ uint32_t _sp;
__asm__ volatile("mv %0, sp" : "=r"(_sp));
PRINT("BOOT_CNT:%lu @0x%08lx END:0x%08lx SP:0x%08lx\n",
(unsigned long)g_boot_count, (unsigned long)&g_boot_count,
(unsigned long)_end, (unsigned long)_sp);
/* 判读(2026-08-17): BOOT_CNT@0x2000f854 → .noinit 被推到 RAM 顶,
栈顶 0x20010000 之下仅 ~1.9KB → .bss≈46KB(大数组), 栈溢出风险!
END = 堆起点(.bss 末): END - 0x20004000 - .data ≈ .bss 大小;
SP = 当前栈深(main 入口浅栈处, 栈顶下方 ~几十字节) */
}
fault_diag_init(); /* 打印上次复位现场 (HardFault mcause/mepc + 执行轨迹 marker) */ fault_diag_init(); /* 打印上次复位现场 (HardFault mcause/mepc + 执行轨迹 marker) */
iot_watchdog_init(); /* 无条件 IWDG (2026-08-13): iot_enable=0 时 iot_mqtt_init 不调, iot_watchdog_init(); /* 无条件 IWDG (2026-08-13): iot_enable=0 时 iot_mqtt_init 不调,
卡死无兜底 → 永久冻结。IWDG 4s 超时 + 主循环喂狗 */ 卡死无兜底 → 永久冻结。IWDG 4s 超时 + 主循环喂狗 */
@@ -348,9 +357,16 @@ int main(void)
OFFLOG_RCC_RSTSCKR |= OFFLOG_RST_RMVF; /* RMVF (bit24): 清复位标志 */ OFFLOG_RCC_RSTSCKR |= OFFLOG_RST_RMVF; /* RMVF (bit24): 清复位标志 */
} }
/* load_cfg/output_cfg: 参数区 SPI 读 + 配置打印 — 实验B未测, 快照延后方案优先, 已恢复 */ /* ===== 实验D (2026-08-17): 验证 load_cfg/output_cfg 是否为栈溢出触发点 =====
BOOT_CNT@0x2000f854 → 栈≈1.9KB (极小)。此二函数含 malloc(512B)+
SPI_Flash_Read+大量 printf(%s), 栈峰值可能触顶。
稳定 → 触发点确认(此处栈深); 仍崩 → 触发点在别处(BLE init等) */
#if 0
load_cfg_from_flash(); load_cfg_from_flash();
output_cfg_from_flash(); output_cfg_from_flash();
#else
PRINT("EXPD: load_cfg/output_cfg skipped\n");
#endif
#endif #endif
PRINT("MAC: %02X %02X %02X %02X %02X %02X\r\n", gMacAddr[0],gMacAddr[1], gMacAddr[2], gMacAddr[3],gMacAddr[4],gMacAddr[5]); PRINT("MAC: %02X %02X %02X %02X %02X %02X\r\n", gMacAddr[0],gMacAddr[1], gMacAddr[2], gMacAddr[3],gMacAddr[4],gMacAddr[5]);