Commit Graph
8 Commits
Author SHA1 Message Date
wangfq 49736c341c feat(vd960DBN): Loop MCU 远程 OTA 固件实现 (MQTT V1.08, ROADMAP P1.4 ①)
先存后刷: MQTT 分片下载 → W25Qxx OTA 暂存区 (0x010000 512KB) → 全镜像 CRC32
复核 → 本地 0x9F ISP 透传刷写 Loop MCU (AT32F421)

- 新增 ota_srv.c/h: CRC32(ISO-HDLC 逐位零表)/OtaMeta 双备份(节流 4KB flush)/
  会话状态机(begin/data/end/abort/flash)/本地刷写状态机(非阻塞 tick: A5→A6→A7
  停等 ACK 1s×3)/安全窗口(有车拒绝 force 跳过)/失败 event_report ota_error
- iot_mqtt_srv.c: 6 个 ota_* 命令分发 + 会话静默(event_report 积压/offlog·快照
  落盘暂停, 结束补发) + IOT_EVT_OTA_ERROR + iot_any_car
- usart_biz.c: uart_srv OTA 分支 ACK 分发 (本地刷写→ota_flash_feed_ack, BLE 透传不变)
- peripheral_main.c: ota_init + ota_poll 挂主循环
- offlog: OTA_START 0x60/OTA_RESULT 0x61 审计事件
- tests/test_ota_srv.c: gcc 隔离单测 9 组全过 (mock NOR/UART2/时钟, 嵌入真实实现)
  抓到 2 个真 bug: ①A7 序号未递减(bootloader 等不到末包) ②重发时 retry 清零(超时永不失败)
- 语法检查: ota_srv/iot_mqtt_srv/usart_biz/offlog 0 新增错误 (基线 interrupt 假阳性除外)
- devlog 置顶条目 + 待板上验证清单
2026-08-20 12:09:13 +08:00
wangfq 5a1893cd1c feat(vd960DBN)+fix(DBNMQTTool): log_query 改 hex 原始字节上报 (2026-08-18)
背景: MQTT 快照流实测 MQTTSerialize_publish failed — JSON 化快照记录 ~810B/条 超 800B 发送缓冲
方案(用户拍板): 对齐 BLE 通道, 原始字节 hex 上报

固件 (V4.3):
- offlog.c/h: 新增 offlog_evt_to_hex() (32B→64 hex)
- snapshot.c/h: 新增 snap_rec_to_hex() (64B→128 hex); 删 SNAP_MAX_QUERY_JSON, 恢复 count=2
- tcp_json_srv.c / iot_mqtt_srv.c: log_query 改 {"seq":N,"hex":"..."}; SEND_BUF 保持 800
- 2 条快照 hex 响应 406B < 800B

文档: TCP JSON V1.03 / MQTT V1.07 §4.17 records 改 hex + 解析表引用 BLE §6.4/§7

工具: parse_offlog_hex/parse_snap_hex/offlog_payload_desc + hex 展示; 验证: gcc 9 断言 + 工具解析全过 + offscreen UI
2026-08-18 14:04:26 +08:00
wangfq eadc67584f fix(vd960DBN): 复位原因位定义错位修正 — RST_REASON=0x08000000=PORRSTF
现场: RST_REASON 打印 0x08000000, 对照 WCH ch32v20x.h 发现
offlog.h 位定义整体错位 (IWDG=bit31实为bit29, SFT=bit24实为bit28,
POR=bit25实为bit27, LPWR=bit29实为bit31)
结论: 0x08000000=PORRSTF=上电/掉电复位 → 电源跌落方向 (SPI擦除电流脉冲?)
修正:
- offlog.h 位定义对齐 WCH 库, 新增 OFFLOG_RST_RMVF=bit24
- peripheral_main.c RMVF 清除改 bit24 (原写 bit27=PORRSTF 只读位,
  复位标志从未清除, 历史累积污染诊断)
- 协议文档 boot 事件位解析同步
测试回归全过
2026-08-12 18:58:16 +08:00
wangfq 92887a3d92 feat(vd960DBN): 传感快照区落地 snapshot.c + BLE SNAP_STAT/QUERY/CLEAR
- snapshot.h/c: 64B 定长 SnapRec (头部16B + 4x12B 0xC0线圈数据原样)
  环形分区独立于事件日志, 快照区 = 总容量 - 固定区576KB - 事件区
- 线程模型: USART2 ISR 只打包+RAM暂存(8深满丢新), 主循环 snap_flush 落盘
  (iot_sensor_ingest 在中断上下文, SPI 45ms 擦除严禁进中断)
- dbn_ble_srv: SNAP_STAT(0x28)/SNAP_QUERY(0x29)/SNAP_CLEAR(0x2A)
  QUERY 上限 2 条 (64x2+2=130B, ODR 教训防御)
- iot_mqtt_srv: ingest 挂 snap_enqueue, publish_sensor 挂 snap_flush
  (放在 READY 检查前, 断网照常落盘)
- peripheral_main: offlog_init 后加 snap_init
- 清空审计: 写事件流 log_clear payload[0]=2
- 测试: test_snapshot.c 8 例全过, offlog/ble_offlog 回归全过
- 文档: DLD960_BLE协议 V1.02 + ROADMAP P1.2 状态 + devlog
2026-08-12 17:40:14 +08:00
wangfq a8120cc852 feat(vd960DBN): 事件日志区动态分区 — JEDEC ID 选档 (ROADMAP 落地)
- offlog.h: OfflogPart 运行时分区表 + g_offlog_part; AREA_BASE 改 0x090000
  (参数64KB+OTA512KB); 容量宏展开为运行时值(主体零改动)
- offlog.c: offlog_part_detect() 读 JEDEC ID → 事件区容量
  W25Q32=512KB/16256条, Q64=1MB/32640, Q128=2MB/65408, Q256=4MB/130944
- storage.c/h: SPI_Flash_ReadJEDEC_ID() (0x9F, 校验 EF 40)
- 旧固件事件区 0x010000 自动废弃(新地址无 magic → 重建), 预期行为
- 测试: mock JEDEC=0x16 + g_offlog_part, 15 例全过
- 文档: BLE/MQTT/TCP 协议 capacity 8064→动态, 交互示例, devlog
2026-08-12 16:46:19 +08:00
wangfq 1a01316c7f feat(vd960DBN): offlog 协议导出命令分发 — log_stat/log_query/log_clear 落地
协议先行 (08893d5, MQTT V1.06 + TCP JSON V1.02) 的固件侧实现:
- offlog 新增导出 API: enabled/seq_last/type_str/evt_to_json
  (seq_first=seq_last-count+1, idx=start_seq-seq_first, count≤4)
- MQTT iot_handle_publish 三分支: log_stat/log_query/log_clear
  (log_query 响应 static buf 防大栈; log_clear 阻塞~2.8s 主循环可接受)
- TCP JSON 三 handler + cmd 表 (需鉴权)
- 单测新增 test_export_json (8 例全过): boot rst 大端/coil sub/evt_retry/data:null/seq 公式
- devlog V3.9
2026-08-05 08:53:18 +08:00
wangfq 5155219c92 fix(vd960DBN): 修复 offlog 编译错误 — 声明补齐 + RCC 宏移入公共头
MRS 编译报错:
1. offlog.c: SPI_Flash_Erase_Sector 隐式声明 → storage.h 补声明
2. peripheral_main.c: OFFLOG_RCC_RSTSCKR 未声明 → RCC 宏从 offlog.c
   移到 offlog.h (peripheral_main.c 只 include offlog.h)
3. offlog.c 删除本地重复 RCC 宏定义

单测重跑 ALL PASS
2026-08-04 16:51:53 +08:00
wangfq ac3fb512d5 feat(vd960DBN): 脱机事件日志系统 (W25Q32 环形) — 解决重复上线取证
背景: 设备挂平台测试出现重复上线(现场未断电), 无本地日志无法区分
设备真复位 vs MQTT 断连重连。iot_handle_suback 每次重连都发
initialize 是重复上线的直接证据, 日志需能区分二者。

实现 (V3.6, ROADMAP P1.2 事件流先行):
- offlog.c/h: W25Q32 256KB 环形事件日志 (头扇区+63数据扇区, 8064条)
  - 32B 定长记录: magic/type/len/flags/seq/ts_ms/unix_ts/boot_seq/payload[12]
  - 8 类事件: BOOT(复位原因)/IOT_CONNECT/READY/DISCONN/RECONN/
    EVT_RETRY/GIVEUP/COIL/TIME_ANCHOR/LOG_CLEAR
  - 掉电恢复: 头扇区写指针锚点 + 上电 seq 连续性扫描
  - 编译期断言防 32B padding 回归
- 插桩 (全部主循环上下文, socket 中断内不写 SPI):
  - main(): offlog_init + RCC_RSTSCKR 复位原因采集/清除
  - iot_mqtt_poll(): MQTT 状态沿检测 (CONNECT/READY/DISCONN)
  - 重连退避/TCP超时/CONNACK拒绝: RECONN/DISCONN(4)/(3)
  - iot_evt_process/enqueue: EVT_RETRY/GIVEUP/COIL
  - net_srv.c dev_time_sync: TIME_ANCHOR 时钟同步锚点
- tests/test_offlog.c: gcc 隔离单测 6 例 (mock W25Q32 NOR 语义)

关键坑: ①中断内写SPI阻塞 ②结构体36B padding致环形错乱
③扇区级覆盖粒度count扣减语义 (均单测抓出)

待办: P1.3 导出命令(log_query/stat/clear) + 快照流 + 复位原因板上验证
2026-08-04 15:04:12 +08:00