feat(vd960DBN): 传感快照区落地 snapshot.c + BLE SNAP_STAT/QUERY/CLEAR

- snapshot.h/c: 64B 定长 SnapRec (头部16B + 4x12B 0xC0线圈数据原样)
  环形分区独立于事件日志, 快照区 = 总容量 - 固定区576KB - 事件区
- 线程模型: USART2 ISR 只打包+RAM暂存(8深满丢新), 主循环 snap_flush 落盘
  (iot_sensor_ingest 在中断上下文, SPI 45ms 擦除严禁进中断)
- dbn_ble_srv: SNAP_STAT(0x28)/SNAP_QUERY(0x29)/SNAP_CLEAR(0x2A)
  QUERY 上限 2 条 (64x2+2=130B, ODR 教训防御)
- iot_mqtt_srv: ingest 挂 snap_enqueue, publish_sensor 挂 snap_flush
  (放在 READY 检查前, 断网照常落盘)
- peripheral_main: offlog_init 后加 snap_init
- 清空审计: 写事件流 log_clear payload[0]=2
- 测试: test_snapshot.c 8 例全过, offlog/ble_offlog 回归全过
- 文档: DLD960_BLE协议 V1.02 + ROADMAP P1.2 状态 + devlog
This commit is contained in:
wangfq
2026-08-12 17:40:14 +08:00
parent a8120cc852
commit 92887a3d92
12 changed files with 1123 additions and 8 deletions
+87 -5
View File
@@ -1,8 +1,8 @@
# DLD960 BLE 通信协议(脱机事件日志)
# DLD960 BLE 通信协议(脱机事件日志 + 传感快照
> 版本: V1.012026-08-12,分包上限改为随协商 MTU 动态)
> 版本: V1.022026-08-12新增传感快照 3 命令;分包上限随协商 MTU 动态)
> 适用: vd960DBNCH32V208WCH BLE 协议栈)
> 用途: 小程序/APP 经蓝牙读取设备本地 W25Q32 环形事件日志(离线取证:区分设备真复位 vs MQTT 断连重连)
> 用途: 小程序/APP 经蓝牙读取设备本地 W25Qxx 环形日志(离线取证:事件流区分真复位 vs MQTT 断连重连;快照流回放 0xC0 传感波形
---
@@ -43,6 +43,9 @@ Magic | Header | Data | CheckByte
| `0x25` | `OFFLOG_STAT` | APP→设备 | 查询脱机事件日志统计(分页定位) |
| `0x26` | `OFFLOG_QUERY` | APP→设备 | 按全局序号分页拉取日志记录 |
| `0x27` | `OFFLOG_CLEAR` | APP→设备 | 清除日志(审计留痕) |
| `0x28` | `SNAP_STAT` | APP→设备 | 查询传感快照统计(分页定位) |
| `0x29` | `SNAP_QUERY` | APP→设备 | 按全局序号分页拉取快照记录 |
| `0x2A` | `SNAP_CLEAR` | APP→设备 | 清除快照(审计写入事件流) |
> 与 MQTT V1.06 / TCP JSON V1.02 的 `log_stat` / `log_query` / `log_clear` 语义一致,通道不同。
@@ -120,7 +123,84 @@ Magic | Header | Data | CheckByte
---
## 6 记录格式(OfflogEvt32B 定长,小端
## 6 传感快照日志(0x28/0x29/0x2AV1.02 新增
**用途**:0xC0 传感帧(4 线圈波形)按上报节奏落盘,与事件日志**分区独立**(快照区 = 总容量 − 固定区 576KB − 事件区)。断网期间波形照常记录,可离线回放。
**线程语义(设备侧)**:采集路径(USART2 中断)只做打包 + RAM 暂存(8 深,满丢新),主循环每轮 `snap_flush()` 落盘——QUERY 读到的是已落盘记录。
### 6.1 查询快照统计 `SNAP_STAT` (0x28)
**请求 data** 无(`Len=1`)。
**响应 data19B,全小端):** 与 §3 `OFFLOG_STAT` 布局相同:
| 偏移 | 长度 | 字段 | 说明 |
|------|------|------|------|
| 0 | 1 | `status` | `0x00`=OK`0x01`=快照未启用 |
| 1 | 2 | `boot_seq` | 当前启动序号 |
| 3 | 4 | `count` | 有效记录条数(0~capacity |
| 7 | 4 | `capacity` | 容量上限(**随芯片动态**W25Q32=48064 / W25Q64=105408 / W25Q128=220096 / W25Q256=449472 |
| 11 | 4 | `seq_first` | 最早一条全局序号(count=0 时=0) |
| 15 | 4 | `seq_last` | 最新一条全局序号 |
### 6.2 分页拉取快照 `SNAP_QUERY` (0x29)
**请求 data5B):**
| 偏移 | 长度 | 字段 | 说明 |
|------|------|------|------|
| 0 | 4 | `start_seq` | 起始全局序号(小端,含);越界返回 0 条 |
| 4 | 1 | `count` | 拉取条数,**上限 2**64B×2+2=130B ≤ 单包缓冲),超限按 2;0 按 2 |
**响应 data**
| 偏移 | 长度 | 字段 | 说明 |
|------|------|------|------|
| 0 | 1 | `status` | `0x00`=OK`0x01`=快照未启用;`0x02`=请求帧过短 |
| 1 | 1 | `count` | 本次实际返回记录条数(0~2) |
| 2 | N×64 | 记录 | `count` 条 SnapRec 原始结构(小端,见 §6.4) |
记录顺序 = 逻辑序号升序。QUERY 响应最大 130BMTU=96 时 2 包(87+43 dat);MTU≥103 时 2 包(94+36 dat)。
### 6.3 清除快照 `SNAP_CLEAR` (0x2A)
**请求 data** 无。**响应 data1B):** `status``0x00`=OK。
> ⚠ **高风险操作**:清除动作本身写入**事件流** `log_clear` 审计(payload[0]=2=快照流,不可清除)。
> ⚠ **阻塞时长随芯片**W25Q32 快照 751 扇区 SPI 擦除 ≈ 34s,期间主循环阻塞。请勿高频调用。
成功后 `SNAP_STAT``count` 归 0`seq_last` 继续递增(序号不复位)。
### 6.4 快照记录格式(SnapRec64B 定长,小端)
| 偏移 | 长度 | 字段 | 说明 |
|------|------|------|------|
| 0 | 1 | `magic` | `0xA6`(区别于事件 `0xA5` |
| 1 | 1 | `len` | 线圈数据有效长度 = coil_count×120~48 |
| 2 | 1 | `flags` | bit0=分包帧(预留) |
| 3 | 1 | `rsvd` | 保留(0 |
| 4 | 4 | `seq` | 全局序号(跨 boot 递增) |
| 8 | 4 | `ts_ms` | boot 内相对时间(ms,采集时刻) |
| 12 | 2 | `boot_seq` | 所属启动段 |
| 14 | 2 | `rsvd2` | 保留(0 |
| 16 | 48 | `coils` | 4×12B 线圈数据,与 0xC0 线上格式一致 |
**线圈 12B 单元**(与 0xC0 帧内每路线圈完全一致):
| 偏移(单元内) | 长度 | 字段 | 说明 |
|------|------|------|------|
| 0 | 1 | `cfg` | freq_level(2) + direction(1) + freq_type(1) + sensitivity(4) |
| 1 | 1 | `cond` | condition(4) + loop_state(1) + car_state(1) + misc_type(2) |
| 2 | 3 | `freq` | 频率,3B 小端无符号 |
| 5 | 3 | `variation` | 变化量,3B 小端有符号补码(= Origin CAPVD |
| 8 | 4 | `misc` | 杂项 4B 小端(misc_type=0 时=通过时间,50ms 单位) |
> 绝对时间回算:用事件流 `time_anchor`boot_seq ↔ unix_ts 映射)+ 本记录 `boot_seq`/`ts_ms`。未同步段仅相对时间。
---
## 7 记录格式(OfflogEvt32B 定长,小端)
| 偏移 | 长度 | 字段 | 说明 |
|------|------|------|------|
@@ -154,8 +234,10 @@ Magic | Header | Data | CheckByte
---
## 7 版本历史
## 8 版本历史
| 版本 | 日期 | 说明 |
|------|------|------|
| V1.00 | 2026-08-10 | 脱机事件日志 3 命令:OFFLOG_STAT / OFFLOG_QUERY / OFFLOG_CLEAR |
| V1.01 | 2026-08-12 | 分包上限改为随协商 MTU 动态:`chunk = min(MTU-9, 94)`;修复 Too large noti 丢包 |
| V1.02 | 2026-08-12 | 新增传感快照 3 命令:SNAP_STAT / SNAP_QUERY / SNAP_CLEAR0x28/0x29/0x2A |