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
|
f1c9358aad
|
feat(vd960DBN): TCP/MQTT log_* 命令支持快照流 stream=snapshot (2026-08-18)
- snapshot.c/h: 新增 snap_rec_to_json() — SnapRec 64B → JSON (channels 对齐 0xC0, variation 3B 符号扩展, misc_type 全枚举)
- tcp_json_srv.c: handle_log_stat/query/clear 加 stream 解析 + snapshot 分支
- iot_mqtt_srv.c: log_stat/query/clear 加 stream 解析 + snapshot 分支
- 事件流 count=0 按上限处理 (与 BLE 对齐); 快照 QUERY count≤2, CLEAR ~45ms
- 新增 gcc 隔离单测 tests/test_snap_to_json.c 34 断言全过
- devlog V4.1
|
2026-08-18 09:01:22 +08:00 |
|
wangfq
|
3d4814bffe
|
fix(vd960DBN): init/clear 懒擦修复不断重启 — 34s 全量擦除超 IWDG 4s
现场: 烧录快照固件后 CH32V208 不断重启 + 串口乱码
根因: snap_init 首擦 751 扇区 ~34s (头在擦完才写→复位后仍全新→死循环);
snap_clear 34s / offlog_clear 2.8s 同类; 均超 IWDG 4s
修复(懒擦): init/clear 只擦写指针起点扇区 ~45ms, 其余由环形写切扇区
逻辑自动擦; clear 为逻辑清除 (count=0 旧数据不可读)
附带: usart_biz.c 非 0x7F 帧 %s 打印改 hex (Loop 数据当字符串=乱码源)
snapshot.h 线程模型注释修正 (lup_process_frame 实际在主循环 uart_srv)
测试: test_snapshot 9例(新增 lazy_erase) + offlog/ble_offlog 回归全过
|
2026-08-12 18:31:56 +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
|
d6174b9d3f
|
feat(vd960DBN): BLE 读取脱机日志 — OFFLOG_STAT/QUERY/CLEAR (0x25/0x26/0x27)
蓝牙通道补齐脱机日志读取 (此前仅 MQTT V1.06 / TCP JSON V1.02 有 log_* 命令):
- 3 条 BLE 命令, 语义对齐 MQTT log_stat/log_query/log_clear
- QUERY 直接传 32B OfflogEvt 原始结构 (二进制协议, 无需 JSON), 复用
idx = start_seq - seq_first 定位, 不新增 offlog API
- 缓冲扩容: MAX_BLE_TMP_BUF_LEN 100→132, 新增 MAX_BLE_DAT_BUF_LEN=132
(QUERY 响应 1+4x32B=129B), clear_buf_dbn_ble_all memset 同步
- 新协议文档 docs/DLD960_BLE协议.md V1.00 (帧格式+分包+命令+记录结构)
- 隔离测试 test_ble_offlog.c 嵌入源文件 3 case 真实文本, 7 例全过;
offlog 回归 8 例 ALL PASS
- devlog V4.0; README 协议矩阵补 BLE 行
|
2026-08-10 14:24:20 +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
|
90755bf465
|
feat(vd960DBN): offlog TIME_ANCHOR 严格用平台下发 unix_ts
offlog_time_anchor 原丢弃传参内部重取 dev_time_now() (毫秒级误差),
改为 offlog_evt_ts() 直接写入平台下发值, 锚点事件与平台 ts 严格一致。
新增单测 test_time_anchor_exact, 7 例 ALL PASS
|
2026-08-04 18:10:18 +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 |
|
wangfq
|
a457b81916
|
feat(iot_mqtt): loop_data 上报调度升级三档 — car_state 沿立即上报
原双速率下进/出车沿最坏等 300ms 门控。改为三档:
- 立即档: 任一通道 car_state 翻转沿 → 直通间隔门控立即发布
- 快速档: |variation|>阈值 → 300ms (不变)
- 空闲档: 配置 interval, 默认 60s (不变)
要点:
- car_edge 优先级最高; 快照仍在门控后刷新, 同沿只触发一次立即档
- 防洪泛天然有界: Loop 事件帧最快 150ms/帧 且 car_state 为防抖后状态
- 协议 §5.2 补上报节奏说明; tests/test_report_cadence.c 8 组全过
|
2026-07-15 16:56:21 +08:00 |
|
wangfq
|
3e28174b40
|
feat(mqtt): 设备时钟同步方案B — 平台经 report_config 下发 Unix ts (协议V1.05)
设备无RTC/SNTP, 原上行 ts=mstick()/1000(上电秒数)。方案B:
- net_srv.c 新增 dev_time_sync()/dev_time_now(): 门槛≥1600000000挡上电秒数,
已校准返回真Unix, 未校准退回上电秒数; 无符号相减处理mstick 49.7天回绕
- manage_mqtt_recv_message 从下行命令信封 ts 校准 (report_config主同步点)
- 全部上行 ts (14处命令响应+initialize+loop_data+event_report) 改 dev_time_now()
heartbeat uptime 字段保留 mstick()/1000 (运行时长非时间戳)
- 协议 V1.05 §2.3 时间同步 + report_config 兼任同步点职责
- tests/test_dev_time_sync.c 6组全过
平台侧配合: 收到 initialize 后下发 report_config 时 ts 填当前 Unix 时间
|
2026-07-15 15:25:44 +08:00 |
|
wangfq
|
e3eaa111fe
|
fix(mqtt): 修复 loop_data>512B 溢出发垃圾包致 broker RST 重连风暴 (现场P0)
根因(非平台推测的环形缓冲/event_report队列):
mqtt_publish 的 mqttBuf=512B < loop_data(4通道)604B
→ MQTTSerialize_publish 返回 -2 不写 buf
→ len 为 uint32_t, -2 变 42.9亿
→ WCHNET 把清零缓冲+越界相邻全局(temp_guide=report_config→report_c)
当 520B 垃圾包发出 → broker 见非法类型0x00 RST → 重连风暴
修复(net_srv.c):
- MAX_MQTTBUF_LEN 512→1024 (容纳 604B loop_data)
- mqtt_publish: len uint32→int + 守卫 if(len<=0)return (序列化失败绝不发残缓冲)
- keepalive 9→60 (报告建议, 9s过激)
event_report 协议违规修复(iot_mqtt_srv.c):
- 重连重发保持原 msg_id/ts (V1.04 §5.3-2), 不再作废换号致平台去重失效
验证: tests/test_mqtt_publish_overflow.c 复现旧垃圾包+验证守卫/大缓冲;
tests/test_event_report.c T8 断言重连同 msg_id. 均全过.
遗留: ts=上电秒数非Unix时间戳, 待定方案(设备无RTC/SNTP)
Refs: docs/incidents/2026-07-15-DC045A49718F-protocol-error.md
|
2026-07-15 14:58:03 +08:00 |
|
wangfq
|
4112b7cbbf
|
feat(iot_mqtt): 实现 event_report 平台必答+设备重发 (协议 V1.04); 时间单位统一 50ms
时间单位:
- 串口协议 V1.06 / TCP JSON 协议: 杂项时间量、事件 value 由 5ms 修正为
50ms, 对齐 Loop 固件 50ms tick 实现 (TMR15 5ms×10)
event_report (iot_mqtt_srv.c + net_srv.c):
- 沿检测双路汇聚: Step1 消费路径 + lup 回调覆盖 uart_srv 路径, 不漏帧
- 16 深环形队列, 事件仅 ACK(code=0) 后出队; 溢出丢最旧
- 5s 超时重发同 msg_id/原始 ts ×3 次, 耗尽挂起, 新事件/重连沿合并补报
- 帧消费提前至 READY/enable 之前: 断网期间事件入队, 重连补报
- 线圈断开期间屏蔽 car 沿; loop_restore value=本地计时/50
- msg_id 独立 uint32 计数 (g_iot_msg_id 为 uint8 混用会破坏去重窗口)
- net_srv.c ACK 路由: cmd=event_report 回显帧确认出队, 不回 unsupported
- gcc 隔离单测 8 组全过 (tests/test_event_report.c), 单包 6 条实测 317B
|
2026-07-15 12:27:22 +08:00 |
|