wangfq
|
3c9a6f900b
|
docs(MQTT): DLD960_IoT_MQTT协议 V1.12 — 4G 通道适配修订为方案 C(Air780 协议转换)
方案 B → 方案 C(用户 2026-08-31 决策):
- Air780 解析 0x7F 帧转换为标准 JSON 命令(loop_data/event_report/initialize/heartbeat),平台零改动
- V1.11 的 frame_report/frame_cmd 降级为可选兜底
- 4G 事件面 = 仅线圈事件(car_enter/car_leave/loop_cut/loop_restore),不含 DBN 内部网络事件
- event_report 复刻 DBN iot_evt_* 逻辑(Lua: 沿检测+ACK+5s×3+16深队列+跨重连同 msg_id),可行性已评估无硬障碍
- 命令响应: Air780 单命令状态机 + 超时回 code=5(与 g_lup_cmd 同模式)
- 链路层: DBN UART2↔UART1 纯转发(魔数分流),转发不丢帧是沿检测前提
同步: README 索引 V1.12 + devlog 置顶条目
|
2026-08-31 15:24:31 +08:00 |
|
wangfq
|
d6873f4b45
|
docs(MQTT): DLD960_IoT_MQTT协议 V1.10→V1.11 — 4G 通道适配(方案B hex透传)
方案 B(原始帧透传 + hex 封装)正式并入主协议:
- 新增 §6 4G 通道适配: 架构(0x7F帧透传)/命令面差异/上行 frame_report/下行 frame_cmd/不支持命令/link 对象/平台要求
- §3 命令详表加 frame_cmd + frame_report(4G 通道专用标注)
- 头部版本行 + 修订记录 V1.11
- 4G 通道: 不使用有线标准 JSON 业务命令;网络配置类命令回 code=4
- 实施主体: Air8781P(Air780EPM) vd960Air 工程;vd960DBN UART1 通道列入计划(固件未实现,如实标注)
- 同步: README 索引 V1.11 + devlog 置顶条目(协议先行)
|
2026-08-31 14:45:46 +08:00 |
|
wangfq
|
2e73155388
|
docs(BLE): DLD960_BLE协议 V1.02→V1.03 — 命令总表补齐 + 未实现如实标注
对照 dbn_ble_srv.c(GBK+CRLF) 逐命令梳理,补齐既有配置命令:
- 0x09/0x10/0x11/0x12: 序列码/设备信息/SSC网络读写
- 0x13/0x14/0x15/0x16: IoT网络/Topic读写(字符串数组 0x00 分隔)
- 0x1C/0x1D: 密码验证/修改(0x1D 在 unpack_packs,不在 switch)
- 0x1E/0x92/0x1F/0x22: 出厂/复位/子功能码
- 0x31: UART波特率读写(⚠ 写响应多 1B 重复低字节)
- 0xC5: 传感上报使能(⚠ report_sens_acs 无定义,0xC0 上报未实现)
- 透传通道 0x7F/0x9F
未实现如实标注: 0x17/0x18/0x20/0x21/0x87/0x88/0x89 无 case;
0x23/0x24/0x8A 空壳/空响应
同步: README 文档索引 V1.03 + devlog 置顶条目(2026-08-31)
|
2026-08-31 13:58:59 +08:00 |
|
wangfq
|
6e711e35ef
|
release(vd960DBN): 固件版本 1.02.04 → 1.02.05 (2026-08-21)
涵盖 8-20 联网稳定性修复系列 + 8-21 MQTT 协议 V1.10 实现:
- SocketSend 0x11 退避 / SocketCreat 失败中止 (死循环闭环)
- OTA hex 提取兼容 json.dumps 空格
- OTA 刷写状态回 idle + ota_report 主动上报
- OTA 命令缓冲 union 合并 (RAM 90% 复位闭环)
- MQTT V1.10: dev_info_query/initialize 补 loop_ver/loop_hw_ver + loop_version_query 实时查询
cmcng.h 三段式一致: FIRMWARE_VER="1.02.05" + MAIN=1/SUB=2/SUBSUB=5
README 当前发布行 + 子项目版本表 → 1.02.05
CHANGELOG 新增 V1.02.05 条目 (配套矩阵: MQTT V1.07→V1.10)
devlog V4.8 条目补版本说明
产品手册/技术规格书留待打 tag 正式发布时同步
|
2026-08-21 08:55:01 +08:00 |
|
wangfq
|
181467b9e6
|
feat(vd960DBN): MQTT 协议 V1.10 固件实现 — 网络上报携带地感版本 (2026-08-21)
协议 V1.10 (3be9e50) 三处新增落地:
1. dev_info_query 响应 data 补 loop_ver/loop_hw_ver (0x4A 缓存值, 未完成/失败为空串)
2. initialize 上报同样携带 (尽力, 可为空)
3. 新增 §4.25 loop_version_query: 0x4A 异步实时查询, 响应在 iot_verq_poll() 回包
固件:
- loop_uart_proto.h/c: 新增 LoopVerCache + g_lup_ver_cache (0x4A 缓存);
lup_cache_from_info() 写缓存, lup_refresh_version_cache() 后台刷新 (通道空闲才发)
- iot_mqtt_srv.c: dev_info_query/initialize 加字段; loop_version_query 分支
(暂存 msg_id/deadline 300ms, busy 拒绝重复查询); iot_verq_poll() 异步回包
(RESPONSE_READY -> code=0 + 三字段 + 同步刷缓存; TIMEOUT -> code=5 保缓存值);
后台刷新: 上电 iot_mqtt_init + OTA done (iot_ota_report_result ok=1) 置 dirty
关键设计: 版本来源=0x4A 实时查询 (非 OTA 元数据 version=目标版本);
缓存值语义 dev_info_query/initialize 同步回包不等异步; 与 TCP 共用 g_lup_cmd
单命令通道 (后发覆盖, 先发者超时 — 低频命令, 待板上验证时序)
单测: tests/test_iot_loop_ver.c — gcc 隔离 (extract+embed 6 函数 + mock)
44 断言全过: 版本帧解析(正常+4 错误路径) / 缓存写入+格式化(空串/NULL 防护) /
verq_poll 成功回包(code=0+三字段+topic+缓存刷新+通道释放) / 超时回包(code=5+缓存值) /
后台刷新(发起/忙不消费/响应消费/残留超时清理)
验证: check_c_balance.py 3 文件 OK; 待板上验证 UART2 0x4A 与 loop_data 共用总线时序
|
2026-08-21 08:26:11 +08:00 |
|
wangfq
|
51298693da
|
fix(vd960DBN): OTA 刷写成功误判未启动 — 状态回 idle + 补 ota_report 主动上报
现场: 远程平台发起 OTA, 设备物理刷写成功 (70块全ACK, flash DONE),
但平台 ota_status 轮询只见 state=ready → 误判'刷写未启动'。
根因:
1. ota_flash_done 刷写成功后台侧状态置 READY (与协议状态机
'FLASHING──成功──▶IDLE(清槽/保留)' 不符), 平台无法区分
'待刷 ready' 与 '已刷完' → 持续 ready 判未启动
2. 固件漏实现协议 §5.5 ota_report 主动上报 (done/failed 重发 3次×5s),
平台收不到成功信号, 只能靠 ota_status 轮询兜底
修复 (协议 V1.09 + 固件):
- 协议: 刷写成功状态明确回 idle (镜像保留, last_result=0, 可重刷);
ota_report 升级为刷写结果主依据; 平台判定指引 (idle+size>0+last_result=0
=成功; 不得以轮询未见 flashing 或持续 ready 判未启动)
- ota_srv.c: ota_flash_done → OTA_STATE_IDLE (镜像保留) + 上报 done;
ota_flash_fail → 补 ota_report failed (保留 event_report 告警);
ota_cmd_begin 兼容 idle+size/crc32 一致 → 直接回 ready (免下载重刷)
- iot_mqtt_srv.c: 新增 ota_report 上报状态机 (立即首发 + 5s×3 重发,
同 msg_id/ts), 共享 _iot_pub_payload (event_report 复用, RAM 零新增)
- 单测: test_flash_flow/test_flash_ready_timeout 断言 ota_report 上报,
state 断言 READY→IDLE; 新增 test_begin_reflash; 10/10 全过 + 22 py 断言
|
2026-08-20 18:56:21 +08:00 |
|
wangfq
|
1badba3893
|
fix(vd960DBN): 联网 SocketSend 0x11 死循环 — 发送退避 + SocketCreat 失败中止
现象: loop_data 606B 发送 0x11(ERR_MEM) → 立即重试10次 → 3次断连 →
重连 SocketCreat 0x1D(ISCONN) 仍继续 Connect → timeout 死循环永久失联
根因:
1. WCHNET_NUM_TCP_SEG=2 (瘦身改小): 重传队列占用即无发送缓冲 → 0x11 瞬时
2. iot_mqtt_send 失败处理过激: 无退避立即重试 + 3次就强制断连
3. WCHNET_CreateTcpMqttSocket: SocketCreat 失败(mStopIfError只打印)仍继续
Connect → 无效 socket 等超时死循环; SocketId_TCP 未置 0xFF 沿用旧 id
修复:
- iot_mqtt_send: 0x11 200ms 退避重试(≤10次, 等SEG释放), 不立即断连
- 强制重连: 补 SocketId_TCP=0xFF
- WCHNET_CreateTcpMqttSocket: SocketCreat 失败置 0xFF + return 不 Connect,
上层指数退避
验证: 语法 0 错误; 待板级确认重发自动恢复 + 重连退避
|
2026-08-20 18:16:31 +08:00 |
|
wangfq
|
c305ca651f
|
fix(vd960DBN): OTA 下载失败 — hex 提取兼容 json.dumps 空格
现象: DBNMQTTool 第一片 ota_data code=1 crc/gap, received=0, 重试全败
根因: 工具 json.dumps 默认带空格 ("data": "hex"), 设备端 strstr 找
"data":" 无空格格式 → 提取失败 → hexbuf 空 → 解码失败 code=1
(simple_parse_json 容错空格所以其他命令正常, 只有手工 strstr 踩坑)
修复:
- ota_srv.c/h: 新增 ota_json_extract_hex() 兼容有无空格 (扫描 data 键跳过空白)
- iot_mqtt_srv.c: ota_data 改用该函数, 删 strstr 手工提取 + hp 残留
- 单测 +test_json_extract_hex: 无空格/带空格(事故场景)/512hex/找不到 4 场景
验证: 单测 11/11 PASS; 语法 0 错误; 待板级重测下载
|
2026-08-20 14:13:06 +08:00 |
|
wangfq
|
2484a03326
|
fix(vd960DBN): 联网复位事故 — OTA 命令缓冲合并 union (RAM 90% 栈余量不足)
现象: SUBACK 后收平台 report_config (PUBLISH len=197) → HardFault →
NVIC_SystemReset (RST_REASON 0x10000000 = SFT, 非 IWDG) → 死循环复位
根因: RAM 90.02% + 6 个 OTA 分支独立 static resp[256~400] + hexbuf[513]
共 ~2.5KB BSS → 栈余量被挤 → iot_handle_publish 深调用链栈溢出
(局部栈改 static 是伪优化: BSS↑=栈余量↓; 正解是 union 复用减总量)
修复:
- iot_mqtt_srv.c: 6 resp + hexbuf 合并函数级 static union _ota_io (~2KB 省)
- ota_srv.c: _chunk_buf/_fs_frame 合并 union (~260B 省) + 删无用变量
验证: 语法 0 错误; gcc 隔离单测 10/10; 待板级确认 RAM 回 ~88% 不再复位
|
2026-08-20 14:04:00 +08:00 |
|
wangfq
|
0b51d84a9b
|
perf(vd960DBN): OTA RAM 优化 — union 复用块缓冲 + 命令分支数组改 static
MRS 编译 RAM 90.02% (44248/48KB) 逼近历史 .bss 挤栈红线, 减负:
- ota_srv.c: _chunk_buf[256] + _fs_frame[254] 合并为 union (下载/校验与刷写帧
互斥复用, 省 ~260B static); ota_send_9f 组帧直接用 union 缓冲 (省 254B 栈)
- iot_mqtt_srv.c: 6 个 ota_* 分支 resp[256~400] + ota_data hexbuf[513] 局部栈
数组改 static (栈峰值 → BSS, 防运行时栈溢出; RAM 总量不变但运行时安全)
验证: gcc 隔离单测 9/9 全过; 语法 0 新增错误
|
2026-08-20 13:41:33 +08:00 |
|
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
|
d4ce0ba23a
|
chore(vd960DBN): 固件版本 1.02.03 → 1.02.04 (SPI 存储适配)
内容: SPI Flash 识别去厂商代码 + 恢复 factory 配置写入 (板级验证通过)。
README/CHANGELOG/devlog 同步; 手册/规格书配套版本更新 (文档保持 V1.02, 同日补充不升版)
|
2026-08-19 15:23:35 +08:00 |
|
wangfq
|
881a774c0c
|
docs(vd960DBN): devlog 标注 factory 写入修复板级验证通过 (W25Q128 读写正常)
|
2026-08-19 15:21:40 +08:00 |
|
wangfq
|
8e58d5fdd1
|
fix(vd960DBN): 恢复 factory 配置写入 — 换新空片后配置永久丢失
8-13 止血(SPI 写触发复位)根因已 8-17 闭环(栈溢出+printf 重入, 非 SPI 问题),
offlog/snapshot 8-18 起持续 SPI 写入稳定 → 解除止血。
新空片(W25Q128)参数区无 magic + write_net_config 不写 magic → 每次上电
memory defaults, 保存配置永久丢失。恢复: mismatch 分支调 factory_dev_info()
写 magic+默认参数到 flash, 首次上电自动初始化。
|
2026-08-19 15:13:18 +08:00 |
|
wangfq
|
f1d9ac4e48
|
fix(vd960DBN): SPI Flash 识别去厂商代码判断 — 兼容其他厂家同容量型号
- W25Qxx 宏 0XEF13~17 -> 0X13~17 (去掉厂商前缀, 只留设备 ID)
- SPI_Flash_ReadJEDEC_ID() 删除 id[0]!=0xEF||id[1]!=0x40 校验, 直接返回容量码 id[2]
(JEDEC 容量码跨厂商标准化, offlog/snapshot 分区判断随之生效)
- storage_init() switch 改 Flash_Model & 0xFF 低字节匹配
- 换非华邦芯片 (如 0x1A 厂商) 时识别不再不一致
|
2026-08-19 14:45:30 +08:00 |
|
wangfq
|
832d2953b0
|
chore(vd960DBN): 固件版本 1.02.01 → 1.02.03 (2026-08-19)
OTA 0x9F 透传修复板级验证通过, 用户更新版本号三段式一致。
V1.02.03 内容: BLE→Loop OTA 修复 (0x9F 帧透传回 BLE) +
8-18 脱机日志快照流/hex 上报 + MQTT 查询命令补齐。
README/CHANGELOG/devlog 同步; 已知约束: OTA 模式无自动退出 (维持现状)
|
2026-08-19 11:20:03 +08:00 |
|
wangfq
|
d67f955fd4
|
fix(vd960DBN): BLE→Loop OTA 失效修复 — 0x9F 帧透传回 BLE
DMA 改造(fed4335)后 UART2 RX 走 lup_feed_byte 只认 0x7F, Loop bootloader
回的 0x9F 响应帧(pre_ok/addr_ok/data ACK)全被吞; OTA 是停等协议
(0xA7 WITH_BACK 每块必回 ACK), 工具等不到 ACK 升级必然卡死。
- loop_uart_proto: 新增 lup_feed_byte_ota() 0x9F 帧状态机 (SUM 校验无 XOR,
复用 g_lup_parser), 枚举追加 OTA 专用状态
- usart_biz: uart2_dma_poll 按 g_flag_counter_ota.flag 切换 0x9F/0x7F 解析器,
模式切换 reset, OTA 溢出阈值放宽整缓冲, 补收帧 tick 归零;
uart_srv OTA 分支 0x9F 帧透传回 BLE + 清 flag
- 单测 tests/test_lup_ota_parser.c 8 断言全过 (bootloader 真实帧向量)
- 遗留: g_flag_counter_ota.flag 无退出机制, 升级后需断电重启
|
2026-08-19 11:01:45 +08:00 |
|
wangfq
|
839d79b487
|
chore(vd960DBN): 移除误提交的测试二进制 test_snap_to_hex
|
2026-08-18 14:04:34 +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
|
f2141976f0
|
feat(vd960DBN)+fix(DBNMQTTool): MQTT 查询命令补齐 + 工具命令集对齐 (2026-08-18)
固件 (V4.2):
- iot_mqtt_srv.c 补齐 ssc_net_query / iot_net_query / iot_topic_query (只读全局组包, 与 TCP JSON §4.5/4.7/4.9 对齐)
- 修复实测: MQTT 通道 ssc_net_query/iot_net_query 返回 code=4 unsupported
工具:
- 禁用固件未实现的 6 个按钮 (ssc/iot_net/iot_topic_set + pwd_set/factory_reset/device_reset) + tooltip 引导 TCP/BLE
- 设备刷新列表移除 loop_param_query (固件未实现)
- offscreen 验证按钮状态正确
|
2026-08-18 11:44:52 +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
|
55192523fe
|
docs(vd960DBN): devlog 2026-08-12 动态分区条目补传感快照区容量对照表 (2026-08-18)
- 原表更名'容量对照(事件日志区)'
- 新增'容量对照(传感快照区)': 起始/大小/数据扇区/max_records/capacity LE 四芯片对照 (0x110000/48064 起)
- 数值与 snapshot.c snap_part_detect 计算一致 (总容量-576KB-事件区, 去头扇区, 64B/条)
|
2026-08-18 08:45:57 +08:00 |
|
wangfq
|
ae9f5eaf4c
|
chore(vd960DBN): 固件版本 1.02.01 (三段式) + cmcng.h 注释修复 (2026-08-17)
用户更新:
- FIRMWARE_VER "1.02.01" (MAIN=1 SUB=2, 新增 FIRMWARE_VER_SUBSUB=1)
- 注释修复: GBK 乱码注释恢复中文 (文件 GBK→UTF-8 编码转换, 中文注释正常)
- 注意: BLE 上报仍为 MAIN/SUB 两字节 (1.02), SUBSUB 仅字符串上报使用
|
2026-08-17 17:19:40 +08:00 |
|
wangfq
|
263dc4e05d
|
chore(vd960DBN): 固件版本 1.0 → 1.1 (2026-08-17)
cmcng.h FIRMWARE_VER "1.0"→"1.1" (MAIN=1 SUB=1):
- 修正字符串与数字不一致 (旧 "1.0" vs MAIN=1 SUB=1)
- 版本内容: 栈溢出修复 + RAM 瘦身 + UART2 RX DMA + 清理
- 注释用 ASCII (cmcng.h 为 GBK 编码)
|
2026-08-17 16:55:51 +08:00 |
|
wangfq
|
8c0f135629
|
chore(vd960DBN): 结案清理 — 移除临时诊断代码 (2026-08-17)
频繁复位问题闭环后清理:
- peripheral.c performPeriodicTask: 删 _dbg_cnt 500ms 调试心跳打印 (BLE 状态已由上层链路验证)
- peripheral_main.c: 删 g_boot_count(.noinit) + BOOT_CNT/END/SP 诊断打印块
- 保留 fault_diag 基础设施 + RST_REASON 一行 (诊断价值, 未来复用)
- 注意: peripheral.c 为 GBK+CRLF, 新注释用 ASCII
|
2026-08-17 16:42:59 +08:00 |
|
wangfq
|
fed4335947
|
feat(vd960DBN): UART2 RX DMA 循环接收 — 根治打印关中断丢帧 (2026-08-17)
遗留项'UART2 偶发丢帧(1-3分钟一次 checksum fail)'落地:
- 根因: PRINT 临界区(关中断~7.4ms)屏蔽 USART2 RXNE 中断 → 丢字节
- 方案: DMA1_Ch6 循环模式硬件收字节(不依赖CPU中断), 主循环轮询消费
- uart2_dma_init(): Ch6 循环模式 + 512B 环形缓冲(aligned(4)) + 关 RXNE
- uart2_dma_poll(): 主循环读 DMA_GetCurrDataCounter 批量喂 lup_feed_byte
(状态机移入主循环无竞争); 溢出保护(未消费>256B重置+丢帧计数)
- uart_init() 末尾调 uart2_dma_init(); USART2_IRQHandler 清空留 IDLE 注释
- 资源: DMA1 全空闲(WCHNET 独立 ETH DMA/BLE 不用 DMA1) → Ch6 独占
- .bss +512B(缓冲), 栈 6.3KB→5.8KB 仍充裕
|
2026-08-17 15:59:16 +08:00 |
|
wangfq
|
f274d70fbd
|
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 初始化回归
|
2026-08-17 15:34:09 +08:00 |
|
wangfq
|
cb63c581be
|
perf(vd960DBN): 二轮RAM瘦身 — RECE_BUF_LEN 1024 + ARP 16 + 中断路径static (2026-08-17)
.map 分析: BLE 栈固定占 RAM 低 16KB 不可裁; 用户 48KB 内 .bss 41.7KB。
- 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]/frame[800] 局部→static (中断上下文栈数组防溢出)
栈 4.7KB→~6.3KB, 中断栈峰值 -1.8KB。devlog 记录 .map 分析结论。
|
2026-08-17 14:26:22 +08:00 |
|
wangfq
|
89ba602e4f
|
fix(vd960DBN): 栈溢出修复闭环 — 打印恢复 + 字符串0终止保险 (2026-08-17)
RAM 瘦身后栈 1.9KB→~4.75KB (END 0x2000f834→0x2000ed3c 实测), printf 峰值安全:
- cfig_flash.c: 恢复 load_cfg 3 处调试 PRINT (magic mismatch×2 + Sub_Code)
- cfig_flash.c: 字符串 0 终止保险 (remote_addr/client_id/username/password/topic_pub/sub
末字节强制 '\0', 防 Flash 字符串不足定长时 %s 越界打印)
- peripheral_main.c: 恢复 output_cfg_from_flash() (调试配置打印)
- 注释更新为修复闭环说明
设备实测: 无复位, MQTT 连 159.75.137.141:1883, BLE 广播正常
|
2026-08-17 14:18:52 +08:00 |
|
wangfq
|
421334ec48
|
perf(vd960DBN): RAM 瘦身 — .bss 省 4.8KB, 栈 1.9KB→~6.7KB (2026-08-17)
栈溢出根因确认后 .bss 瘦身四刀:
- net_config.h: ETH_MAX_PACKET_SIZE 1520→768 (MSS=700最大帧758B, 省3.76KB)
- iot_mqtt_srv.c: payload[1400]→800 (loop_data最大~604B, 省600B)
- iot_mqtt_srv.h: IOT_MQTT_SEND_BUF_LEN 1024→800 (_iot_send_buf/resp/buf 同步, 省224B)
- net_srv.c: MAX_MQTTBUF_LEN 1024→800 (512仍不够勿回改, 省224B)
⚠ ETH 768 为 MSS=700 最小安全值; 若现场有大UDP包截断改回1024。
待办: .map 确认 BLE 栈占用; RECE_BUF_LEN/ARP 表可再省; 局部大数组转static。
|
2026-08-17 14:10:52 +08:00 |
|
wangfq
|
26f2326c96
|
fix(vd960DBN): 栈溢出止血 — load_cfg 去调试打印, output_cfg 暂关 (2026-08-17)
实验D确认 load_cfg/output_cfg 为跑飞触发点。根因: .bss≈46KB
(BLE栈+ETH DMA 7.6KB+SPI_FLASH_BUF 4KB+网络缓冲) 挤占 RAM,
栈仅 ~1.9KB (BOOT_CNT@0x2000f84c 证明 .noinit 被推到 RAM 顶)。
load_cfg 的 printf 栈峰值触顶 → 覆盖 .noinit+返回地址 → PC 跑飞循环。
修复:
- cfig_flash.c: load_cfg 内 3 处调试 PRINT 注释 (magic mismatch×2 + Sub_Code×1)
- peripheral_main.c: load_cfg 恢复(配置加载保留); output_cfg 调用 #if 0 (纯调试打印)
- devlog: 实验D结论 + 修复记录
根治待办: 减 .bss 给栈腾 4KB+ (需 .map 确认大数组);
output_cfg 恢复调试打印前需减栈压力
|
2026-08-17 11:06:56 +08:00 |
|
wangfq
|
452ff68bae
|
test(vd960DBN): 实验D — 栈空间诊断 + load_cfg/output_cfg 触发点验证 (2026-08-17)
新证据: BOOT_CNT@0x2000f854 = .noinit 被推到 RAM 顶, 栈顶(0x20010000)
之下仅 ~1.9KB → .bss≈46KB (BLE/WCHNET/SPI_FLASH_BUF 等大数组挤占)。
栈溢出 → 覆盖 .noinit(g_boot_count 恒1/g_fault_diag 消失) + 覆盖返回地址
→ PC 跑飞跳回 0 → 循环。快照延后无效因为问题不是快照 SPI 而是栈空间。
- BOOT_CNT 打印加 _end(堆起点, 反推.bss大小) + 当前 SP(栈深)
- load_cfg/output_cfg #if 0 (EXPD 标记): 稳定→触发点确认; 仍崩→更晚
- 待用户提供编译后 .map 确认 .bss 组成
|
2026-08-17 11:00:03 +08:00 |
|
wangfq
|
8cf01544f6
|
feat(vd960DBN): 快照区延后初始化(开机3s后) — 避开启动早期SPI重负载窗口 (2026-08-17)
诊断: 08-14恢复快照区后频繁重启。RSTSCKR无复位标志(非硬件复位) +
BOOT_CNT恒=1(.noinit被清, RAM全丢级) + 实验A(跳过offlog_boot)仍崩
→ 启动早期SPI重负载(offlog/snap init 擦+整扇区写回~80ms×2)让系统
进入临界状态, 后续SPI操作(load_cfg读参数区)成为压垮点。
方案:
- snapshot.c/h: 新增 snap_delayed_init(), 主循环每轮调用, 开机3s后
首次进入执行 snap_init (非阻塞, mstick()>=3000 门控)
- peripheral_main.c: main() 移除 snap_init 调用; 主循环喂狗后加
snap_delayed_init(); 撤销实验A(恢复offlog_boot)/实验B(恢复load_cfg)
- 3s内传感帧由 snap_enqueue/snap_flush 的 !_ready 门控自动丢弃不落盘
- 保留 BOOT_CNT 诊断打印(.noinit 计数器+地址)
- devlog 置顶 2026-08-17 条目
|
2026-08-17 10:31:39 +08:00 |
|
wangfq
|
5803255d89
|
test(vd960DBN): 实验B — 跳过 load_cfg/output_cfg, 跑飞触发点下移 (2026-08-17)
实验A(跳过 offlog_boot)仍循环复位 → offlog_boot 非触发点, 跑飞点下移。
新证据: BOOT_CNT 恒=1 (.noinit 计数器每次被清) → RAM 全丢级重启,
RSTSCKR 却无复位标志 → 疑似掉电-恢复(未触发POR) 而非软件跑飞。
- load_cfg_from_flash + output_cfg_from_flash #if 0, 加 EXPB 标记
- BOOT_CNT 打印加 &g_boot_count 地址, 确认 .noinit 段是否生效
(地址 >= _ebss≈0x2000612c 且在 .noinit → 复位不清零; 恒1 → RAM被清)
预期: 不崩 → 触发点在参数区SPI读或%s打印; 仍崩 → 触发点更晚/更早
|
2026-08-17 10:15:21 +08:00 |
|
wangfq
|
0c717e4818
|
test(vd960DBN): 实验A — 跳过 offlog_boot SPI 写, 验证跑飞触发点 (2026-08-17)
日志诊断: RSTSCKR 全 0(非硬件复位) + snap ok 后 71B 乱码 + 无 ASCII 打印
→ PC 跑飞跳回 0x00000000 重启, 触发点锁定 offlog_boot(SPI 32B 页写)。
与 08-12 实验 99ef634 结论一致。
- offlog_boot() 调用 #if 0, 保留 RMVF 清除
- 新增 .noinit g_boot_count 计数器: 每次 main 重进 +1 并打印 BOOT_CNT
(跑飞重启不清零, 区分真复位 vs 跑飞)
- 新增 EXPA: offlog_boot skipped 标记打印
预期: 不崩 → offlog_boot 写实锤; 仍崩 → 跑飞点下移 load_cfg/output_cfg
|
2026-08-17 10:04:52 +08:00 |
|
wangfq
|
8873b334d2
|
feat(vd960DBN): 恢复快照区功能, 移除 sim_snap_spi 实验桩, UART2 波特率注释修正
- peripheral_main.c: snap_init() 恢复 (去 #if 0), offlog_boot() 恢复
(上电复位原因记入事件日志); 删除 sim_snap_spi 模拟写密度实验函数
及主循环调用 (printf 重入修复后 SPI 写无罪已确诊, 实验收尾)
- loop_uart_proto.h/c: UART2 波特率注释 115200/19200 -> 192000
(usart_biz.c 硬编码 192000 为实际值; g_storage_uart_baud=19200
为独立配置项不驱动 UART2, BLE 显示 19200 不代表实际速率)
- devlog: 新增 2026-08-14 条目, UART2 RX DMA 方案列入待办
|
2026-08-14 09:46:23 +08:00 |
|
wangfq
|
960d1e83a1
|
docs(vd960DBN): devlog 置顶 2026-08-13 复位/卡死全链路诊断闭环
printf 重入 + json_sensor_callback 卡死 + UART2 丢字节 三层根因,
SPI 写无罪/QFN28 无 NRST/5min restart 真相/修复清单/遗留待办
|
2026-08-14 03:02:17 +08:00 |
|
wangfq
|
b493e10454
|
fix(vd960DBN): UART2 粘帧/checksum fail — 高频打印关中断丢字节 + flag 不清
现场: LUP 帧后 checksum fail 刷屏 (坏帧: 7F 03 39 EF... 多帧拼接)。
根因链条:
1. LUP Rx 打印 190B @256000 = 7.4ms 关中断 (PRINT 临界区)
→ UART2(19200) RX 溢出丢字节 → 帧解析错位 → 粘帧
2. g_pkg_uart_2.flag 清理缺失: uart_srv 0xC0 分支不 InitPkgUart,
tcp_json_push_sensor not authed 提前 return 也不清
→ 坏帧反复处理 → checksum fail 刷屏
修复:
- LUP Rx 打印 #if 0 (高频打印关中断是丢字节根因, 调试时开)
- json_sensor_callback not authed 打印 #if 0 (每帧刷屏)
- uart_srv 所有分支消费后统一 InitPkgUart (0xC0 + 非0xC0无BLE)
- 顺带修 report disabled 双反斜杠
|
2026-08-13 17:43:24 +08:00 |
|
wangfq
|
a36cc15cf2
|
test(vd960DBN): 二分卡死点 — 注释 json_sensor_callback enter PRINT + 删冗余打印
现场: LUP 帧后卡死 (5分钟后神秘复位 RST=0x10000000, marker丢失)。
卡死点在 lup_process_frame 内 json_sensor_callback 的 enter PRINT
(printf %d 处理), LUP Rx 打印(%s)成功但 enter(%d%d%d)卡死。
实验:
- json_sensor_callback enter PRINT #if 0 (坐实 printf 问题)
- uart_srv 187-190 重复逐字节打印 #if 0 (LUP Rx 已缓冲打印, 冗余)
验证: 不卡死→printf %d 问题实锤; 仍卡死→json_sensor_callback 后续代码
|
2026-08-13 17:22:31 +08:00 |
|
wangfq
|
e7389b95fb
|
fix(vd960DBN): fault_diag 无条件打印 marker — 卡死(非HardFault)也能定位
原只在 magic=0xFA57FA57 (HardFault) 时打印, 卡死/IWDG 复位时
marker 有值但 magic=0 → 轨迹丢失。改为:
- magic 有效 → 完整现场 (mcause/mepc/mtval/marker)
- marker!=0 且无 HardFault → 打印 no-hardfault + marker (卡死定位)
|
2026-08-13 16:35:30 +08:00 |
|
wangfq
|
4bdf8a7993
|
fix(vd960DBN): IWDG 无条件启用+喂狗 — 卡死兜底 (卡死定位闭环)
现场: printf 重入修复后乱码消失, 但 LUP 帧处理卡死(连 JSON:
sensor_cb enter 都没打印), 且 iot_enable=0 模式 IWDG 未初始化
(iot_mqtt_poll 才喂狗, tcp_json 分支不喂) → 卡死永久冻结无兜底。
修复:
- main 无条件 iot_watchdog_init() (IWDG 4s 超时)
- 主循环 while 开头无条件 iot_watchdog_kick() (原只在 iot_mqtt_poll)
- json_sensor_callback / iot_evt_sensor_cb 加 FAULT_MARKER(MK_EVT_CB_IN/OUT)
效果: 卡死 → 4s IWDG 复位 → 上电 FAULT_DIAG 打印 marker 定位卡死点
|
2026-08-13 16:15:26 +08:00 |
|
wangfq
|
ee3ade6f00
|
fix(vd960DBN): PRINT 宏临界区保护 — printf 重入修复 (乱码+HardFault 根因)
现场: LUP 帧后乱码+复位。JSON: sensor 打印被二进制污染、
LUP Rx hex 残留重复 → printf 交叉输出的典型症状。
根因: BLE 协议栈回调(peripheral.c, BB 中断上下文)与主循环
都有 PRINT, 交叉调用 printf → 输出乱码 + newlib 堆/状态破坏
→ HardFault (RST=0x10000000 为 HardFault_Handler 内 NVIC_SystemReset)。
修复:
- debug.h PRINT 宏: 保存/恢复 MSTATUS 临界区 (__get_MSTATUS/
__disable_irq/printf/__set_MSTATUS), 中断里调用也能正确恢复,
不会嵌套误开中断
- loop_uart_proto: LUP Rx 逐字节打印改缓冲一次性输出 —
逐字节 PRINT 关中断 ~350us/字节屏蔽 UART2 ISR 丢帧
|
2026-08-13 16:06:35 +08:00 |
|
wangfq
|
9f5102e9e8
|
feat(vd960DBN): fault_diag — .noinit RAM 现场 + 执行轨迹 marker 定位神秘复位
现象: LUP 帧后复位, RST=0x00000000 (无标志) 且 HardFault 打印缺失
(上次 0x10000000=SFT 确认 HardFault 路径, 这次连打印都没有)
方案: .noinit 段复位不清零, 跨复位留痕
- Link.ld: 新增 .noinit 段 (startup 只清 .bss 不碰)
- fault_diag.h: FaultDiag{magic,mcause,mepc,mtval,marker,boot_cnt} + FAULT_MARKER 轨迹宏
- HardFault_Handler: 纯 RAM 写 mcause/mepc/mtval (官方 __get_MCAUSE/MEPC/MTVAL,
不依赖 UART/printf, 栈坏也能留痕) + 尽力打印
- main 开头 fault_diag_init(): 打印上次现场 + 递增 boot_cnt
- 轨迹 marker: 主循环 LOOP_TOP/UART_SRV/SIM_SPI/POLL_BLE + LUP 链
LUP_FRAME/INGEST/EVT_FEED 入口出口, 复位后看 marker 停在哪一步
|
2026-08-13 15:44:07 +08:00 |
|
wangfq
|
1bbaac0046
|
fix(vd960DBN): HardFault_Handler 抓 RISC-V 异常现场 — 定位崩溃源头
诊断修正(2026-08-13): RST=0x10000000(bit28 SFT) = HardFault_Handler
内 NVIC_SystemReset, 不是硬件复位! 复位紧跟 LUP 传感器帧(30ms内),
0xC0 帧处理路径触发代码异常。模拟实验 SPI 写(cnt=64/128 擦除+头写)
全部成功, SPI 写本身不触发复位, 推翻 VDD 跌落/共线假设。
- HardFault_Handler 打印 mcause(0x342)/mepc(0x341)/mtval(0x343)
mcause 5/7=野指针(mtval给地址) 2=非法指令 4/6=未对齐
mepc 用 .map 文件反查函数
|
2026-08-13 15:31:34 +08:00 |
|
wangfq
|
87c8e01936
|
test(vd960DBN): SPI写密度模拟实验 + factory写止血 — VDD跌落诊断
- peripheral_main: sim_snap_spi 模拟快照落盘节奏 (20ms 64B页写 + 每64条切扇区擦除+头写)
- cfig_flash: magic不匹配时跳过 factory SPI_Flash_Write, 用内存默认值继续
(SPI写触发硬件复位死循环止血: 参数区0x00写也崩, RST=0x00000000)
- 诊断修正: CH32V208GBU6 QFN28 无 NRST 引脚, 共线假设作废;
SPI写/擦除→电流尖峰→VDD跌落→内部POR/PDR(2.4V)复位;
BLE射频+SPI电流叠加是头号嫌疑
|
2026-08-13 11:27:08 +08:00 |
|
wangfq
|
99ef6348d7
|
test(vd960DBN): 跳过 offlog_boot 写 — 二分定位 SPI 触发点
f766530(跳过snap)仍崩 → 非快照SPI; 旧固件也有 offlog_boot 32B 写
→ 硬件一直有问题只是未暴露; 另一差异: 事件区 0x010000(旧) vs 0x090000(新)
本版: #if 0 offlog_boot 写 (保留 RMVF 清除)
不崩 → offlog_boot 写(或切扇区擦除)触发; 崩 → 更早 SPI 读操作/非SPI
|
2026-08-12 19:39:50 +08:00 |
|
wangfq
|
f766530609
|
test(vd960DBN): 跳过 snap_init 实验 — SPI 序列还原旧固件
回答'为什么旧固件正常': 旧固件也有 offlog_boot 32B 写, 理论上也踩同样硬件问题
差异: 新固件启动早期 SPI 密度翻倍(snap_init 读+擦+写头) + 快照区首擦
实验: #if 0 snap_init → SPI 序列=旧固件
稳定 → 快照 SPI 触发; 崩 → offlog_boot 本身, 旧固件也该崩(硬件一直有问题)
|
2026-08-12 19:34:55 +08:00 |
|
wangfq
|
8bb576111b
|
test(vd960DBN): SPI 分频 16→128 极慢版 — 验证频率无关性
降频4倍(9053831)后乱码字节不变+仍复位 → 非频率相关串扰
疑似 MOSI(PA7) 写数据与 NRST/调试线物理共线/短路 (乱码=写数据错位采样)
分频128(~0.5-1MHz): 若仍崩 → 100%物理层问题, 软件无解, 必须硬件修
硬件测量: 断电测 PA5/PA7 与 NRST 导通电阻(应无穷大); 查原理图 SPI 走线
|
2026-08-12 19:31:49 +08:00 |
|
wangfq
|
9053831f27
|
fix(vd960DBN): SPI 串扰复位软件缓解 — 降时钟+缓边沿, 恢复功能
实验闭环: Flash/SPI 全禁用后设备稳定 (BLE/WCHNET/TCP 全正常)
→ SPI 操作触发复位+乱码实锤; 崩点在 offlog_boot 写 32B (不擦除)
→ 排除电流, 判定 SPI 信号串扰 NRST(复位) + 调试线(乱码)
缓解: storage.c GPIO 50MHz→10MHz 缓边沿 + SPI 分频 4→16 降时钟
恢复: peripheral_main.c 两个隔离块改 #if 0 (Flash + UART2 正常)
硬件根治(待现场): NRST 加 100nF 电容 / SPI 走线远离 NRST / 串阻 22Ω
|
2026-08-12 19:27:47 +08:00 |
|
wangfq
|
22224416a3
|
test(vd960DBN): Flash/SPI 全禁用实验 — 定位 SPI 操作触发复位
UART2 隔离后(06fb009)依旧 80ms 复位循环+乱码 → 排除 Loop 数据路径
Hex 日志: 乱码紧跟 snap ok 后的 offlog_boot SPI 写, 复位标志全 0
= NRST 毛刺复位特征, 疑似 SPI 总线(PA4-7)串扰 NRST/调试线 或 电源瞬态
本版: #if 1 跳过 storage/offlog/snap/offlog_boot/load_cfg 全部 SPI 调用
判定: 稳定 → SPI 触发实锤, 硬件查电源/NRST/布线
仍复位 → 与 SPI 无关, 纯硬件(电源/晶振/其他)
|
2026-08-12 19:21:57 +08:00 |
|