wangfq
|
6c6ddf8b0f
|
docs(ROADMAP): 容量预算重算 — 事件日志翻倍后快照 4.8万条基准
- W25Q32: 最坏300ms压满 ~4.0h / 繁忙 ~1.5天 / 一般 ~16.7天 (原4.4h/1.5天/18天)
- 新增各芯片快照保留时长对比表 (Q32~Q256, 同落盘节奏)
- 注明事件日志独立 512KB→4MB 不受快照覆盖影响
|
2026-08-12 16:29:54 +08:00 |
|
wangfq
|
667b5376ab
|
docs(ROADMAP): 事件日志区容量整体翻倍 — W25Q32 512KB 起类推
- W25Q32: 256KB→512KB (~16000条), 快照区 ~3.19MB→~2.94MB
- W25Q64: 512KB→1MB, W25Q128: 1MB→2MB, W25Q256: 2MB→4MB (类推)
- 传感快照区 = 总容量 − 参数64KB − OTA512KB − 日志区
- 容量预算基准同步: 日志512KB / 快照~2.94MB ≈ 4.8万条@64B
|
2026-08-12 16:27:05 +08:00 |
|
wangfq
|
62c6133632
|
docs(ROADMAP): 移除 W25Q80 支持 — 最小可部署配置定为 W25Q32
- W25Q80(1MB) 扣除参数64KB+OTA512KB后仅剩448KB, 快照区太紧张
- 容量映射表保留 W25Q32/Q64/Q128/Q256; 事件日志等比 256KB→2MB
- 最小配置 = W25Q32(4MB)
|
2026-08-12 16:20:37 +08:00 |
|
wangfq
|
d7f9c29f25
|
docs(ROADMAP): 脱机日志分区规划调整 — OTA暂存提前 + 按存储类型动态容量
- 分区顺序: 参数区 → OTA镜像暂存区 → 事件日志区 → 传感快照区
- 参数区(64KB)/OTA暂存(512KB) 固定; 事件日志+传感快照 按 JEDEC ID 动态
- 新增 W25Q80/Q32/Q64/Q128/Q256 容量映射表 (EF 40 14/16/17/18/19)
- 事件日志区等比翻倍 128KB→2MB, 快照吃剩余; W25Q80(1MB) 为最小配置
- 容量预算段注明以 W25Q32 为基准, 其他芯片等比缩放
|
2026-08-12 16:18:17 +08:00 |
|
wangfq
|
193455e629
|
docs(vd960DBN): devlog 记录第二分包根因 — 响应缓冲越界踩踏 g_notify_buftemp
|
2026-08-12 14:51:47 +08:00 |
|
wangfq
|
e8b7c6f70c
|
fix(vd960DBN): BLE 响应缓冲越界防御 — 根因: MAX_BLE_DAT_BUF_LEN 宏不一致(ODR)
根因链 (14:46 日志 + .map 铁证):
- .map: g_buf_ble_response = 107B (7 + dat[100]) -> 编译时 MAX_BLE_DAT_BUF_LEN=100
- 但 QUERY 响应 130B 写入 dat[0..129] -> 越界 30B
- 越界踩中相邻 g_notify_buftemp.flag/len (0x20007BDC)
- 第二分包填充后被物理抹除 (无 CLR_NTF = 非 clear_ble_notify_buf 干的)
修复 (兼容新旧宏, 永不越界):
- QUERY: _req_count 按 MAX_BLE_TMP_BUF_LEN 动态限制 (100->3条/132->4条)
- set_response_buf: dat_len 截断到 MAX_BLE_DAT_BUF_LEN
- 验证: 旧宏100 下 3条=98B 分包[93,17] 全合规
|
2026-08-12 14:51:21 +08:00 |
|
wangfq
|
67734d3b9a
|
debug(vd960DBN): clear_ble_notify_buf 抓现行 — buf指针 + 调用者返回地址
- 沿监控证实: 第二包填充成功 (flag=1 len=49 temp=1) 后被 clear_ble_notify_buf 清空
(flag=0 len=0), 但无 BLE send 打印 = 不是 performPeriodicTask 发送路径
- clear_ble_notify_buf 入口: 有货被清时打印 buf 指针 + __builtin_return_address(0)
- 若 buf 指针 != g_notify_buftemp → 指针/内存布局问题; ret 对 .map 定位调用者
|
2026-08-12 14:41:44 +08:00 |
|
wangfq
|
6582b93938
|
debug(vd960DBN): notify flag / ntf_temp 变化沿监控 — 抓第二包消失瞬间
- ret=00008122 对 .map = set_response_to_notify 内部 (0x7FEC+0x136)
→ CLEAR busy 是第二包填充完成的正常清空, 队列清空不是问题!
- 真正问题: 第二包填充后 notify flag 从 1 被清 0, g_flag_notify_temp=0
→ 下一个 TMOS 周期不发送 (无 BLE send len:49)
- 加 BLE ntf flag x->y (len= temp=) 沿监控, 只在变化时打印
|
2026-08-12 14:28:41 +08:00 |
|
wangfq
|
7a08e083d6
|
debug(vd960DBN): clear_buf_dbn_ble 抓现行 — 有货被清时打印调用者返回地址
- 已排除 simpleProfile_Notify (发送后 resp=1 队列完好)
- 队列在 hex 打印后 ~20ms 被清空 (amt/seq/off 全0 = clear_buf_dbn_ble 效果)
- clear_buf_dbn_ble 入口: 仅当 buf->flag=1 (有货被清) 时打印 + __builtin_return_address(0)
- 烧录后 ret=地址 对照 .map 文件直接定位调用者
|
2026-08-12 14:14:39 +08:00 |
|
wangfq
|
66f156105c
|
debug(vd960DBN): peripheralChar4Notify 内 resp 队列状态实验打印
- 上一轮日志: BLE send 时 resp=1 amt=2 seq=1 off=87 (队列正常),
但 peripheralChar4Notify 执行后下一周期队列已空
- 锁定嫌疑: simpleProfile_Notify 库函数内部是否清了 g_buf_ble_response
- N4 enter / after simpleProfile_Notify 各打印一次 resp 状态
|
2026-08-12 14:08:34 +08:00 |
|
wangfq
|
60576b2b33
|
debug(vd960DBN): 抓现行打印 — 发送前队列状态 + resp flag 变化沿
- 心跳证实: 第一包发出后 resp=0 amt=0, 队列已被意外清空 (第二包不存在)
- poll_dbn_ble 尾部: resp flag 变化沿打印 (0->1/1->0 各一次, 不刷屏)
- performPeriodicTask: 发送前打印 len + resp 队列状态
- 烧录后一次看清 谁在何时清了 g_buf_ble_response
|
2026-08-12 14:02:23 +08:00 |
|
wangfq
|
ef3316f2b3
|
docs(vd960DBN): BLE 日志查询交互过程文档 + 协议 V1.01 动态分包 + 周期心跳
- 新增 docs/DLD960_BLE日志查询交互.md: 0x25/0x26/0x27 完整交互示例
(真实日志逐字节解析, 分包规则, 第二分包未发问题记录)
- DLD960_BLE协议.md V1.01: 分包上限改为随协商 MTU 动态 (min(MTU-9,94))
- peripheral.c: performPeriodicTask 加 500ms 心跳打印 (确认 TMOS 周期存活
+ resp 队列状态, 定位第二分包为何不续传)
|
2026-08-12 13:51:32 +08:00 |
|
wangfq
|
070db9f383
|
debug(vd960DBN): performPeriodicTask 拉包失败打印 resp 状态 + 注释闭合
- 第二分包未进发送函数, 加条件打印 (仅当队列有货但拉包返回0时)
BLE pull FAIL: resp flag/amt/seq/off 一烧录即知第二包断在哪
- 补 ble_notify_chunk_max 注释块闭合 */
|
2026-08-12 11:55:44 +08:00 |
|
wangfq
|
5eef0756f2
|
debug(vd960DBN): BLE notify 发送数据 hex 打印 — 排查第二分包
- peripheralChar4Notify OK 分支: 打印 len/MTU + 整包 hex (对齐收包打印风格)
- 烧录后设备日志可直接比对发送帧与小程序收到帧
|
2026-08-12 11:45:06 +08:00 |
|
wangfq
|
bcf797285b
|
fix(vd960DBN): BLE 第二分包丢失 — performPeriodicTask 主动拉包 + 发送日志
- 现场: 第一包 93B 正常收到, 第二包 49B 永远收不到 (两包间隔 50ms)
- 根因: 分包续传依赖 poll_dbn_ble 下一轮收包/主循环轮转填充, 与 TMOS 周期交错
- peripheral.c: performPeriodicTask 发完当前包后主动 set_response_to_notify 拉下一分片,
与收包事件解耦; peripheralChar4Notify 增加 BLE notify OK/FAIL 打印 (发送失败不再静默)
- 隔离测试: 仅靠周期事件驱动, MTU=96 3 周期发出 93B+49B, 重组 130B 一致
|
2026-08-12 11:35:21 +08:00 |
|
wangfq
|
62f7de0ca2
|
fix(vd960DBN): BLE 分包粒度动态化 — 修复 offlog_query Too large noti 丢包
- 根因: MAX_BLE_DAT_RESPONSE_LEN=96 写死, MTU 协商 96 后整包 102B > MTU-3=93
peripheralChar4Notify 直接 return 丢第一包, 小程序重组不完整
- peripheral.c: 新增 peripheral_get_mtu() getter
- dbn_ble_srv.c: ble_notify_chunk_max() 按 min(MTU-9,94) 动态分包
4 处 MAX_BLE_DAT_RESPONSE_LEN 统一替换 (set_response_buf/to_notify/iot_net/iot_topic)
- 消除 BLE_Notify_Buf.buf[100] 写 102B 越界 2B 隐患
- 隔离 C 测试 MTU=23/96/185/517 四组全过, 重组 130B 逐字节一致
|
2026-08-12 08:30:44 +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
|
5ebd8247f0
|
feat(DBNMQTTool): 脱机事件日志命令支持 — log_stat/log_query/log_clear (MQTT V1.06)
- protocol.py: CMD_LOG_* 常量 + LOG_COMMANDS + data_log_query 边界钳制
(start_seq>=1, count 1~4) + LOG_EVENT_TYPE_DESC 事件类型中文描述
- main.py: 参数配置 Tab 新增脱机日志面板 (统计/拉取/清除 + 显示区)
- _on_message 响应分发: log_stat 统计展示, log_query 记录格式化
(unix_ts 真实时间 / boot+ts_ms 未同步), log_clear 二次确认
- devlog 追加
|
2026-08-05 09:06:11 +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
|
08893d5134
|
docs(protocol): 脱机事件日志命令规范 — MQTT V1.06 + TCP JSON V1.02
新增 3 命令 (两协议同步):
- log_stat: 日志统计/分页定位 (stream/boot_seq/count/capacity/seq_first/seq_last)
- log_query: 按全局序号分页拉取, count≤4 (受 500B 发布限制)
- log_clear: 清除+审计留痕 (log_clear 事件不可清除)
日志时间戳语义 (§2.3 补充): 每条记录 ts_ms(相对) + unix_ts(已同步,
0=未同步), 锚点回算规则; 10 类事件类型表 (boot/iot_*/evt_*/coil/
time_anchor/log_clear) 带 data 字段解析。
同步: README/CHANGELOG/产品手册/技术规格书 协议矩阵
(MQTT V1.05→V1.06, TCP JSON V1.01→V1.02)
注: 固件命令分发 (log_stat/log_query/log_clear 处理) 待 P1.3 实现,
本文档为协议先行
|
2026-08-04 18:34:31 +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
|
2b1e888a73
|
refactor(vd960DBN): tcp_json_srv data_json[2048] 宏化 → TCP_JSON_DATA_BUF_LEN(1024)
三处 char data_json[2048] (sensor_report×2 + loop_param_query×1)
改用头文件宏 TCP_JSON_DATA_BUF_LEN, 默认 1024。
容量核验: format_sensor_json 4通道~660B / format_loop_param_json~920B
均 < 1024, format 函数有 snprintf 溢出保护; 最终帧受 MAX_FRAME=800 截断。
附带: 栈上缓冲 2048→1024 每处省 1KB
|
2026-08-04 17:06:29 +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 |
|
wangfq
|
a5ac54a2bf
|
docs(vd960DBN): 开发日志 V3.5 — 保活精简 + SocketSend 故障恢复
|
2026-07-23 18:36:40 +08:00 |
|
wangfq
|
98d9b99cf6
|
fix(vd960DBN): 断连重连时重建 TCP socket (不是复用已 close 的)
root cause 1: 3次失败断连后, iot_connect_broker() 只设
g_iot_socket=SocketId_TCP, 但 WCHNET_SocketClose 后
socket 已销毁, 没有重建 → TCP connect 一直超时
root cause 2: old socket close 未完成就立即重连,
WCHNET_SocketCreat 可能失败
fix:
1. iot_connect_broker() 先调 WCHNET_CreateTcpMqttSocket()
真正 create + connect
2. 3次失败后加 3s 延迟再重连, 给 WCHNET 清理时间
|
2026-07-23 17:41:41 +08:00 |
|
wangfq
|
7c0de6c566
|
fix(vd960DBN): SocketSend 连续3次失败 → 主动断连重连
root cause: WCHNET_SocketSend 返回 ret=0x11(sent=0) 后
TCP超时要等~2分钟才触发 SINT_STAT_TIM_OUT, 期间所有
loop_data/event_report 全丢, 平台收不到任何数据
fix: iot_mqtt_send 追踪连续失败计数, 3次→强制 close socket
+ g_iot_state=DISCONNECTED, 触发 iot_mqtt_poll 重连
(成功一次就清零, 新连接也清零)
|
2026-07-23 17:14:49 +08:00 |
|
wangfq
|
29d1f6a783
|
refactor(vd960DBN): 去掉 heartbeat JSON 上报, MQTT PINGREQ 已保活
heartbeat 是单向设备上报, 平台不回复; MQTT PINGREQ/PINGRESP
已是双向保活。loop_data 按 g_report_cfg.interval 上报即可。
删除: iot_send_heartbeat() 函数 (省 ~40行 + BSS payload[512]→栈)
|
2026-07-23 15:28:10 +08:00 |
|
wangfq
|
bdc2720d96
|
docs(vd960DBN): 开发日志 — V3.4 今日MQTT栈重构完整记录
|
2026-07-23 15:22:29 +08:00 |
|
wangfq
|
8f1bbf75f8
|
refactor(vd960DBN): 看门狗精简 — 去掉平台响应超时, 只保留硬件 IWDG
heartbeat 是单向设备上报, 平台不回复; 用 '3×心跳无平台回复→重启'
逻辑不成立。保活依赖三层已有机制:
MQTT层: PINGREQ/PINGRESP (60s) → broker不回 → TCP超时
TCP层: KeepAlive → WCHNET SINT_STAT_DISCONNECT/TIMEOUT
硬件层: IWDG (4s) → 主循环卡死 → 硬件复位
|
2026-07-23 15:21:59 +08:00 |
|
wangfq
|
127fed4b07
|
feat(vd960DBN): 硬件 IWDG 看门狗 + 平台响应超时重启
设计:
1. 硬件 IWDG: LSI≈40kHz, Prescaler=256, Reload=625 → ~4s 超时
主循环 iot_mqtt_poll() 每轮喂狗, 防死循环/硬故障
2. 平台响应看门狗: 3×心跳周期(180s)内无平台回复 → NVIC_SystemReset
_iot_last_recv_ms 刷新点:
- iot_handle_publish() — 收到平台任意 PUBLISH 命令
- iot_evt_handle_ack() — event_report 的 ACK
- iot_handle_suback() — 刚连上 READY 时初始化计时
3. 仅在 IOT_STATE_READY 时检查 (未连上不触发)
|
2026-07-23 14:49:07 +08:00 |
|
wangfq
|
199cb5d23f
|
config: WCHNET_TCP_MSS 576→700, TCP_JSON_MAX_FRAME 4096→800
- WCHNET_TCP_MSS=700: 减少 TCP 分段, 配合 iot_mqtt_send 循环重试
→ RECE_BUF_LEN 自动扩至 1400 (原 1152)
- TCP_JSON_MAX_FRAME=800: 匹配实际 JSON 帧大小
|
2026-07-23 14:30:47 +08:00 |
|
wangfq
|
9e830639d3
|
fix(vd960DBN): iot_mqtt_send 循环重试防 WCHNET 部分发送致 _raw
root cause: WCHNET_SocketSend 返回部分发送(520/607B),
剩余字节留在TCP发送队列, 与下一个MQTT包拼接,
broker收到乱码 → _raw + RST断连
fix: iot_mqtt_send 加 while 循环, 指针偏移重试直到全部发出;
最多10次重试, slen==0或错误时返回-1
|
2026-07-23 13:57:54 +08:00 |
|
wangfq
|
a9c36e4c9d
|
fix(vd960DBN): 心跳 msg_id 双递增修复 + %d→%lu
root cause: iot_send_heartbeat 先 ++g_iot_msg_id(JSON) 再
iot_mqtt_publish 内部 ++g_iot_msg_id(MQTT pktid) → 跳号
fix: 心跳改用 g_iot_msg_id + 1 (与其他发布对齐)
|
2026-07-23 13:43:13 +08:00 |
|
wangfq
|
67976eca8e
|
fix(vd960DBN): IoT MQTT 命令处理完善 — report_config + event_report ACK + initialize 走 IoT 路径
issues:
1. iot_handle_suback 调 dev_initialize_pub() → 旧 mqttBuf 路径, 与 IoT 栈混淆
2. report_config 命令无人处理 → 平台收到 code=4 unsupported
3. event_report ACK (code=0) 被当 unsupported command → 重发闭环断裂
fix:
1. 新增 iot_send_initialize() — IoT 路径, 用 iot_mqtt_publish
2. 新增 report_config 处理 — 解析 enable/interval/once/env_eval/sensor_type
3. 新增 event_report ACK 识别 — code=0 → iot_evt_handle_ack; ACK 不回复
|
2026-07-23 12:24:09 +08:00 |
|
wangfq
|
a577537c38
|
fix(vd960DBN): 修复 WCHNET_SocketSend 参数类型不匹配致栈破坏 hard fault
root cause: iot_mqtt_send() 声明 uint16_t slen = len,
传给 WCHNET_SocketSend(..., uint32_t *len) 时取址 &slen。
WCHNET 写 4 字节返回值到 2 字节栈变量 → 破坏相邻栈内容
(返回地址/帧指针) → 函数返回时 hard fault 重启
fix: slen 改为 uint32_t
|
2026-07-23 11:52:58 +08:00 |
|
wangfq
|
32f0edb875
|
fix(vd960DBN): MQTT CONNECT 改回中断上下文发送, 消除 SocketSend hard fault
root cause: WCHNET SocketSend 在中断上下文外调用会 hard fault。
旧代码 mqtt_connect() 在 WCHNET_HandleSockInt CONNECT 中断里直接调;
v4 改成了延后到主循环 iot_mqtt_poll() 里发 → hard fault
fix: iot_mqtt_handle_sock_int 的 CONNECT 分支直接调用
iot_mqtt_send_connect() (对齐旧代码行为), 不再延后到 poll
|
2026-07-23 11:47:27 +08:00 |
|
wangfq
|
9521a5e667
|
fix(vd960DBN): 修复 SocketSend 后重启 — RecvBuf 用错 + 栈溢出
root cause:
1. iot_mqtt_handle_sock_int 的 CONNECT 处理调了
WCHNET_ModifyRecvBuf(_iot_wchnet_buf), 覆盖了 WCHNET 原生的
SocketRecvBuf, 导致后续 SocketSend 时 DMA 访问非法内存 → hard fault
2. uint8_t tmp[RECE_BUF_LEN](1152B) 在中断栈上, 叠加调用链
可能撑爆 2KB 栈
fix:
1. net_srv.c WCHNET_HandleSockInt: 保留 SocketRecvBuf + KeepLive,
其余事件委托给 iot_mqtt_handle_sock_int
2. iot_mqtt_handle_sock_int: 移除 ModifyRecvBuf(已在 wrapper 处理)
3. tmp[1152] 改为 static (移到 BSS, 省 1152B 栈)
|
2026-07-23 11:39:52 +08:00 |
|
wangfq
|
3d017ccca9
|
fix(vd960DBN): IoT MQTT 栈独立接管 socket 事件, 消除双 CONNECT 致频繁 initialize
root cause: WCHNET_HandleSockInt 在 iot_enable=1 时仍走旧 MQTT 代码:
CONNECT → mqtt_connect() ← 发 MQTT CONNECT #1
iot_mqtt_poll() → send_connect() ← 发 MQTT CONNECT #2 (同一socket)
broker 见双 CONNECT → 协议违规踢线 → 4s 后重连 → 循环
RECV → mqtt_data_manage() ← 旧代码收 CONNACK
→ dev_initialize_pub() ← initialize msg_id=1, 强设 g_iot_state=READY
fix:
1. net_srv.c WCHNET_HandleSockInt: iot_enable 时直接调 iot_mqtt_handle_sock_int
2. peripheral_main.c: poll_mqtt() → iot_mqtt_poll() (IoT 自有 PINGREQ)
BSS savings: -1024B (data_json eliminated), send buffer 隔离 (v3)
|
2026-07-23 11:25:52 +08:00 |
|
wangfq
|
086dbc6d7c
|
fix(vd960DBN): loop_data 改用 iot_mqtt_publish 发送, 缓冲隔离防 _raw 异常 v3
- root cause (v3): event_report 的 mqtt_publish → MQTTSerialize_publish(mqttBuf)
写入的 MQTT 二进制泄漏到 loop_data 的 payload 缓冲, 产生 _raw 异常
- fix: loop_data 改用 iot_mqtt_publish() 发送, 其内部 buf[1024] 与
全局 mqttBuf[1024] 物理隔离, event_report 和 loop_data 不再争用同一缓冲
- 同时: 消灭 data_json[1024] (v1), coil_count 硬限 (v1),
msg_id 改预读避免 iot_mqtt_publish 内部 ++ 导致跳号
- note: iot_send_heartbeat 有同样 msg_id 双 ++ 问题, 待修
|
2026-07-23 11:04:17 +08:00 |
|
wangfq
|
e11a80c859
|
fix(vd960DBN): 消灭 data_json[1024] 中间缓冲, 防 BSS 重叠致 MQTT 上报 _raw 异常
- root cause: data_json[1024] + payload[1400] BSS 合计 2424B,
叠加 iot_mqtt_srv.c 其他缓冲 (~9KB total), 在 48KB RAM 上
与 mqttBuf[1024] 重叠, event_report 的 MQTT 二进制
泄漏到 loop_data payload
- fix: 直接在 payload 构建完整 JSON, 省 1024B BSS
- defense: coil_count > 4 硬限, 防 0xC0 坏帧溢出
- JSON 输出格式不变
- also: set_response_tran_to_notify 加返回值
- also: uart_srv BLE 通知逻辑重构
|
2026-07-23 09:26:18 +08:00 |
|
wangfq
|
95a1d2b5d2
|
docs(roadmap): 板载W25Q32(4MB)确认, 分区与容量预算按实际重算
- 分区: 参数64KB / 事件流256KB(~8000条) / OTA暂存512KB / 快照区~3.2MB
- 快照容量三场景预算: 快档压满~4.4h / 繁忙车道~1.5天 / 一般车道~18天
- 补充延长保留的两个手段: 落盘与上报解耦 / 沿事件预触发环形
- 移除'W25Q型号确认'前置项
|
2026-07-17 19:04:28 +08:00 |
|
wangfq
|
70e44e6241
|
docs(roadmap): 补充脱机日志子系统 + 日志导出管理 + 远程OTA路线细化
- P1.2 脱机日志: W25Qxx 分区规划(参数/事件流/快照流/OTA暂存),
事件流必录清单, 快照流同频落盘挂 iot_sensor_ingest 同源出口,
无RTC时间戳方案(boot_seq+mstick+时钟锚点)
- P1.3 导出与管理: MQTT断网补报/命令分页拉取/BLE小程序读取
三通道, log_stat/log_clear(鉴权+审计自记录)
- P1.4 远程OTA: 先走现网MQTT+复用ISP透传底层(与BLE OTA同构);
Loop先存后刷+断点续传+回滚, 继电器安全底线;
DBN自身远程OTA三路线比选(过渡态=仍走BLE最稳妥)
- 风险表新增: 无RTC时间戳、日志写与总线争用
|
2026-07-17 18:57:13 +08:00 |
|
wangfq
|
ea29433633
|
docs: 新增 ROADMAP — V1.0.0 之后的开发计划 (P0稳固→P1上云→P2算法→P3会车)
- P0 (v1.1.0): BLE透传重构收尾(0xC0三消费方真值表) + TODO清剿
(loop_ok硬编码/MQTT接收溢出防护) + 工装回归清单
- P1 (v1.2.x): edc_server消费契约(先落库后ACK)、流量API、
远程OTA方案评审、4G通道预研
- P2 (v2.0.0): 抗变频器干扰(先现场采CAPVD取证)、双线圈测速+
车型粗分类、半截车双峰识别、方向判别
- P3 (v2.x): 会车控制 — 业务只认event_report、异常分支先行、
纯平台/纯单机/混合三方案对比
|
2026-07-17 18:13:29 +08:00 |
|
wangfq
|
579eeecb23
|
docs: 校准通信接口表述 — DLD960 无 RS485 接口
- 对外通信 = 网口(TCP JSON/MQTT) + 蓝牙(小程序/OTA) + 扩展TTL串口(预留4G上云, RFU)
- 内部双 MCU 经 UART TTL 互联 (0x7F @192000)
- 修正范围: README/CHANGELOG/技术规格书/产品手册/硬件资源文档概述
- acceptance-standard 中 RS-485 为通用验收检查项, 保留
|
2026-07-16 16:39:02 +08:00 |
|
wangfq
|
d61ff830aa
|
fix(vd960DBN): BUFF_STACK_SIZE 512→64 对齐 Loop 侧串口帧缓冲
- 串口帧缓冲装的是 Loop↔DBN 的 0x7F 私有协议帧, 与 Loop 侧发送缓冲(64)同源
- 当前最大帧 0x0C 多线圈上报实测 56B (Len=51), 64 留 8B 余量, 512 严重浪费
- g_pkg_uart_1/2 各省 448B, 合计回收 ~896B SRAM
- 顺带删除零引用死结构体 USART_DMA_UNIT + RX_BUFFER_LEN 宏
|
2026-07-16 14:52:16 +08:00 |
|
wangfq
|
c0bdcd956d
|
docs: 新增产品手册 + 技术规格书 (V1.00, 配套整机 V1.0.0)
- 产品手册: 接口/指示灯/线圈施工要求/快速上手/参数配置/故障排查
- 技术规格书: 双MCU架构/检测规格/灵敏度阈值表(SensTable换算)/算法机制/协议矩阵/配套要求
- README: 文档索引挂接产品文档
|
2026-07-16 10:31:10 +08:00 |
|
wangfq
|
130054658a
|
docs: 整理发布文档 — 重写根 README + 新增 CHANGELOG (V1.0.0)
- README: 双MCU架构图、子项目/固件版本表、协议版本矩阵、文档索引、发布流程
- CHANGELOG: V1.0.0 首发说明 — Loop/DBN 配套版本矩阵、双侧功能汇总、已知约束
|
2026-07-16 10:02:44 +08:00 |
|
wangfq
|
6284bca0cb
|
fix(iot_mqtt): loop_data 陈旧快照 — 事件与缓存统一帧摄取 (同源)
现场: 长车离开后 event_report 正确, 但 loop_data 连续 34s/100+ 条
iscar:true 陈旧快照, 且冻结 diff=517 锁死 fast_mode 300ms 刷屏。
根因: 0xC0 帧两条竞争消费路径数据源分裂 —
uart_srv→lup回调只喂事件不更新 _cached_sr;
Step1 直读才更新缓存, 但赢得竞争概率实测 ~2%
→ 事件每帧必达而快照冻结, 出现'事件说车走了、快照说车还在'。
修复:
- 新增 iot_sensor_ingest(): 事件沿 + _cached_sr 刷新单一入口,
回调与 Step1 两路汇入, 帧竞争不再影响数据新鲜度
- Step1 直读路径补 lup_verify_checksum (此前裸解析未校验)
|
2026-07-15 17:48:30 +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
|
e54334e761
|
docs: event_report 不受 report_config.enable 门控 (王工拍板)
- devlog 决策落定, 移除待确认标记
- MQTT/TCP 两协议 §5.x 补充: enable/interval 仅管 loop_data, 事件上报解耦
|
2026-07-15 13:45:51 +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 |
|
wangfq
|
0861a1c1f8
|
proto: event_report 增加平台/客户端必答确认机制 (MQTT V1.04 / TCP V1.01)
事件为不可再生关键数据, QoS/TCP送达不代表业务层落库, 引入应用层闭环:
- 应答格式: 回显 msg_id + code/msg, 不带 data
- 设备重发: 5s 超时, 同 msg_id/原始 ts, 最多 3 次, 失败留队列
待重连或下一事件合并上报 (MQTT ≤500B / TCP ≤4096B 拆包)
- 平台/客户端: 先落库后应答; msg_id 十分钟窗口去重, 重复包答 code=0 不重复入库
- 附正常/应答丢失重发时序图; 命令详表与交互示例同步
|
2026-07-15 11:55:21 +08:00 |
|
wangfq
|
dc7dd1cb26
|
feat(iot_mqtt): 快速上报增加 car_state 翻转沿触发
- Step2: 任一通道 |variation|>=阈值 或 car_state 翻转沿, 均进入 300ms 快速档
(高灵敏度档小车 variation 可能不过阈值, 但 Loop 已判翻转, 事件不应慢发)
- 修复首版两坑: if(fast_mode=0) 单等号致沿检测死代码;
快照刷新移到间隔门控之后, 防止沿被门控吞掉后退化为空闲慢发
- gcc 隔离单测: buggy 沿后延迟 950ms vs fixed 250ms, 出车沿/负向variation回归通过
- devlog 补 2026-07-15 条目
|
2026-07-15 09:34:04 +08:00 |
|
wangfq
|
964d619f10
|
docs(vd960Loop): variation 分析报告标记 DBN 解析端升级已核实
代码核对确认: 步长12B/bit23符号扩展/misc偏移/fast_mode双向绝对值均已落地
|
2026-07-15 08:46:20 +08:00 |
|
wangfq
|
7c5920805d
|
docs(vd960Loop): variation-analysis.md 对齐协议 V1.05 (变化量 2B无符号→3B有符号)
- 全文口径切换: variation = Origin - CAPVD, 3B LE 补码, ±2^23 饱和
- 新增 §5 变更分析: 回绕污染/方向丢失缺陷、符号语义、bit23 符号扩展、
步长 11→12 死绑定的静默错位风险及 Len 字节兼容方案
- 波形场景补充方向语义: 锯齿极性=漂移方向, 持续负值=基线污染诊断
- 旧问题清单更新: 2B 截断标记已解决; 待验证新增新旧固件混跑错位复现
|
2026-07-15 08:38:22 +08:00 |
|
wangfq
|
82e01cd337
|
docs(devlog): 记录 variation 2B->3B有符号升级 (V1.05)
- vd960Loop/docs/devlog.md: 组包端改动(uint32->int32,方案B,饱和防回绕),
背景/影响范围/验证
- vd960DBN/docs/devlog.md: 接收端4处联动(结构体/解析步长/符号扩展/
fast_mode abs阈值), 缓冲核查
两端均标注必须同版本发布
|
2026-07-14 16:48:25 +08:00 |
|
wangfq
|
bfc9646e48
|
proto(V1.05): variation 由 2B无符号 扩展为 3B有符号
背景: variation 是遥测量, 用于离线跟踪分析车检器算法。原 2B 无符号
存在两个缺陷: (1)CAPVD域量级~131072, 大车全覆盖时偏差可超65535而回绕,
污染数据; (2)绝对值丢失方向, 分不清'车进入'与'反向漂移'。
改动 (三端联动, 同版本发布):
- 协议 DLD960Loop_串口通信协议.md: 变化量 2B->3B有符号补码, 定义
variation=Origin-CAPVD (正=车/裕量, 负=反向漂移); 每单元11->12B,
Len 47->51; 补符号扩展说明; 示例报文重算(XOR=FE SUM=38); 修订记录V1.05
- vd960Loop main.c: 组包 uint32->int32, Origin-CAPVD, 3B LE, +-2^23饱和防回绕
- vd960DBN loop_uart_proto.h: variation uint16->int32
- vd960DBN loop_uart_proto.c: 步长11->12, data_len/11->/12, misc偏移右移1B,
variation 3B解码+bit23符号扩展
- vd960DBN iot_mqtt_srv.c: fast_mode 阈值判断改 abs(variation)>=10, 正负变化都加速
验证: 本地 gcc 隔离单测 编解码往返/符号扩展/饱和/方向语义/fast_mode 全通过;
大车 diff=100000 旧版回绕34464 新版正确保留。字节账: 帧56B < Loop缓冲64B
< DBN缓冲512B < MSS576, 均不溢出。整体固件编译需在 Keil/MounRiver 侧完成。
|
2026-07-14 14:47:39 +08:00 |
|
wangfq
|
db52f92348
|
docs: 新增 variation 上报量分析报告
分析 uart_report_packet_loop_acs 中 variation=|Origin-CAPVD| 的更新机制:
- 三操作数节奏: CAPVD~10ms / Origin 5s阶跃 / 上报窗150/600ms采样
- Origin 基线状态机: 稳定期(win100~1s)/正常(win500~5s)/冻结/冻结超时(~10s)/有车冻结
- 波形特征: 无车漂移锯齿波、车辆驻留干净跟随、大干扰防污染冻结
- 风险: 采样混叠、2B截断回绕、锯齿谷误判空闲、稳定期切换拐点
|
2026-07-14 11:47:19 +08:00 |
|
wangfq
|
403770e1c8
|
feat(iot_mqtt): 传感器MQTT主动上报改为双速率间隔上报
- 新增传感器数据缓存(_cached_sr), 0xC0帧到达时更新缓存, 不上报
- 根据各通道 variation 决定上报间隔:
空闲态(diff < 10): 使用 g_report_cfg.interval 秒
变化态(diff >= 10): 固定 300ms 快速上报
- interval=0 时自动退化为最小 1s 空闲间隔
- 断线时清缓存+复位计时, 重连后等新帧首发
- 消除对 g_pkg_uart_2.flag 的硬依赖, 从缓存自主定时上报
新增常量:
IOT_MQTT_FAST_INTERVAL_MS 300
IOT_MQTT_VARIATION_THRESHOLD 10
IOT_MQTT_IDLE_INTERVAL_MIN_MS 1000
|
2026-07-13 10:57:40 +08:00 |
|
wangfq
|
c2fb459a80
|
vd960DBN docs: 开发日志更新 V3.2 — 双主题统一 + initialize 对齐 + packet_id 断连修复
|
2026-07-10 15:02:04 +08:00 |
|
wangfq
|
01ab739d05
|
vd960DBN: 修复 mqtt_publish QoS>0 时 packet_id=0 导致 broker 断连
MQTT 规范要求 QoS≥1 的 PUBLISH 必须带非零 packet_id。
net_srv.c 的 mqtt_publish 硬编码 packet_id=0,broker 检测到协议违规后主动断开连接。
修复:QoS>0 时使用递增的 packet_id。
|
2026-07-10 09:20:14 +08:00 |
|
wangfq
|
01db1e6a1c
|
DBNMQTTool: 增加 dld960/+/dev/# 订阅兼容旧固件多级 topic
旧固件响应发布到 dld960/{sn}/dev/config/resp 等多级路径,
单级通配 dld960/+/dev 无法匹配,# 通配确保向后兼容。
|
2026-07-10 09:12:31 +08:00 |
|
wangfq
|
9d9e4fa4bc
|
DBNMQTTool: initialize 消息解析后同步显示设备型号到列表
- device_manager.mark_online 增加 model/hard_ver/soft_ver 参数
- 修复旧格式 extra_info.version 取 soft_ver 的问题
- main.py 的 initialize 处理传入完整设备信息
|
2026-07-10 09:04:39 +08:00 |
|
wangfq
|
11d1a96d24
|
同步协议 V1.03:双主题发布对齐 + initialize 数据格式修正
vd960DBN:
- heartbeat/sensor/initialize 发布统一走 dld960/{sn}/dev
- dev_initialize_pub 补 model/hard_ver/soft_ver,删 extra_info.version
DBNMQTTool:
- 协议版本号更新至 V1.03
- 协议 Topic 树和模拟页增加 initialize 支持
|
2026-07-10 08:49:28 +08:00 |
|
wangfq
|
652fc5f938
|
feat: V1.03 initialize 上线消息 — 固件+工具同步
vd960DBN:
- dev_initialize_pub() 改为 V1.03 格式 (msg_id/cmd/ts/data/extra_info)
- iot_mqtt_srv: 订阅改双主题 dld960/{sn}/srv, 响应 topic 改 dev
- SUBACK 后自动发 initialize 告知服务器上线
- net_srv.h: 加 dev_initialize_pub 声明
DBNMQTTool:
- protocol.py: 加 CMD_INITIALIZE
- device_manager: DeviceInfo 加 extra_info, 加 mark_online()
- main.py: 接收 initialize 消息, 自动标记设备上线
- docs: 协议 V1.03 + devlog V3.1
|
2026-07-09 21:32:39 +08:00 |
|
wangfq
|
1ff731c309
|
fix(docs): initialize 消息结构修正 — snake_case + data包装
- extra_Info → extra_info(命名风格统一)
- 字段表加 data.extra_info.* 路径前缀
- JSON 结构统一为 data: {...} 包装,加 ts
|
2026-07-09 19:00:43 +08:00 |
|
wangfq
|
c515638032
|
fix: MQTT协议 V1.02 同步 — 字段名缩短 + 时间单位修正
- docs/DLD960_IoT_MQTT协议.md: 字段缩写 + 时间单位 5ms→50ms
- vd960DBN/iot_mqtt_srv.c: 6字段缩短对齐协议 (level/iscar/freq/diff/sens/cndtn)
- vd960DBN/tcp_json_srv.c: gap_ms5/passtime_ms → gap/passtime
- vd960DBN/loop_uart_proto.h: 注释 5ms→50ms
- DBNMQTTool/main.py: 模拟样本数据字段同步
|
2026-07-09 10:18:03 +08:00 |
|
wangfq
|
466ce00680
|
feat(iot_mqtt): 恢复 loop_data 完整字段 + 分批发送(2通道/包)
按 DLD960_TCP_JSON协议.md §5.1 恢复完整字段:
- ch, freq_level, has_car, loop_ok, freq_current, freq_diff,
sensitivity, condition, misc.type, misc.value
每包发 2 个通道,确保 JSON < 450 字节 (mqttBuf 512 安全范围内)。
4 通道设备每次 SensorReport 发 2 条 loop_data 消息。
|
2026-07-08 17:21:06 +08:00 |
|
wangfq
|
4c6d23a951
|
fix(iot_mqtt): 传感数据 topic 改为 V1.01 双主题协议 dld960/{sn}/dev
原 iot_make_topic("dev","data","loop") → dld960/{sn}/dev/data/loop (V1.00)
改为直接用 g_iot_topic.topic_pub → dld960/{sn}/dev (V1.01)
与 report_config 等命令响应共用同一 topic,DBNMQTTool 订阅 dld960/+/dev 可接收到
|
2026-07-08 16:54:23 +08:00 |
|
wangfq
|
8425b473d3
|
fix: net_srv.h 添加 mqtt_publish() 声明供 iot_mqtt_srv.c 调用
|
2026-07-08 16:12:20 +08:00 |
|
wangfq
|
8232ec2c55
|
fix(iot_mqtt): 改用 net_srv.c mqtt_publish() 发送传感数据
iot_mqtt_publish_sensor() 原先调用 iot_mqtt_publish() →
iot_mqtt_send() → WCHNET_SocketSend() 从主循环发送导致重启。
改为调用 net_srv.c 的 mqtt_publish()(与 report_config 响应
共用同一路径,已验证在中断上下文中稳定工作)。
同时在 net_srv.h 中声明 mqtt_publish() 供跨文件调用。
|
2026-07-08 16:11:50 +08:00 |
|
wangfq
|
2175fee742
|
fix(iot_mqtt): 移除 iot_mqtt_send() hex dump 循环避免栈溢出重启
hex dump 连续 65 次 PRINT 调用消耗大量栈空间,
在 CH32V208 2KB 栈限制下导致溢出重启.
改为仅打印 len 和 ret/status.
|
2026-07-08 15:52:43 +08:00 |
|
wangfq
|
a71adaafdc
|
fix(iot_mqtt): 精简 loop_data JSON 避免 WCHNET_SocketSend 超大包崩溃
问题: 4通道传感器数据 JSON ~700字节 → MQTT Publish 733字节
超过 WCHNET TCP MSS(576) 和原始 MAX_MQTTBUF_LEN(512) 设计上限
WCHNET_SocketSend(733) 导致设备重启
修复:
- 移除非必要字段: freq_current, freq_diff, condition
- 展平 misc 嵌套对象 → mt(类型) + mv(数值)
- 缩短 key 名: freq_level→fl, has_car→car, loop_ok→ok, sensitivity→sens
- 每通道 ~70字, 4通道 ~280, 全包 ~400字节
- 加安全检查: payload >450 时跳过并打印警告
|
2026-07-08 15:09:50 +08:00 |
|
wangfq
|
555cdb741d
|
fix(iot_mqtt): g_iot_socket 未初始化导致 WCHNET_SocketSend(0xFF) 硬故障重启
根因: iot_mqtt_srv.c 中 g_iot_socket 初始化为 0xFF,
仅 iot_connect_broker() 中设为 SocketId_TCP.
但内联 MQTT 模式(iot_mqtt_poll 从未调用)下该赋值永不执行.
iot_mqtt_publish_sensor() 调用 iot_mqtt_send() →
WCHNET_SocketSend(0xFF, ...) → HardFault → 设备重启.
修复: iot_mqtt_init() 中设置 g_iot_socket = SocketId_TCP,
该函数在 net_srv_init() flag==1 时被调用(含首次启动和每次重连).
|
2026-07-08 09:11:23 +08:00 |
|
wangfq
|
0e116c2d31
|
fix(net_srv): MQTT 主动上报无数据 + PINGREQ 缺失导致断连
问题1: iot_mqtt_publish_sensor() 检查 g_iot_state != IOT_STATE_READY 直接 return,
但 g_iot_state 从未被 net_srv.c 内联 MQTT 处理器设置为 READY → 无传感数据上报
问题2: poll_mqtt() 依赖 flag_mqtt_ping_send 触发 PINGREQ,
但该标志从未被设为 1 → broker keepalive 超时断连 (~12s)
修复:
- mqtt_data_manage() CONNACK: 设 g_iot_state=IOT_STATE_READY
- WCHNET_HandleSockInt DISCONNECT: 设 g_iot_state=IOT_STATE_DISCONNECTED
- mqtt_data_manage() PINGRESP: 重置 flag_mqtt_ping_err
- poll_mqtt(): g_activ_counter > 9000 自动触发 PINGREQ
|
2026-07-08 08:55:10 +08:00 |
|
wangfq
|
de2e70fd89
|
feat(vd960DBN): MQTT ssc_net_set / iot_net_set / iot_topic_set 实现
- ssc_net_set: 解析 dev_ip/subnet_mask/route_ip/lssc_ip/dns/port,调用 write_net_config
- iot_net_set: 解析 host/port/client_id/username/password,调用 write_net_config
- iot_topic_set: 解析 client_id_enable/topic_pub/topic_sub,调用 write_net_config
- 三个 SET 命令均写入 flash 并在完成后返回 code=0 success
|
2026-07-07 21:15:55 +08:00 |
|
wangfq
|
2bbe388738
|
fix: iot_mqtt_srv.c 添加缺失的 tcp_json_srv.h include
|
2026-07-07 18:47:05 +08:00 |
|
wangfq
|
a7de4dfcde
|
feat(vd960DBN): MQTT/TCP report_config 支持完整7参数配置
- 新增 ReportConfig 结构体 (sensor_type/enable/once/env_eval/interval/ack_required/timeout)
- net_srv.c: MQTT report_config handler — 查询/设置均返回完整配置JSON
- tcp_json_srv.c: TCP JSON handle_report_config 同步升级,兼容旧 active_report
- iot_mqtt_srv.c: g_report_active → g_report_cfg.enable
- g_report_active 全局变量替换为 g_report_cfg 结构体
|
2026-07-07 18:39:45 +08:00 |
|
wangfq
|
cd92f3e0c3
|
feat(DBNMQTTool): 查询响应自动回填输入框 + 主动上报配置
- _on_message 中 ssc_net/iot_net/iot_topic/report_config 查询结果
不再仅显示 JSON,改为调用 _apply_* 方法回填到对应输入框
- 新增「主动上报配置」GroupBox(sensor_type / interval / timeout
+ 4 开关),支持查询/设置 CMD_REPORT_CONFIG
- import 增加 CMD_REPORT_CONFIG / data_report_config
|
2026-07-07 18:22:39 +08:00 |
|
wangfq
|
b932dd7c6f
|
feat: DBNMQTTool 日志增强 — 收发打印 topic + payload 详情
新增 _log_send() / _log_recv() 两个统一日志方法:
- 发送: 标签 + → topic + PASTE:{精简payload}
- 接收: ← topic + summary + RECV:{精简payload}
- payload >200/300 字符自动截断
覆盖所有收发路径:
- [模拟]/[协议]/[自定义]/[命令] 发送
- 响应/loop_data/event_report/heartbeat/Initialize 接收
- mqtt_client.py 自动订阅事件日志
|
2026-07-07 17:47:58 +08:00 |
|
wangfq
|
5e4e1b1ec7
|
fix: DeviceManager 死锁 — threading.Lock 改为 RLock
根因: update_from_dev_info/update_loop_data/update_event/update_heartbeat
在 with self._lock 块内调用 get_or_create(), 后者再次 with self._lock.
Python threading.Lock 不可重入 → 永久阻塞 → GUI 无响应.
修复: self._lock = threading.RLock() (可重入锁)
清理: mqtt_client.py 移除 debug print 和未使用的 sys import
|
2026-07-07 17:36:35 +08:00 |
|
wangfq
|
c98aa5b0bb
|
fix: MqttClient 回退信号方案,添加 publish debug 日志追踪阻塞点
- 移除 QObject 基类和 QueuedConnection 信号方案
- publish() 直接调用 self._client.publish() 并打印前后日志
- 添加 print(flush=True) 确保 Windows 终端实时输出
目的是确认阻塞发生在:
[MqttClient] publish topic=... qos=1 ← 打印后消失?
[MqttClient] publish done mid=... ← 这行能否出现?
|
2026-07-07 17:27:15 +08:00 |
|
wangfq
|
baa82c895d
|
fix: MqttClient 重构为 QObject — publish 通过 Qt 信号排队避免 C 层崩溃
问题: paho-mqtt publish() C 扩展在 Windows 上从 GUI 线程调用时静默崩溃。
修复:
- MqttClient 改为 QObject 子类
- publish() 通过 Qt Signal(Qt.QueuedConnection) 排队,_do_publish()
始终在主线程事件循环中执行 paho 调用
- 状态/消息通知改用 Qt Signal 跨线程传递
- 新增 subscribe()/unsubscribe() 公开 API,消除 main.py 直接
访问 _client 的脆弱代码
- 移除 MainWindow 中已不再需要的中间信号 _mqtt_status/_mqtt_msg
|
2026-07-07 14:25:49 +08:00 |
|
wangfq
|
6eb93637c7
|
fix: DBNMQTTool — 所有 publish 路径增加通用异常捕获
问题: _custom_publish / _proto_publish / _sim_publish 只 catch
json.JSONDecodeError, MqttClient.publish() 抛出的 ConnectionError
等异常未被捕获, 在 Qt 信号槽中导致静默崩溃(Windows 无 traceback).
修复:
- _custom_publish: +except Exception, 避免 toPlainText() 重复调用
- _proto_publish: +except Exception, 避免 toPlainText() 重复调用
- _sim_publish: +except Exception
- _custom_subscribe/_custom_unsubscribe: +except Exception, +_client 空检查
|
2026-07-07 14:15:36 +08:00 |
|
wangfq
|
5a2ef0be5d
|
fix: DBNMQTTool — right 局部变量改为 self._notebook
_build_ui() 中 right = QTabWidget() 是局部变量,导致
_proto_publish_item() 中 self._notebook.setCurrentWidget() 报
AttributeError: 'MainWindow' object has no attribute '_notebook'
|
2026-07-07 14:07:52 +08:00 |
|
wangfq
|
90d723517e
|
feat: manage_mqtt_recv_message 实现 V1.01 协议命令分发
net_srv.c: manage_mqtt_recv_message() 从占位打印升级为完整命令分发器:
已实现(8条):
- dev_info_query: 返回设备信息(序列码/版本/子码)
- ssc_net_query: 返回 SSC 网络配置
- iot_net_query: 返回 IoT 网络配置(MQTT broker)
- iot_topic_query: 返回 topic 配置
- pwd_verify: 验证设备密码
- factory_reset: 出厂初始化+重启
- device_reset: 设备复位
未实现(返回 code=4):
- dev_serial_set, pwd_set, ssc_net_set 等 SET 类命令
所有响应通过 g_iot_topic.topic_pub (dld960/{sn}/dev) 发布
|
2026-07-07 13:58:27 +08:00 |
|
wangfq
|
3cdc5b6286
|
fix: MQTT PUBLISH 接收修复 — topic 过滤 + cmd/Method 双格式支持
问题: mqtt_data_manage() 的 PUBLISH 分支直接调用 manage_mqtt_recv_message(),
跳过了 mqtt_deserialize_publish() 的 topic 过滤, 且只支持旧 Method 格式.
修复:
- mqtt_data_manage: PUBLISH 改为走 mqtt_deserialize_publish 做 topic 匹配
- mqtt_deserialize_publish: topic 过滤已改用 g_iot_topic.topic_sub
- manage_mqtt_recv_message: 优先解析 cmd, 兼容旧 Method 字段
|
2026-07-07 12:09:07 +08:00 |
|
wangfq
|
ab3a4cea0a
|
fix: 出厂默认 topic 使用真实设备序列号 + PRINT 修正
- cfig_flash.c: factory_dev_info() 用 gMacAddr 生成真实主题 dld960/{SN}/srv + dld960/{SN}/dev
- net_srv.h: TOPIC_DEFAULT 加注释标明为格式模板
- net_srv.c: 修复上次提交的 PRINT 宏转义异常
|
2026-07-07 10:57:20 +08:00 |
|
wangfq
|
b707241429
|
feat: MQTT 双主题同步到 vd960DBN 固件 + DBNMQTTool devlog
vd960DBN 固件改动:
- net_srv.h: 默认 topic 改为 dld960/{sn}/srv + dld960/{sn}/dev
- net_srv.c: dg_subscribe_display_topic() 直接用 topic_sub 订阅(不再追加 client_id/sn 后缀)
- net_srv.c: mqtt_deserialize_publish() topic 过滤改用 g_iot_topic.topic_sub(不再硬编码 TOPIC_DEFAULT_SUBSCRIBE)
DBNMQTTool 文档:
- devlog.md: 清理过期 topic 引用语义
|
2026-07-07 09:46:54 +08:00 |
|
wangfq
|
770d67346f
|
refactor: MQTT 主题方向 down→srv, up→dev
- dld960/{sn}/down → dld960/{sn}/srv
- dld960/{sn}/up → dld960/{sn}/dev
- 通配符 dld960/+/up → dld960/+/dev
|
2026-07-07 09:42:35 +08:00 |
|
wangfq
|
213716033c
|
feat: MQTT 协议 V1.01 — Topic 压缩为双主题 (up/down)
- 7个主题压缩为2个: dld960/{sn}/down + dld960/{sn}/up
- 消息类型由 JSON cmd 字段区分,不再依赖 topic 路径
- protocol.py: topic_up()/topic_down() 替代旧7个函数
- mqtt_client.py: 4个通配符订阅→1个 dld960/+/up
- main.py: 消息路由改为 cmd 匹配,协议Topic树简化
- 文档更新 V1.01
|
2026-07-07 09:18:29 +08:00 |
|
wangfq
|
d29e16acc8
|
docs(DBNMQTTool): 开发日志 — 初始化到模拟上报全记录
|
2026-07-06 23:27:40 +08:00 |
|
wangfq
|
c19e465284
|
feat(DBNMQTTool): 模拟上报 + 协议Topic + 自定义Topic
新增三个 Tab:
1. 模拟上报 — 可编辑 loop_data/event_report/heartbeat JSON,
支持单次发送和周期上报(间隔可调)
2. 协议Topic — 按协议文档列出所有 dld960/{sn}/srv/... 和 dev/... topic,
双击填充到发布区,支持编辑 JSON 载荷
3. 自定义Topic — 自由输入 topic 发布,支持订阅/取消订阅,
接收消息实时展示
新增:
- QComboBox, QSpinBox, QPlainTextEdit 控件
- paho.mqtt.client 导入(topic_matches_sub 通配符匹配)
- 自定义订阅消息自动路由到接收区
|
2026-07-06 21:40:26 +08:00 |
|
wangfq
|
5210051f19
|
chore(DBNMQTTool): 删除误提交的 vim swap 文件
|
2026-07-06 21:32:30 +08:00 |
|
wangfq
|
213c0ddc2d
|
fix(DBNMQTTool): paho-mqtt disconnect 回调签名兼容 v1/v2
- _on_disconnect: 用 *args 兼容 v1(3参数) 和 v2(5参数)
- Client 构造加 callback_api_version=VERSION2
- _on_connect 签名保持不变 (v2)
|
2026-07-06 21:32:24 +08:00 |
|
wangfq
|
e1bf3dcfca
|
refactor(DBNMQTTool): tkinter → PySide6
- main.py: 完整重写为 PySide6 (Qt for Python)
- requirements.txt: 加 PySide6>=6.6.0
- 使用 Qt 信号/槽替代 tkinter 回调
- 界面更现代化,Fusion 风格
- 分组框 (QGroupBox) 布局,QSplitter 分栏
|
2026-07-06 21:19:55 +08:00 |
|
wangfq
|
a2cfe4602c
|
feat: DBNMQTTool — DLD960 IoT MQTT 设备管理工具 (Python/tkinter 跨平台)
基于《DLD960_IoT_MQTT协议.md》V1.00 实现
功能:
- MQTT Broker 连接管理
- 设备自动发现(订阅 dld960/+/dev/# 通配符)
- 设备信息查询(dev_info_query)
- 网络配置(SSC/IoT TCP)+ Topic 配置
- 实时线圈数据监控(loop_data)+ 事件上报(event_report)
- 心跳监控(heartbeat)
- 控制命令:密码验证/设置、出厂初始化、设备复位
项目结构:
- main.py 主窗口 (tkinter GUI)
- dbn_mqtt_tool/
- protocol.py DLD960 IoT MQTT 协议定义
- mqtt_client.py MQTT 客户端封装 (paho-mqtt)
- device_manager.py 设备发现与状态管理
|
2026-07-06 18:14:38 +08:00 |
|