fix(vd960Air): 修复上电反复复位, 打通测试服务器连接
现象: 上电后 Lua VM 报 uart_app.lua:28 attempt to index a boolean value
→ VM exit → 15s 后自动复位, 死循环, 永远走不到 MQTT 连接
根因(4 处叠加, 第 1 处致命):
1. config.lua 末尾漏 return —— require 对无返回值模块返回 true,
local CFG = require "config" 后访问 CFG.CFG_xxx 直接报错
2. 全工程 10 处调用 mstick(), 但 LuatOS 并无此 API(正确为 mcu.ticks())
3. MQTT 服务器仍是合宙官方测试服 lbsmqtt.airm2m.com:1884
4. MQTT 鉴权用户名/密码硬编码为空串
修复:
1. config.lua 末尾加 return _G(配置项本就是全局变量);
另: ClientID 的 mobile.imei() 加空值防护(or "unknown")
2. 新增 mstick.lua: 全局 mstick() = mcu.ticks() 封装(回退 os.time()*1000),
原 10 处调用点零改动; main.lua 在 require "config" 之后 require "mstick"
3. 服务器改为 110.41.131.144:1883(明文非 TLS), 新增 CFG_MQTT_USER/PASS,
mqtt_main 改为 auth(CLIENT_ID, CFG_MQTT_USER, CFG_MQTT_PASS, true)
4. .gitignore 放行 vd960Air/tools/ —— 官方 tools/ 忽略规则导致自检脚本
无法入库(sim_frame_test.py 自 8/31 起一直未入库)
新增工具:
- tools/sim_load_test.lua: 离线加载+冒烟自检(lua5.3 + LuatOS API 桩 + 严格全局
检查), 按 main.lua 真实顺序加载全部模块并冒烟调用关键函数, 用于抓取
"require 返回值缺失""调用了不存在的 API"这类语法检查抓不到的运行时问题
验证:
- luac5.3 -p 全部 14 个 lua 文件通过
- 离线自检: 16 项断言 + 8 项冒烟全部通过
- Python 帧协议参考验证全部通过
- readme Markdown 表格列数 0 异常
文档: readme 补 §8 板级问题修复记录, 更新文件结构/待确认清单/计划表
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
|
||||
```
|
||||
┌─────────────────┐ UART1 (115200) ┌──────────────────────┐ MQTT 3.1.1 ┌──────────┐
|
||||
│ vd960DBN │ 帧协议(0x7D) │ Air8781P 整板 │ JSON │ 云平台 │
|
||||
│ vd960DBN │ 0x7F 帧字节流 │ Air8781P 整板 │ JSON │ 云平台 │
|
||||
│ CH32V208 │ ◄───────────────► │ Air780EPM (LuatOS) │ ─────────────► │ dld960 │
|
||||
│ (车检器通信MCU) │ PB6=TX / PB7=RX │ vd960Air 应用 │ dld960/{sn}/ │ 主题族 │
|
||||
└─────────────────┘ └──────────────────────┘ {dev,srv} └──────────┘
|
||||
@@ -193,8 +193,9 @@ vd960DBN 与地感 MCU 的串口逻辑(loop_uart_proto.c,UART2,0x7F 帧):
|
||||
|
||||
```
|
||||
vd960Air/
|
||||
├── main.lua # 入口: 加载 config/看门狗/4G网卡/uart_app/app_iot/mqtt_main
|
||||
├── config.lua # 配置: MQTT 服务器/序列号/主题/UART/上报节奏/link 开关
|
||||
├── main.lua # 入口: 加载 config/mstick/看门狗/4G网卡/uart_app/app_iot/mqtt_main
|
||||
├── config.lua # 配置: MQTT 服务器(地址/端口/账号密码)/序列号/主题/UART/上报节奏/link 开关
|
||||
├── mstick.lua # 统一毫秒时基: 全局 mstick() 封装 mcu.ticks()(2026-09-10 新增)
|
||||
├── frame_parser.lua # ★ 0x7F 帧解析状态机(Lua 版 lup_feed_byte,IDLE→HEADER→VALUE→CHECK)
|
||||
├── proto_conv.lua # ★ 0xC0 传感帧 → loop_data + car_state/loop_state 沿检测
|
||||
├── evt_queue.lua # ★ event_report 队列 + ACK 状态机(16深/5s×3/跨重连同 msg_id)
|
||||
@@ -205,7 +206,8 @@ vd960Air/
|
||||
├── netdrv_device.lua # 网卡: 仅 4G(官方 netdrv_4g)
|
||||
├── network_watchdog.lua # 网络看门狗(官方原样)
|
||||
├── tools/
|
||||
│ └── sim_frame_test.py # 帧协议参考验证(Python 1:1 复刻解析公式,字节级断言)
|
||||
│ ├── sim_frame_test.py # 帧协议参考验证(Python 1:1 复刻解析公式,字节级断言)
|
||||
│ └── sim_load_test.lua # 离线加载+冒烟自检(lua5.3 + LuatOS API 桩,2026-09-10 新增)
|
||||
└── mqtt/
|
||||
├── mqtt_main.lua # MQTT 客户端(连接成功 → initialize + 未决事件重发)
|
||||
├── mqtt_receiver.lua # 下行分发: event_report ACK 路由 + report_config 时钟校准
|
||||
@@ -243,7 +245,9 @@ vd960Air/
|
||||
|
||||
- [ ] vd960DBN UART1 帧格式是否按 §3 设计稿(0x7D 帧),或用户文档另有规定
|
||||
- [ ] dev_serial 获取方式: config 写死 vs UART 握手动态下发(当前 config 写死)
|
||||
- [ ] MQTT 服务器地址/端口/TLS、鉴权方式(平台为准)
|
||||
- [x] **MQTT 服务器(2026-09-10 定)**: 测试服 `110.41.131.144:1883`,明文(非 TLS),鉴权 `admin/****`
|
||||
—— 实现: `config.lua` `CFG_MQTT_HOST/PORT/USER/PASS`,`mqtt_main` 取配置传入 `mqtt:auth()`
|
||||
- [ ] 商用 MQTT 地址/端口、是否启用 TLS(1883 明文 / 8883 TLS)、账号权限
|
||||
- [ ] 4G 特有命令清单(如 `4g_status_query` / `link_status_report`)是否纳入主协议 4G 章节
|
||||
- [ ] 通道切换策略: 有线失效判定、4G 启用条件、回切策略
|
||||
- [ ] 心跳: 4G 通道 heartbeat 间隔/内容是否与有线一致
|
||||
@@ -255,6 +259,7 @@ vd960Air/
|
||||
|------|------|------|
|
||||
| P0 | 工程骨架 + 帧协议 + MQTT 桥接 + link 注入 | ✅ 完成 |
|
||||
| **P0.5** | **方案 C MVP: 0x7F 帧解析 + 0xC0→loop_data + 沿检测→event_report + ACK 状态机 + initialize/heartbeat + 时钟校准**(2026-08-31) | ✅ 代码完成,待板级 |
|
||||
| **P0.5-fix** | **上电复位修复: config.lua 漏 return + mstick 时基 + MQTT 服务器/鉴权配置**(2026-09-10) | ✅ 已修,待板级复测 |
|
||||
| P1 | 下行命令转换(loop_param_*/log_*/ota_* 转 0x7F)+ 0x7D 配置同步下发 + vd960DBN UART1 通道联调 | ⏳ 待板/待 vd960DBN 版本 |
|
||||
| P2 | 板级联调: 帧校验、背压、掉线重连、看门狗 | ⏳ 待板 |
|
||||
| P3 | 通道切换(策略待讨论)+ 脱机日志/OTA 走 4G | ⏳ 规划 |
|
||||
@@ -265,4 +270,33 @@ vd960Air/
|
||||
- [ ] BLE 设置服务器/topic 参数时(0x13/0x15 等),同步经 UART1 下发 Air780 配置
|
||||
- [ ] 通道切换策略(待讨论: 动态自动 vs 人工设置;暂定默认 4G)
|
||||
|
||||
## 8 板级问题修复记录
|
||||
|
||||
### 8.1 2026-09-10 上电反复复位(无法连接测试服务器)
|
||||
|
||||
**现象**: 模块上电后无法连接 MQTT 测试服务器;模块日志结尾:
|
||||
```
|
||||
[000000000.212] I/user.main vd960Air 001.999.000
|
||||
[000000000.281] E/main Luat:
|
||||
[000000000.281] E/main uart_app.lua:28: attempt to index a boolean value (local 'CFG')
|
||||
[000000000.281] E/main Lua VM exit!! reboot in 15000ms
|
||||
```
|
||||
即 Lua VM 报错退出 → 15s 后自动重启 → 死循环,永远走不到 MQTT 连接。
|
||||
|
||||
**根因(4 处叠加,第 1 处为致命)**:
|
||||
|
||||
| # | 问题 | 影响 | 修复 |
|
||||
|---|------|------|------|
|
||||
| 1 | `config.lua` **末尾漏写 `return`** | Lua 的 `require` 对无返回值模块返回 `true`,`local CFG = require "config"` 后访问 `CFG.CFG_xxx` → `attempt to index a boolean value` → **VM 退出/复位** | 末尾 `return _G`(配置项本就是全局变量) |
|
||||
| 2 | 全工程 **10 处调用 `mstick()`**,但 LuatOS 无此 API(正确为 `mcu.ticks()`) | 走到即报 `attempt to call a nil value (global 'mstick')`;波及 initialize/heartbeat/事件重发/时钟校准 | 新增 `mstick.lua`: 全局 `mstick()` = `mcu.ticks()` 封装(回退 `os.time()*1000`),**10 处调用点零改动** |
|
||||
| 3 | MQTT 服务器仍是合宙官方测试服 `lbsmqtt.airm2m.com:1884` | 连不到用户测试服 | 改为 `110.41.131.144:1883` |
|
||||
| 4 | MQTT 鉴权**用户名/密码硬编码为空串** | 测试服要求账号密码,匿名连接被拒 | `config.lua` 增 `CFG_MQTT_USER/PASS`;`mqtt_main` 改为 `auth(CLIENT_ID, CFG_MQTT_USER, CFG_MQTT_PASS, true)` |
|
||||
|
||||
**验证方式**: 新增离线自检 `tools/sim_load_test.lua`(lua5.3 + LuatOS API 桩 + **严格全局检查**),
|
||||
按 `main.lua` 真实顺序加载全部模块并冒烟调用关键函数 → **全部通过**(16 项断言 + 8 项冒烟)。
|
||||
|
||||
**教训**:
|
||||
- **"语法正确" ≠ "能跑"**: `luac -p` 全绿,但"模块漏 return""调用了不存在的 API"这类问题只在运行时暴露 → **每次上板前先跑 `sim_load_test.lua`**
|
||||
- 新增 API 调用前先交叉核实 LuatOS 是否提供(如 `mstick` vs `mcu.ticks()`),不要"想当然"
|
||||
|
||||
> 基底来源: 合宙官方 Air780EPM demo/mqtt(main.lua / uart_app.lua / mqtt/* / network_watchdog / netdrv_device),MIT 许可。
|
||||
|
||||
Reference in New Issue
Block a user