6.6 KiB
6.6 KiB
下位机协议实现完备性分析
分析日期: 2026-03-15
对照文档: 采集端通信协议规范 v2.1.3 (2026-02-07)
分析对象: prj/TCPClient 工程全部源码
前提说明
协议规范描述了 ZMQ PUB-SUB + JSON 架构,但实际 MCU 与配置端服务器之间已约定采用自定义二进制 TLV 帧格式(0x55AA Magic + CRC16-MODBUS)通过双 TCP 通道(5511 控制 / 5512 数据)通信。以下审计基于 TLV 协议层面进行。
一、接收端(服务器 → 下位机,控制通道 5511)
| # | 功能 | 状态 | 说明 |
|---|---|---|---|
| 1 | ConfigCommon 全量配置 | ✅ 已实现 | TYPE_CONFIG_COMMON(0x20) 完整解析 23 字节 |
| 2 | Config2D 全量配置 | ✅ 已实现 | TYPE_CONFIG_2D(0x22) 完整解析 61 字节全部字段 |
| 3 | Config1D 全量配置 | ✅ 已实现 | TYPE_CONFIG_1D(0x23) 完整解析 26 字节 |
| 4 | 设备 ID 分配 | ✅ 已实现 | TYPE_DEVID_ASSIGN(0x05) 解析后断线重连 |
| 5 | 判定结果接收 | ✅ 已实现 | TYPE_DETECTION_RESULT(0x40) → detect_cb 回调 NG/OK |
| 6 | 帧请求(截图/采集) | ✅ 已实现 | TYPE_TEMP_FRAME(0x10) 请求 → temp_req_cb 回调 |
| 7 | ACK 响应接收 | ✅ 已实现 | TYPE_ACK_PAYLOAD(0x30) 在 TLV 解析循环内可识别 |
| 8 | 部分参数更新 | ❌ 未实现 | 规范 §4.2.2 定义 UpdateParameters 键值点更新,无对应 TLV 类型 |
| 9 | 控制命令组 | ❌ 未实现 | Start/Stop/Pause/Resume/GetStatus/GetConfiguration/SwitchPipelineMode/ResetStats 共 8 个控制命令均无解析 |
| 10 | 文件传输 | ❌ 未实现 | 规范 §3.3.1 {deviceId}/file 无对应功能 |
| 11 | 时间同步 | ⚠️ 仅定义 | TYPE_SYNC_TIME(0x03) 已定义常量但未在 parse_and_dispatch_tlv 中处理 |
二、发送端(下位机 → 服务器,数据通道 5512)
| # | 功能 | 状态 | 说明 |
|---|---|---|---|
| 1 | 握手 | ✅ 已实现 | TYPE_HANDSHAKE(0x01) 连接后立即发送(UUID + 硬件/固件版本) |
| 2 | 心跳 | ✅ 已实现 | TYPE_HEARTBEAT(0x02) 每 2s 发送 UpTime + CpuLoad + MemUsage |
| 3 | ACK 应答 | ✅ 已实现 | TYPE_ACK_PAYLOAD(0x30) 响应带 FLAG_ACK_REQ 的帧 |
| 4 | 温度帧(2D 触发帧) | ✅ 已实现 | TYPE_TEMP_FRAME(0x10) 零拷贝发送 + 自动分片 |
| 5 | 原始帧上报 | ❌ 未实现 | TYPE_RAW_FRAME(0x11) 仅定义常量,无发送逻辑 |
| 6 | 设备注册 | ❌ 未实现 | 规范 §8.1 DeviceRegisterEvent 注册事件未发送 |
| 7 | 状态上报 | ❌ 未实现 | 规范 §5.3.5 定期 AcquisitionStatusEvent 未实现 |
| 8 | 命令处理回执 | ❌ 未实现 | 规范 §5.3.3 ChangedEvent 回执未实现 |
| 9 | Masked 帧 | ❌ 未实现 | 不区分 Triggered/Masked/Live 帧类型发送 |
三、核心处理逻辑
| # | 功能 | 状态 | 说明 |
|---|---|---|---|
| 1 | 2D 滑窗 ROI 提取 | ✅ 已实现 | 积分图 + 滑窗搜索最大平均温度区域,提取 TargetWidth × TargetHeight |
| 2 | 内部温度触发 | ✅ 已实现 | TriggerRoi 区域 Max/Avg vs TriggerTemperatureThreshold |
| 3 | Burst 连拍 | ✅ 已实现 | BurstCount + InternalIntervalMs 状态机 |
| 4 | NG GPIO 输出 | ✅ 已实现 | PA8 脉冲,宽度从 NGioDelay 配置读取 |
| 5 | 帧分片 | ✅ 已实现 | 超 1400B 自动分片,最后一片设置 FLAG_LAST_FRAGMENT |
| 6 | CRC16 校验 | ✅ 已实现 | 收发双向 CRC16-MODBUS 校验 |
| 7 | 自动重连 | ✅ 已实现 | 检测断线后 3s 重连双通道 |
| 8 | 阈值蒙版输出 | ⚠️ 部分 | 滑窗搜索时低温 → 90 替换,但规范要求输出数据中低于 MaskThreshold → 替换为 0 |
| 9 | 触发延迟 (DelayMs) | ✅ 已实现 | burst_delay_pending + burst_delay_until_ms 状态机实现,消抖后延迟再连拍 |
| 10 | 外部 GPIO 触发 | ✅ 已实现 | PA15/EXTI15 上升沿 EXTI 中断,EXTI15_10_IRQHandler + burst_debounce_pending 消抖 + TriggerDelayMs 延迟 |
| 11 | Alarm GPIO | ❌ 未实现 | AlarmGpioLine/AlarmHoldMs 字段已解析但无 GPIO 驱动 |
| 12 | 1D 数据采集处理 | ✅ 已实现 | S1D_IDLE / S1D_DEBOUNCE / S1D_COLLECTING 完整状态机,内/外部触发、预环形缓冲、切片、发送 |
| 13 | Training 模式 | ❌ 未实现 | 字段可解析但无训练采样功能 |
| 14 | 消抖 (DebounceIntervalMs) | ✅ 已实现 | 2D 外部触发消抖与 1D HighTimerLimit 均已实现 |
四、汇总统计
| 类别 | ✅ 已实现 | ⚠️ 部分 | ❌ 未实现 |
|---|---|---|---|
| 接收(控制通道) | 7 | 1 | 3 |
| 发送(数据通道) | 4 | 0 | 5 |
| 处理逻辑 | 10 | 1 | 3 |
| 合计 | 21 | 2 | 11 |
五、优先级建议
P0 — 必须补齐(影响基本功能验证)
- 控制命令接收 — 至少实现
StartAcquisition/StopAcquisition/GetStatus,否则服务端无法控制采集启停 - 状态上报 — 周期性上报运行状态给服务端,否则服务端无法监控设备健康
- 触发延迟 (DelayMs) — 简单改动,在触发检测到后 delay 再开始采集
- 阈值蒙版输出 — 提取后的数据中
val < MaskThreshold→ 替换为 0
P1 — 高优先级(完善核心流程)
- 外部 GPIO 触发 — 实际产线通常用外部触发信号
- Alarm GPIO — 独立于 NG GPIO 的报警输出
- 命令处理回执 (ChangedEvent) — 服务端需要确认命令被执行
- 设备注册事件 — 完整的上线握手流程
P2 — 可延后
- 1D 数据处理(如果当前只做 2D 热成像)
- Training 模式
- 文件传输
- 原始帧/Masked 帧分类发送
- 时间同步
- 部分参数更新
六、涉及源文件清单
| 文件 | 职责 |
|---|---|
Middle/QDXnetworkStack/qdx_protocol.h |
协议常量、TLV 类型定义、结构体 |
Middle/QDXnetworkStack/qdx_protocol.c |
CRC16、帧构建、序列化工具 |
Middle/QDXnetworkStack/qdx_tcp_logic.h |
TCP 逻辑层 API 声明 |
Middle/QDXnetworkStack/qdx_tcp_logic.c |
双通道连接管理、TLV 解析/分发、心跳、帧发送 |
Middle/QDXnetworkStack/qdx_preprocess.h |
预处理 API 声明 |
Middle/QDXnetworkStack/qdx_preprocess.c |
滑窗 ROI、温度过滤、内部触发检测 |
Middle/QDXnetworkStack/qdx_port.h |
HAL 抽象层声明 |
Middle/QDXnetworkStack/qdx_port.c |
FreeRTOS + WCHNET HAL 实现 |
User/main.c |
应用主逻辑:RTOS 任务、Burst 状态机、NG GPIO、测试模式 |
Debug/dvp.c |
DVP 图像采集驱动 |
Debug/mini212g2.c |
Mini212G2 传感器 UART 驱动 |