docs(vd960DBN): devlog 重写 2026-08-17 条目 — 根因闭环 + 板级验证通过 (2026-08-17)
- 条目重写为完整闭环: 诊断(Hex日志+实验A/D) → 根因(.bss挤占RAM→栈1.9KB→ printf栈溢出→PC跑飞) → 修复链(4 commit) → .map分析(BLE栈16KB固定) → 二轮瘦身 → 板级验证(用户实测无异常重启) - 验证项标记: 一轮瘦身版无复位(MQTT/BLE正常), 二轮瘦身版测试无异常重启 - 遗留: TCP JSON 回归 + 快照区 3s 初始化回归
This commit is contained in:
+35
-73
@@ -4,103 +4,65 @@
|
||||
>
|
||||
> 项目定位: DLD960 通信板 — BLE 配网、TCP JSON 协议服务、Loop MCU 串口桥接
|
||||
|
||||
## 2026-08-17 — 快照区延后初始化(开机 3s 后)— 启动早期 SPI 重负载疑似触发跑飞
|
||||
## 2026-08-17 — 频繁"复位"根因闭环:.bss 挤占 RAM → 栈溢出 → PC 跑飞
|
||||
|
||||
### 背景
|
||||
08-14 恢复快照区功能(8873b33)后,现场频繁"复位"(100~180ms 一轮完整启动日志)。
|
||||
Hex 日志诊断:
|
||||
|
||||
### 诊断过程(Hex 日志 + 二分实验)
|
||||
|
||||
| 观察 | 推断 |
|
||||
|------|------|
|
||||
| RST_REASON 首次 0x08000000(POR),之后恒 0x00000002(无任何复位标志位) | 非硬件复位(POR/IWDG/SFT/PIN 都会置位) |
|
||||
| 无 FAULT_DIAG 输出 | 非 HardFault(fault_diag 仅在 HardFault 后打印) |
|
||||
| 每轮都到 `INIT: snap ok`,之后无任何 ASCII 直接 71B 乱码+重启 | 跑飞点在 snap_init 之后(offlog_boot/load_cfg/output_cfg 区间) |
|
||||
| 实验A(跳过 offlog_boot,commit 0c717e4):仍崩 | offlog_boot 非触发点 |
|
||||
| BOOT_CNT 恒=1(.noinit 计数器每次从 0 开始) | RAM 全丢级重启(掉电-恢复但未触发 POR) |
|
||||
| RST_REASON 首次 0x08000000(POR),之后恒 0x00000002(无复位标志位) | 非硬件复位(POR/IWDG/SFT/PIN 都会置位),是 PC 跑飞跳回 0 |
|
||||
| 无 FAULT_DIAG 输出 | 非 HardFault |
|
||||
| snap ok 后 71B 乱码 + 无 ASCII 打印 | 跑飞点在 offlog_boot/load_cfg/output_cfg 区间 |
|
||||
| 实验A(跳过 offlog_boot, 0c717e4):仍崩 | offlog_boot 非触发点 |
|
||||
| 实验D(跳过 load_cfg/output_cfg, 452ff68):**完全正常启动** | **触发点 = load_cfg/output_cfg** |
|
||||
| BOOT_CNT@0x2000f84c END:0x2000f834 | **.bss≈46KB → 栈仅 ~1.9KB**(危险) |
|
||||
|
||||
### 结论
|
||||
启动早期 SPI 重负载(offlog_init 擦+整扇区写回 ~80ms + snap_init 擦+整扇区写回 ~80ms)
|
||||
让电源/系统进入临界状态,随后的 SPI 操作(load_cfg 读参数区)成为压垮点。
|
||||
08-13"稳定 6 分钟"实为实验状态(snap_init/offlog_boot 均 #if 0),非完整固件。
|
||||
### 根因
|
||||
**.bss 挤占 RAM → 栈仅 1.9KB → load_cfg/output_cfg 的 printf 栈峰值触顶**
|
||||
→ 溢出覆盖 .noinit(g_boot_count 恒 1、g_fault_diag 消失)+ 返回地址 → PC 跑飞 → 循环。
|
||||
08-13"稳定 6 分钟"实为实验状态(snap_init/offlog_boot 均 #if 0),非完整固件;
|
||||
快照区延后无效,因为问题不是快照 SPI,是栈空间被 .bss 挤占。
|
||||
|
||||
### 方案
|
||||
快照区延后到开机 3s 后初始化:避开启动早期 SPI 重负载窗口;3s 内传感帧
|
||||
由 snap_enqueue/snap_flush 的 !_ready 门控自然丢弃(视为无效快照数据)。
|
||||
### 修复链(4 个 commit)
|
||||
| commit | 内容 |
|
||||
|--------|------|
|
||||
| 452ff68 | 实验D:BOOT_CNT 加 END/SP 打印 + 跳过 load_cfg/output_cfg(定位触发点) |
|
||||
| 26f2326 | 止血:load_cfg 去调试打印、output_cfg 暂关(设备稳定启动) |
|
||||
| 421334e | RAM 瘦身一轮:ETH 1520→768、payload/MQTT buf 1400/1024→800(栈 1.9→4.7KB) |
|
||||
| 89ba602 | 闭环:恢复全部调试打印 + load_cfg 字符串 0 终止保险 |
|
||||
|
||||
| 文件 | 变更 |
|
||||
|------|------|
|
||||
| `snapshot.c` | 新增 `snap_delayed_init()`:主循环每轮调用,mstick()>=3000 且未初始化时执行 snap_init(非阻塞) |
|
||||
| `snapshot.h` | 声明 `snap_delayed_init()` |
|
||||
| `peripheral_main.c` | main() 移除 snap_init 调用;主循环喂狗后加 snap_delayed_init();撤销实验A(恢复 offlog_boot)/实验B(恢复 load_cfg/output_cfg);保留 BOOT_CNT 诊断打印 |
|
||||
|
||||
### 实验 D 结论(2026-08-17 晚,commit 452ff68/后续)
|
||||
实验 D(跳过 load_cfg/output_cfg)**设备完全正常启动**(WCHNET/TCP/BLE 全通)→
|
||||
**触发点确认 = load_cfg_from_flash / output_cfg_from_flash**(栈溢出)。
|
||||
|
||||
BOOT_CNT 打印扩展证实 RAM 布局:
|
||||
```
|
||||
BOOT_CNT:1 @0x2000f84c END:0x2000f834 SP:0x2000ffd0
|
||||
```
|
||||
- END(0x2000f834) = 堆起点 → **.bss ≈ 46KB**(BLE 栈 + ETH DMA 7.6KB + SPI_FLASH_BUF 4KB + 网络缓冲)
|
||||
- g_boot_count@0x2000f84c = .noinit 被推到 RAM 顶 → **栈仅 ~1.9KB**(危险)
|
||||
- 栈溢出 → 覆盖 .noinit(g_boot_count 恒1/g_fault_diag 消失) + 返回地址 → PC 跑飞 → 循环
|
||||
- **快照延后无效的原因**:问题不是快照 SPI,是栈空间被 .bss 挤占
|
||||
|
||||
### 修复(栈溢出止血)
|
||||
| 文件 | 变更 |
|
||||
|------|------|
|
||||
| `cfig_flash.c` | load_cfg 内 3 处调试 PRINT 注释(magic mismatch ×2 + Sub_Code ×1)——printf 栈峰值是压垮 1.9KB 栈的最后一根稻草 |
|
||||
| `peripheral_main.c` | load_cfg 恢复(保留配置加载);output_cfg 调用 #if 0(纯调试打印,栈峰值高) |
|
||||
|
||||
### RAM 瘦身(2026-08-17 晚,commit 后述)— .bss ≈46KB → 目标栈 4KB+
|
||||
实验 D 确认栈溢出根因后,.bss 瘦身四刀(省 ~4.8KB,栈 1.9KB → ~6.7KB):
|
||||
|
||||
| 文件 | 项目 | 现状 | 改为 | 省 .bss |
|
||||
|------|------|------|------|---------|
|
||||
| net_config.h | ETH_MAX_PACKET_SIZE | 1520 (RX×4+TX=7.6KB) | **768** (MSS=700 最大帧 758B) | **3.76KB** |
|
||||
| iot_mqtt_srv.c | payload[] | 1400 | **800** (loop_data 最大~604B) | 0.6KB |
|
||||
| iot_mqtt_srv.h | IOT_MQTT_SEND_BUF_LEN | 1024 | **800** (影响 _iot_send_buf/resp/buf) | 0.22KB |
|
||||
| net_srv.c | MAX_MQTTBUF_LEN | 1024 | **800** (512 仍不够勿回改) | 0.22KB |
|
||||
|
||||
⚠ ETH_MAX_PACKET_SIZE 768 是贴着 MSS=700 的最小值:TCP 帧 758B ✓;
|
||||
若现场出现 >728B 数据的大 UDP 包会截断,保守可改 1024(省 2.48KB)。
|
||||
|
||||
### .map 分析 + 二轮瘦身(2026-08-17 晚,commit 后述)
|
||||
用户提供编译后 .map 解析结论:
|
||||
### .map 分析(用户提供编译产物)
|
||||
- **BLE 栈(libwchble.a)固定占用 RAM 低 16KB(0x20000000~0x20004000,链接脚本外)**——WCH CH32V20x 工程约定,不可裁剪
|
||||
- 用户 48KB:.data 1.6K + .bss 41.7K + .noinit 28B → 栈 4.7KB(实测稳定)
|
||||
- 用户 48KB:.data 1.6K + .bss 41.7K + .noinit 28B → 栈 4.7KB
|
||||
- .bss 大块:RECE_BUF_LEN 系列 ~10KB、Mem_Heap 7.2KB、MACRx/TxBuf 3.8KB、eth DMA 5.9KB、SPI_FLASH_BUF 4KB、ARP 1.2KB、iot buf 2KB
|
||||
|
||||
二轮瘦身(省 ~3.4KB,栈 4.7KB → ~6.3KB + 中断栈峰值降 1.8KB):
|
||||
|
||||
### 二轮瘦身(cb63c58)— 栈 4.7KB → ~6.3KB + 中断栈峰值 -1.8KB
|
||||
| 文件 | 项目 | 改动 | 收益 |
|
||||
|------|------|------|------|
|
||||
| net_config.h | RECE_BUF_LEN | MSS×2(1400)→**1024**(MSS=700 帧+头≈740B 够) | 5 数组省 ~2.6KB |
|
||||
| net_config.h | WCHNET_NUM_ARP_TABLE | 50→**16**(停车设备连接 IP 少) | ~0.8KB |
|
||||
| tcp_json_srv.c | tmp_buf[RECE_BUF_LEN] | 局部→**static**(中断上下文 1KB 栈数组) | 栈峰值 -1KB |
|
||||
| tcp_json_srv.c | frame[TCP_JSON_MAX_FRAME] | 局部→**static**(中断上下文 800B) | 栈峰值 -0.8KB |
|
||||
| net_config.h | WCHNET_NUM_ARP_TABLE | 50→**16** | ~0.8KB |
|
||||
| tcp_json_srv.c | tmp_buf[RECE_BUF_LEN]/frame[800] | 局部→**static**(中断上下文栈数组) | 栈峰值 -1.8KB |
|
||||
|
||||
### 遗留(根治)
|
||||
- [x] BLE 栈占用确认:16KB 固定(RAM 低区),不可裁剪
|
||||
- [ ] (可选)g_report_cfg 1400B 结构体审查(ReportConfig 含大数组?)
|
||||
- [ ] (可选)Mem_Heap_Memory 7.2KB 是 WCHNET 库内部堆,需查库配置是否可减
|
||||
- [ ] 快照区 3s 延后初始化保留(已确认非根因,作为启动早期 SPI 减压无害)
|
||||
|
||||
### 验证
|
||||
- [x] 实验D:跳过 load_cfg/output_cfg → 正常启动(WCHNET/TCP/BLE 全通)
|
||||
- [ ] 板级:本修复版(load_cfg 恢复+去打印)→ 正常启动 + 配置加载生效
|
||||
- [ ] 板级:不再循环重启
|
||||
### 板级验证(用户实测)
|
||||
- ✅ 一轮瘦身+打印恢复版:**无复位**,MQTT 连 159.75.137.141:1883、BLE 广播正常、dev_serial=DC045A49718F 配置加载生效
|
||||
- ✅ 二轮瘦身版(RECE_BUF_LEN 1024 + ARP 16 + static):**测试无异常重启**
|
||||
- [ ] 待回归:TCP JSON 命令交互(RECE_BUF_LEN 减小后接收缓冲 1024 ≥ MSS 帧 740B,理论无影响)
|
||||
- [ ] 待回归:快照区 3s 后初始化(`INIT: snap ok`)、断网快照落盘、BLE 0x28/0x29/0x2A
|
||||
|
||||
### 遗留
|
||||
- BOOT_CNT 打印保留(确认 .noinit 段生效 + 区分复位 vs 跑飞重启)
|
||||
- 快照区延后 3s 期间(0~3s)传感数据不落盘(按需求接受)
|
||||
- 电源裕量问题若确认:W25Q32 VCC 加 100nF+10uF 电容、SPI 走线远离电源
|
||||
- BOOT_CNT 打印保留(区分复位 vs 跑飞重启,诊断价值)
|
||||
- 快照区延后 3s 保留(非根因,但作为启动早期 SPI 减压无害)
|
||||
- (可选)g_report_cfg 1400B 结构体审查、WCHNET Mem_Heap 7.2KB 库配置——收益有限暂不动
|
||||
|
||||
---
|
||||
|
||||
## 2026-08-14 — 快照区功能恢复启用 + UART2 波特率澄清
|
||||
|
||||
|
||||
|
||||
### 背景
|
||||
printf 重入复位问题已确诊修复(2026-08-13,SPI 写无罪)。实验遗留的隔离代码收尾:快照区恢复启用、模拟写密度的 `sim_snap_spi` 实验桩移除。
|
||||
|
||||
|
||||
Reference in New Issue
Block a user