Commit Graph
42 Commits
Author SHA1 Message Date
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 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 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 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 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 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 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 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 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 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 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 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 0c8402d726 fix(vd960DBN): MQTT socket 复用 SocketId_TCP,对标官方 WCHNET MQTT 例程
根因分析:iot_connect_broker 自建 socket 与 WCHNET_CreateTcpMqttSocket
创建的 SocketId_TCP 冲突(重复创建),且自建 socket 的 WCHNET_SocketSend
崩溃。官方 MQTT 例程使用统一的 SocketId/SocketId_TCP 模式。

改动:
- peripheral_main.c: 恢复 WCHNET_CreateTcpMqttSocket() 调用
- iot_connect_broker: 不再创建新 socket,直接复用 SocketId_TCP
- 全链路(SocketSend/HandleSockInt/poll)通过 g_iot_socket=SocketId_TCP 统一
2026-07-06 16:09:22 +08:00
wangfq 46091639cd fix(vd960DBN): iot_connect_broker 加 SourPort + iot_mqtt_send 加 hex dump
- SourPort 参考 WCHNET_CreateTcpMqttSocket 设为 port_dev_udp+1
- iot_mqtt_send 打印前64字节 hex 内容
2026-07-06 15:44:22 +08:00
wangfq 88526158d0 fix(vd960DBN): MQTT CONNECT 改为 poll 内延迟发送,避免中断内 WCHNET_SocketSend 崩溃
1. 参考 net_srv.c mqtt_connect 模式重写 iot_mqtt_send_connect:
   - clientID 用 g_dev_number_str(全局),不用 g_iot_dev_serial
   - username/password 直接赋值,不用 strlen 检查
   - memset 手动初始化,不用 brace-initializer 赋值

2. SINT_STAT_CONNECT 中断内不再调 iot_mqtt_send_connect,
   改为标记 TCP_CONNECTED,由 iot_mqtt_poll 下一轮发送 —
   参考 tcp_json_handle_sock_int 不立即发送数据的模式
2026-07-06 15:16:24 +08:00
wangfq 884a622cab refactor(vd960DBN): 缓冲区 2048→1024,单次交互不超 1KB
- IOT_MQTT_RECV_BUF_LEN: 2048 → 1024
- IOT_MQTT_SEND_BUF_LEN: 2048 → 1024
- data_json 改用宏
- iot_handle_publish 的 json[] 改 static 防栈溢出
2026-07-06 13:47:10 +08:00
wangfq 7459c0fa80 fix(vd960DBN): iot_mqtt_publish_sensor 栈溢出 — data_json[2KB] + payload[2KB] = 4KB 远超 2KB 栈
每次主循环调 iot_mqtt_publish_sensor 都分配 4KB 栈变量,
直接栈溢出踩烂全局变量(含 g_iot_dev_serial→clientId=空),
最终在 iot_mqtt_send_connect→WCHNET_SocketSend 时 hard fault。
改为 static 彻底消除栈压力。
另加 iot_mqtt_send 调试日志。
2026-07-06 13:40:25 +08:00
wangfq de3a7c197e fix(vd960DBN): MQTTPacket_connectData_initializer 不能用于赋值,用临时变量中转 2026-07-06 11:31:12 +08:00
wangfq dfadc26717 fix(vd960DBN): MQTT buffer 从栈改为 static,防止栈溢出 (栈仅 2KB)
iot_mqtt_send_connect:  opts(~85B) + buf[256]  → static (~340B 省)
iot_mqtt_send_subscribe: buf[256]              → static (256B 省)
iot_mqtt_publish:        buf[2048]             → static (2KB 省)
调用链 WCHNET_HandleGlobalInt → iot_mqtt_handle_sock_int
→ iot_mqtt_send_connect 会叠加 WCHNET 协议栈内部开销,
2048B 栈极易溢出导致 hard fault(现象:乱码+truncated日志+重启)
2026-07-06 11:27:08 +08:00
wangfq c0220c1d37 fix(vd960DBN): IoT socket 重复创建 + broker IP 解析错误
- iot_connect_broker: 删除 memcpy,get_ipstr_to_array 已正确解析 IP
  之前 memcpy 把原始 ASCII 字节覆写到 broker_ip,导致 IP 变成 49.50.49.46
- peripheral_main.c: IoT 模式下跳过 WCHNET_CreateTcpMqttSocket,
  由 iot_connect_broker() 统一管理 socket 生命周期,避免重复创建
2026-07-06 10:46:51 +08:00
wangfq e6dbdb5296 fix(vd960DBN): 修复无法设置 IoT 模式的 bug 2026-07-06 10:24:15 +08:00
wangfq 39bda6067f fix(vd960DBN): add missing closing brace for case PUBLISH block in iot_process_recv
case PUBLISH: { ... } was missing its closing }, causing ARMCC to think
iot_send_heartbeat and iot_connect_broker were declared inside a function body.
2026-07-03 18:28:40 +08:00
wangfq 122c36bb9d fix(vd960DBN): iot_make_topic missing 5th arg for "srv"/"ctrl" topic 2026-07-03 18:18:38 +08:00
wangfq 6f5effae8c fix(vd960DBN): iot_mqtt_srv compilation errors
- Add extern g_report_active (from tcp_json_srv.h)
- Fix iot_make_topic call: 4-arg -> 5-arg (add NULL for 'status' sub)
- Fix SOCK_INF field names: DestPort->DesPort, DestAddr->IPAddr
- Fix struct _WCHNET_IPAddr -> uint8_t broker_ip[4] (type not available)
2026-07-03 18:12:55 +08:00
wangfq 9629729dc9 feat: IoT MQTT 客户端实现 — NET_SSC_ENABLE=0 时启用
新增文件:
- iot_mqtt_srv.h/c: MQTT 客户端 (TCP→CONNECT→SUBSCRIBE→READY)
  支持: dev_info_query, pwd_verify (其他命令框架预留)
  上报: loop_data (传感器), heartbeat (心跳 60s)
  断线重连: 指数退避 5s~60s
  协议: DLD960 IoT MQTT V1.00 (dld960/{sn}/...)

修改:
- net_config.h: 新增 NET_IOT_ENABLE = !NET_SSC_ENABLE,
  IoT 模式分配 1 TCP socket (MQTT client)
- net_srv.c: IoT 初始化 + socket 中断路由
- peripheral_main.c: IoT poll + sensor publish 调用

模式:
  NET_SSC_ENABLE=1 → SCC + TCP JSON Server (原有行为)
  NET_SSC_ENABLE=0 → IoT MQTT Client (新增)
2026-07-03 17:36:22 +08:00