Files
vd_960/docs/ROADMAP.md
T
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

221 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# vd960 (DLD960) 开发计划 — V1.0.0 之后
> 制定日期:2026-07-17 · 基线:整机 V1.0.02026-07-16 发布)
> 原则:先稳固、再上云、后算法深化;任何涉及继电器输出的改动,防砸车逻辑优先。
---
## 0. 现状基线
| 项 | 状态 |
|----|------|
| 整机版本 | V1.0.0(首发),Loop/DBN 固件 1.0 配套 |
| 协议 | Loop 串口 V1.05 / TTL 串口 V1.01 / TCP JSON V1.01 / IoT MQTT V1.05 |
| 在途改动(未提交) | BLE 透传路径重构:`usart_biz.c` 0x7F→0x8F 帧改走 `set_response_tran_to_notify()`,原 `_report_flag` 保留机制移除 |
| 已知约束 | 无 RTC(依赖平台下发 ts);CH32V208 栈紧张;Loop/DBN 固件禁止混刷 |
---
## P0 — 发布后稳固(目标 V1.1.0,约 2~4 周)
### P0.1 BLE 透传路径重构收尾 🔴(在途)
当前工作区改动把 0xC0 传感帧的 BLE 转发从"置 flag 延迟消费"改为"立即 notify"。收尾必须核对三件事:
1. **帧消费方真值表**0xC0 帧现在有 **三个消费方**TCP JSON 回调 / MQTT `iot_sensor_ingest` / BLE notify)。2026-07-15 的"陈旧快照 34 秒"事故根因就是消费路径数据源分裂——BLE 加入后必须重画一张"谁消费、谁清理(InitPkgUart"的真值表,确保:
- 每条路径都能拿到帧(同源汇聚不漏帧);
- 帧最终一定被清理(无滞留 → 无假"新帧");
- BLE ACS 分支改 Magic 为 0x8F 后,MQTT/TCP 路径若还要读同一缓冲,读到的是被改过的帧头(**待确认是否有影响**)。
2. `set_response_tran_to_notify()` 新增返回值的语义与调用方检查。
3. 板上验证:BLE 小程序连上时,TCP/MQTT 上报不受影响;BLE 断开后无帧泄漏。
### P0.2 代码 TODO 清剿
| 位置 | 问题 | 优先级 |
|------|------|--------|
| `iot_mqtt_srv.c:753` | `loop_ok[i] = 1` 硬编码,未取 Loop MCU 真实线圈状态 → 平台看到的线圈健康度是假的 | 🔴 高 |
| `net_srv.c:528` | MQTT 接收长度未做溢出防护(`len-received` 越界风险)| 🔴 高 |
| `storage.c:494`DBN | Flash_Model 读失败无停机/降级保护 | 中 |
| `net_srv.c:1225` | 序列号修改命令未实现 | 中 |
| `dbn_ble_srv.c:870` | ACS timeout `min→ms` 换算待确认(当前 ×60×100,疑似按 10ms tick,需对时钟源) | 中 |
| `main.c`Loop)多处 | "不整个设备复位,只复位蓝牙以外部分"——历史注释,评估后关闭或立项 | 低 |
### P0.3 回归验证清单(配合 vd_test_fixture 工装)
- [ ] 长车双线圈场景复测:car_leave 事件后**下一条** loop_data 的 iscar 必须已翻 false(同源验证)
- [ ] event_report 断网入队 → 重连补报闭环;5s 超时重发 ×3 后的放弃行为
- [ ] 时钟同步:校准前 ts=上电秒数的平台侧兼容;mstick 49.7 天回绕仿真(gcc 隔离单测)
- [ ] MQTT 稳定性:>512B 帧、PINGREQ 保活、broker 主动踢线后的重连节奏
- [ ] 拨码/灵敏度/hold_time/relay_delay 全参数配置读写一致性(BLE 链路 + MQTT 链路交叉验证)
**P0 出口条件**:以上全绿 → 两侧 `FIRMWARE_VER` 升 1.1 → 整机 tag v1.1.0。
---
## P1 — 传感数据上云闭环(目标 V1.2.x,约 1~2 月,与 edc_server 平台侧并行)
这是你"传感数据云 + 业务平台"目标的主线,设备侧固件已基本就绪,重心在平台侧消费。
### P1.1 平台侧对接(edc_server
- **event_report 消费契约**:平台先落库、后 ACK(code=0)——严禁先 ACK 后落库(设备出队后事件不可再生)
- **loop_data 落库 + 可视化**variation 有符号曲线(正=车/裕量,负=基线污染——免费的诊断维度)、频率漂移趋势图;锯齿波形态识别(5s 基线阶跃是正常形态,别当故障)
- **流量/占用 API**:基于 car_enter/car_leave 事件 + 通过时间/车间距(50ms 单位)产出分通道流量计数、占用率、平均通过时间
- **设备台账**initialize 上线登记、心跳离线判定(阈值=心跳间隔×3)、report_config 远程下发界面
### P1.2 脱机日志子系统 🆕(W25Qxx SPI NOR
**硬件底子**DBN 外挂 SPI NORSPI1)。默认 **W25Q3232Mbit = 4MB,已确认)****兼容 W25Q80 / W25Q64 / W25Q128 / W25Q256**,上电先读 JEDEC ID 识别存储类型,再按类型映射各分区容量。
**分区规划(顺序:参数区 → OTA 镜像暂存区 → 事件日志区 → 传感快照区)**
| 分区 | 容量策略 | 用途 |
|------|---------|------|
| 参数区 | **固定 64KB**0x000000 起,现用 <1KB | 现有配置,留余量 |
| OTA 镜像暂存区 | **固定 512KB** | Loop 固件(64KB×2 版本回滚)+ 预留 DBN 镜像 |
| 事件日志区 | **随存储类型**(见下表) | 环形,关键事件流,不被快照冲掉 |
| 传感快照区 | **随存储类型**(= 总容量 − 参数区 − OTA − 事件日志区) | 环形,0xC0 帧原样落盘 |
**存储类型 ↔ 容量映射表**(上电读 JEDEC ID 后选档):
| JEDEC ID | 芯片 | 总容量 | 参数区 | OTA 暂存 | 事件日志区 | 传感快照区 |
|----------|------|--------|--------|----------|-----------|-----------|
| EF 40 14 | W25Q80 | 1MB | 64KB | 512KB | **128KB**~4000 条) | **320KB** |
| EF 40 16 | W25Q32(默认) | 4MB | 64KB | 512KB | **256KB**~8000 条) | **~3.19MB** |
| EF 40 17 | W25Q64 | 8MB | 64KB | 512KB | **512KB**~16000 条) | **~6.94MB** |
| EF 40 18 | W25Q128 | 16MB | 64KB | 512KB | **1MB**~32000 条) | **~14.44MB** |
| EF 40 19 | W25Q256 | 32MB | 64KB | 512KB | **2MB**~64000 条) | **~29.44MB** |
- 事件日志区容量随芯片**等比翻倍**(128KB→2MB),保证日志保留时长不随硬件降配而缩水
- 传感快照区吃剩余容量;W25Q80(1MB)为最小可部署配置,快照仅 320KB(约 5200 条 @64B),适合纯日志场景
- 分区边界在**上电初始化时**由 JEDEC ID 计算得出,offlog/快照代码按运行时分区表寻址,不写死
**两条日志流分开存**
1. **事件流(必录,低速率)**car_enter/car_leave(含时间量)、线圈断线/恢复、继电器动作、上电/复位(含复位原因)、MQTT/TCP 连接与断开、event_report ACK 超时/重发/放弃、配置变更(含来源:BLE/MQTT/TCP)、灵敏度换档、**时钟同步锚点**、固件升级开始/结果、日志清除操作(审计自记录)
2. **快照流(环形可覆盖)**:0xC0 帧二进制原样 + 头部(序号/boot_seq/mstick),~64B/条,**记录节奏与网络上报同频**(空闲按 interval、活动 300ms、car 沿立即)——直接挂在 `iot_sensor_ingest()` 同源出口,天然与上报一致
**容量预算****以 W25Q32 为基准**:事件日志 256KB / 快照区 ~3.19MB ≈ 5.2 万条 @64B;其他芯片按映射表等比缩放——W25Q64 快照保留时长 ×2.2W25Q80 快照仅 ~5200 条,**事件日志保留时长不缩水**):
| 场景 | 落盘节奏 | 保留时长(W25Q32) |
|------|---------|---------|
| 最坏情况:快档 300ms 连续压满 | 3.3 条/s | ~4.4 小时 |
| 繁忙出入口(日均 2000 车次,每车次 ~15 条突发 + 空闲 30s 底噪) | ~3.3 万条/天 | ~1.5 天 |
| 一般车道(空闲 30s 为主) | ~2900 条/天 | **~18 天** |
若现场要求更长保留:把空闲档快照落盘间隔与上报解耦(如落盘固定 60s),或快照只存"有沿事件前后 ±N 条"(预触发环形),容量立刻翻数倍——**实施时按现场需求选**。
**⚠ 无 RTC 的时间戳设计(最容易踩的坑)**:断电后 mstick 归零,纯 Unix 时间戳不可行。方案:每条记录带 `(boot_seq, mstick)`;每次时钟同步成功时写一条**时间锚点事件**boot_seq ↔ unix_ts 映射);导出时由平台/小程序用锚点回算绝对时间。从未同步过的 boot 段只有相对时间——协议文档里要写明这个语义。
**磨损与 RAM**:环形顺序写天然磨损均衡(4KB sector 顺序擦除,W25Q 10 万次擦写寿命无忧);**复用现有 `SPI_FLASH_BUF[4096]`,不新增大缓冲**CH32V208 SRAM 紧张的教训)。
### P1.3 日志导出与管理 🆕
**导出通道(三条,统一按序号分页,不按时间——时间不可靠)**
| 通道 | 机制 | 说明 |
|------|------|------|
| MQTT 自动补报 | 断网期间事件流落盘,重连后按序号续传 | 现有 16 深 RAM 队列扩展为 flash-backed,溢出转日志区;与 event_report ACK 闭环衔接 |
| MQTT/TCP 命令拉取 | `log_query {stream, start_seq, count}` 分页 | 复用现有 cmd 分发框架;注意 Publish≤500B 分批(MSS=576 教训) |
| BLE 小程序读取 | 复用 0x8F 通道新增日志读命令 | BLE MTU 分包(20~244B),小程序侧分页 UI |
**管理命令**
- `log_stat`:各流的序号区间、条数、容量占用
- `log_clear {stream}`:**需鉴权**;分流清除;清除动作本身写入事件流(审计——谁在什么时候清了日志)
- 自动管理:环形覆盖为常态,无需人工干预;满不停写
### P1.4 远程 OTA 🆕(路线已定:先走现网 MQTT,底层复用 ISP 透传)
**关键认知**BLE 给 Loop MCU 升级 = "镜像经手机流式送到 CH32V208 → ISP 串口透传刷写"。远程 OTA 只是把"送镜像"的传输层从 BLE 换成 MQTT,**ISP 透传底层完全复用**——且 Loop MCU 的 OTA 根本不需要 CH32V208 做 A/B 分区,镜像只是路过。
**分两档,难度和节奏完全不同:**
**① Loop MCU (AT32F421) 远程 OTA —— v1.2.x 落地**
采用**先存后刷**(优于流式直透):
1. 平台 MQTT 分片下发(每片带 offset+CRC,≤500B/片,支持断点续传)→ 写入 W25Qxx 暂存区
2. 全镜像 CRC 校验通过后,才启动 ISP 透传本地刷写(复用 BLE OTA 的透传状态机)
3. 抗网络抖动:下载阶段断网无所谓,续传即可;刷写阶段纯本地,窗口短
4. 暂存区保留上一版镜像 → 支持回滚重刷
**安全底线(会车产品,升级失败=继电器行为不可控)**
- 升级窗口检查:有车压线圈时告警/延迟启动——**待定策略**
- ISP 期间 Loop MCU 停止检测,继电器处于什么状态?(复位后 GPIO 默认态应为断开=常开安全侧,**待板上验证**)
- 刷写失败自动重试 ×3,仍失败 → event_report 告警 + 保持 ISP 可重入(AT32 ISP bootloader 兜底,不会真砖)
- 升级开始/结果写入事件日志
**② DBN (CH32V208) 自身远程 OTA —— 方案评审先行,落地后置**
难点:128KB Flash 装不下 APP 双分区;现有 BLE OTA 走 WCH "OnlyUpdateApp" IAP 框架(bootloader 固定只认 BLE)。候选路线:
- (a) 镜像下到 W25Qxx 暂存 + 校验 → 改 bootloader 支持从外部 Flash 搬运(**动 bootloader 风险高**,刷坏只能拆壳烧录)
- (b) RAM 驻留搬运代码自刷写(掉电=砖,不推荐)
- (c) 维持现状:DBN 升级仍走 BLE(现场人员),只有 Loop 支持远程——**最稳妥的过渡态**
先出方案评审文档比选,v1.2.x 期间不阻塞 ①。
**③ 4G 通道下的 OTA**4G 模组(TTL 对接 UART1)跑 MQTT 后,①②的分片下载协议原样复用——传输层无关是这套设计的出发点。注意 4G 流量成本:64KB 镜像 + 重传开销可忽略,但快照流补报要设流量上限。
### P1.5 设备侧其他补强
- **loop_data 增补字段**(若 P1.1 分析需要):如 Origin 绝对值上报,便于平台重建基线轨迹——走协议 V1.06 流程,两侧同版本配套
- **DBNMQTTool** 同步:日志拉取/OTA 分片下发的模拟与断言(工具先行,固件后到)
### P1.6 4G 上云通道(UART1 RFU 启用,可后置到 P3
- 模组选型(Cat.1 足够:EC800 系列/Air780 级别),AT 透传 vs 模组内置 MQTT 两条路线对比
- 网口 MQTT 与 4G MQTT 复用同一 `iot_mqtt_srv` 状态机,仅换传输层——架构上先留接口
---
## P2 — 检测算法深化(Loop 侧,目标 V2.x,约 2~3 月)
### P2.1 抗变频器/电磁干扰 🎯(你的长期主目标)
1. **先取证再动手**:用工装+现场采集受扰线圈的 CAPVD 原始序列(10ms 粒度),确认干扰形态(周期性拍频 / 白噪 / 突发脉冲)——**待现场验证**
2. **频点错开**:4 路线圈两级调频电容(33nF/10nF)已有硬件基础,上电自检各路振荡频率,间距不足时自动切档,抑制相邻串扰
3. **算法层**:现有 IIR+斜率限幅+进入确认对突发脉冲已有基础免疫;针对周期性拍频评估陷波/中值预滤(注意 10ms tick 下的计算预算)
4. 产出:抗干扰测试报告(干扰源型号、距离、频谱、误检率前后对比)
### P2.2 双线圈测速 + 车型粗分类
- 利用现有 misc 时间量(通过时间/车间距,50ms 单位)+ 已知线圈间距 → 速度估计
- 信号长度(占用时间×速度)→ 车长 → 粗分类(小车/大车/拖挂)
- 拖挂车"半截车"识别:单通道内 variation 双峰形态检测——直接服务会车防砸
- 输出通道:event_report 新增 speed/class 字段(协议升版)
### P2.3 方向判别
- 线圈 1→2 与 2→1 的触发时序 → 方向语义,供会车/双向流量使用
- Loop 侧输出还是平台侧算:**倾向 Loop 侧**(时序精度 50ms 内,平台侧受上报调度抖动影响)
---
## P3 — 会车控制与融合(依赖 P1/P2 产出)
- **会车控制逻辑平台侧先行**:基于多台 DLD960 的 event_report(有 ACK 闭环,可靠交付)做单通道红绿灯会车状态机;业务逻辑只认 event_reportloop_data 仅做展示——两通道职责不混
- **异常分支优先设计**:设备离线(心跳超时)→ 会车灯降级策略;继电器粘连检测(relay_count 与命令数比对);车辆长时间停留(hold_time 超时全通道重启的平台侧感知)
- **单机版会车评估**:DLD960 四通道 + 继电器本地联动能否覆盖小型场景(无平台依赖,可靠性更高)——出对比方案:纯平台 / 纯单机 / 混合
- **雷达/相机融合接口预留**:扩展 UART1 或网口接入目标列表,融合仲裁放平台侧
---
## 版本映射与节奏
| 版本 | 内容 | 前置 |
|------|------|------|
| v1.1.0 | P0 全部(BLE 收尾 + TODO 清剿 + 回归全绿) | — |
| v1.2.x | P1 设备侧(脱机日志 + Loop 远程 OTA + 协议 V1.06 | edc_server 对接联调 |
| v2.0.0 | P2 算法深化(抗干扰 + 测速分类 + 方向) | 现场干扰数据采集 |
| v2.x | P3 会车控制 | P1 平台 + P2 方向判别 |
## 风险与待现场验证
| # | 风险 | 应对 |
|---|------|------|
| 1 | BLE 重构改动帧消费时序,复发"不同源"类 bug | P0.1 真值表 + 长车复测强制过 |
| 2 | 变频器干扰形态未知,算法方案可能推倒重来 | 先采数据后设计,不拍脑袋 |
| 3 | DBN 自身远程 OTA 无安全落点(128KB 无 A/B、bootloader 只认 BLE | 过渡态:DBN 走 BLE、Loop 走远程;bootloader 改造单独评审 |
| 4 | 协议再升版(V1.06)又是双侧死绑定 | 沿用 Len 字节区分格式的兼容方案,发布走配套矩阵 |
| 5 | 无 RTC,脱机日志绝对时间不可靠 | boot_seq+mstick+时钟锚点回算;协议明示"未同步段仅相对时间" |
| 6 | 日志高频写与 MQTT/BLE 共抢主循环与 SPI 总线 | 快照落盘按 page 缓写、擦除放空闲窗口;实测不达标就降快照档频率 |