上传文件至 /
This commit is contained in:
@@ -1,19 +1,21 @@
|
||||
---
|
||||
tags: []
|
||||
aliases:
|
||||
- "**前端感知系统通信协议 (ICD) V2.1**"
|
||||
- "**前端感知系统通信协议 (ICD) V2.2**"
|
||||
date created: 星期一, 十二月 8日 2025, 9:01:09 上午
|
||||
date modified: 星期一, 十二月 8日 2025, 6:08:02 晚上
|
||||
date modified: 星期五, 一月 9日 2026, 7:27:23 晚上
|
||||
---
|
||||
|
||||
# **前端感知系统通信协议 (ICD) V2.1**
|
||||
# **前端感知系统通信协议 (ICD) V2.2**
|
||||
|
||||
文档编号: FES-SW-ICD-002
|
||||
|
||||
版本: V2.1 (Integer-Only + TaskID + ACK/Status Clarified)
|
||||
版本: V2.2 (Header HCS/Epoch/DestID + Control Ext + Data Snapshot)
|
||||
|
||||
说明:版本以本页“版本”字段为准;文档编号用于配置管理索引,不随次版本必然变化。
|
||||
|
||||
备注:当前文件名包含 “V2.1” 属历史遗留,正文内容为 **V2.2** 规范;互操作时以 `ProtoVer` 字段为准。
|
||||
|
||||
适用架构: Host (CPU/GPU) <-> Device (Pure Logic FPGA)
|
||||
|
||||
物理链路: 10Gbps Ethernet (UDP/IP)
|
||||
@@ -24,11 +26,12 @@ date modified: 星期一, 十二月 8日 2025, 6:08:02 晚上
|
||||
|
||||
### **0.1 变更综述 (Executive Summary)**
|
||||
|
||||
V2.0/2.1 协议并非 V0.1 的简单增量更新,而是基于 **“软件定义雷达 (SDR)”** 与 **“异构计算适配 (Heterogeneous Computing)”** 理念的架构级重构。本次迭代的核心目标是解决 V0.1 在**高带宽吞吐瓶颈**、**软硬件强耦合**及**可靠性机制缺失**三大方面的系统性缺陷。
|
||||
本版本关注点(协议层面):
|
||||
|
||||
V2.0 引入了 **RFC 标准化报文头**、**混合对齐策略**、**微单位整数物理层**以及 **RMA 维护通道**,确保系统能够支撑 10Gbps 线速传输,并具备向后兼容的长期演进能力。
|
||||
|
||||
V2.1 在 V2.0 的基础上补齐了 **Status/ACK 报文规范**,明确 **SeqID 的作用域(按流递增,非全局)**,并引入 **TaskID** 以支持并发多任务(多 CPI/Pulse 流交错)。同时将控制/数据关键物理量字段统一为 **整数/微单位整数**,以满足“FPGA 只能处理整数”的实现约束。
|
||||
- **一致性与可解析性**:统一通用头与 `PayloadLen` 语义,避免解析器进入未定义行为。
|
||||
- **确定性控制闭环**:控制指令具备幂等去重与 ACK 判据,禁止“猜测已执行”。
|
||||
- **高吞吐数据平面**:固定偏移与自然对齐,支持零拷贝 DMA;数据重组以 `Key + Offset/Count` 为准。
|
||||
- **可演进**:保留区受校验保护,新增字段不得改变 RAW Payload 起始偏移。
|
||||
|
||||
### **0.2 详细变更对照表**
|
||||
|
||||
@@ -82,10 +85,10 @@ V2.1 在 V2.0 的基础上补齐了 **Status/ACK 报文规范**,明确 **SeqID
|
||||
|
||||
### **1.1 协议设计哲学:微单位整数 (Micro-Unit Integer)**
|
||||
|
||||
为兼顾后端算法(SPS)对高精度的需求与前端硬件(FPGA)对整数运算的偏好,V2.x 协议废弃了 V1.0 中低精度的量化因子(如 0.0025° LSB),也放弃了早期草案中激进的 IEEE 754 浮点直传方案,转而采用工业界成熟的 **“微单位整数 (Micro-Unit Integer)”** 策略。
|
||||
规范:
|
||||
|
||||
- **后端视角(高精度)**:软件驱动层负责将物理浮点数无损转换为微小单位的整数(例如将 $45.123456^\circ$ 转换为 $45,123,456$)。这一精度($10^{-6}$ 量级)远超物理硬件极限,确保了数据在传输层不引入任何不可忽略的量化噪声。
|
||||
- **前端视角(纯整数)**:FPGA 将所有字段视为标准的定点整数(Integer),无需消耗逻辑资源去实现浮点运算单元(FPU)。波束解算与相位控制将全部通过高效的整数位移与乘加运算完成。
|
||||
- 传输层物理量 **必须** 使用整数表示(频率 Hz、角度 $\mu^\circ$、增益 mdB、时间 ns 等),禁止在协议层引入 IEEE 754 浮点依赖(除非字段明确标注为仿真/回放用途)。
|
||||
- SPS 驱动层 **必须** 负责完成“物理量(浮点)↔ 微单位整数”的无损转换;业务代码 **不得** 直接操作/硬编码协议整数。
|
||||
|
||||
### **1.2 物理量数据类型定义**
|
||||
|
||||
@@ -101,18 +104,12 @@ V2.1 在 V2.0 的基础上补齐了 **Status/ACK 报文规范**,明确 **SeqID
|
||||
|
||||
### **1.3 基础架构约束**
|
||||
|
||||
- **适配器模式 (Adapter Pattern)**:
|
||||
- SPS 主机端的驱动层必须实现 **“物理量 $\leftrightarrow$ 微单位整数”** 的透明转换层。
|
||||
- 上层算法业务代码应始终操作 `double` 或 `float` 类型的物理值,严禁在业务逻辑中直接硬编码整数魔数。
|
||||
- **字节序 (Endianness)**:
|
||||
- 统一采用 **Little-Endian (小端模式)**,符合 x86 主机与大多数 ARM/FPGA 软核的内存布局习惯。
|
||||
- **物理链路与 MTU**:
|
||||
- 物理层:10Gbps SFP+ 光纤以太网。
|
||||
- 传输层:UDP/IP (IPv4)。
|
||||
- MTU:**强烈推荐**开启 **Jumbo Frames (9000 Bytes)**,以降低高带宽回波数据传输时的 CPU 中断频率。
|
||||
- **兼容性要求(必须)**:系统必须支持在 **MTU 1500** 的网络环境中运行,协议语义保持不变(仅表现为数据平面分片包数量增加)。
|
||||
- **分片实现要求(必须)**:发送端必须在**应用层**根据路径 MTU 进行切包,禁止依赖 IP 层分片(IP fragmentation)。
|
||||
- **部署建议**:若网络设备/网卡/虚拟化环境无法开启 Jumbo,则应优先保证链路可达与稳定运行,再通过提升接收端并行度与缓冲区(例如增大 socket 接收缓冲)抵消分片增多带来的开销。
|
||||
规范:
|
||||
|
||||
- **字节序**:所有 `uint16/uint32/uint64/int32/int16` 等多字节字段 **必须** 采用 Little-Endian。
|
||||
- **传输**:UDP/IPv4。
|
||||
- **MTU**:应优先使用 Jumbo(9000)以降低中断与包头开销;系统 **必须** 能在 MTU 1500 下工作。
|
||||
- **分片**:发送端 **必须** 在应用层按路径 MTU 切包,禁止依赖 IP 分片。
|
||||
|
||||
### **1.4 混合对齐策略 (Hybrid Alignment)**
|
||||
|
||||
@@ -120,21 +117,25 @@ V2.1 在 V2.0 的基础上补齐了 **Status/ACK 报文规范**,明确 **SeqID
|
||||
|
||||
1. **控制平面 (SPS $\to$ DACS)**:
|
||||
|
||||
- 采用 **1-Byte Packed (紧凑模式)**。
|
||||
- **理由**:控制指令数据量小,FPGA 解析状态机(FSM)处理逐字节提取(Shift-Register)非常高效,且无需关心 CPU 的缓存行对齐问题。
|
||||
- 采用 **1-Byte Packed (紧凑模式)**(以减少带宽开销)。
|
||||
|
||||
2. **数据平面 (DACS $\to$ SPS)**:
|
||||
|
||||
- 采用 **8-Byte Natural Alignment (自然对齐)**。
|
||||
- **理由**:高通量回波数据必须适配主机 CPU/GPU 的内存访问特性。数据包头(Header)将填充至 Cache Line 边界,确保后续的原始 I/Q 载荷(Payload)起始地址严格对齐,从而支持 **Zero-Copy DMA** 和 **GPU Direct Storage** 技术。
|
||||
- 采用 **8-Byte Natural Alignment (自然对齐)**(以匹配 DMA/Cache Line/向量化读取)。
|
||||
|
||||
---
|
||||
|
||||
## **2. 通用报文头 (Common Header)**
|
||||
|
||||
设计原则:
|
||||
规范(必须):
|
||||
|
||||
所有 UDP 报文(包括控制、状态、回波数据及 RMA 维护包)均强制包含此标准头。该头部长度严格固定为 32 Bytes (256 bits),且内部关键字段均按 8-Byte 自然对齐 排列。这一设计不仅适配 64 位 CPU 的内存访问特性,更完美契合 FPGA 内部常见的 256-bit AXI-Stream 数据总线,确保硬件解析实现“零填充、零移位”的高效处理。
|
||||
- 所有 UDP 报文(Control/Status/Data/RMA)**必须**携带该通用报文头,且位于 UDP Payload 起始处。
|
||||
- 报文头长度 **固定为 32 Bytes**;多字节字段 **必须** Little-Endian。
|
||||
- 接收端 **必须** 先完成以下检查后才允许继续解析:
|
||||
- `Magic Word` 正确;
|
||||
- `HCS` 校验通过(见 2.3.4);
|
||||
- `PayloadLen` 与实际 UDP 应用层长度一致(`UdpPayloadBytes == 32 + PayloadLen`)。
|
||||
- 对齐/保留:`Reserved` **必须** 全 0;接收端遇到非 0 时可告警但不得改变兼容性行为。
|
||||
|
||||
### **2.1 报文头结构定义**
|
||||
|
||||
@@ -145,10 +146,13 @@ V2.1 在 V2.0 的基础上补齐了 **Status/ACK 报文规范**,明确 **SeqID
|
||||
| **8** | **Timestamp** | `uint64` | **PTP 纳秒时间戳**。<br>统一使用 Unix Epoch (1970-01-01 00:00:00 ns),用于全系统时序对齐。 |
|
||||
| **16** | **PayloadLen** | `uint16` | 后续载荷 (Payload) 的有效字节长度。<br>不包含本 Header 的 32 字节。 |
|
||||
| **18** | **PacketType** | `uint16` | 报文类型标识:<br>`0x01`: Control (控制指令)<br>`0x02`: Status (状态遥测)<br>`0x03`: Data (回波数据)<br>`0xFF`: RMA (维护通道) |
|
||||
| **20** | **ProtoVer** | `uint8` | **协议版本号**。<br>高 4 位为主版本,低 4 位为次版本。<br>当前 V2.1 对应 **`0x21`**(V2.0 为 `0x20`)。 |
|
||||
| **20** | **ProtoVer** | `uint8` | **协议版本号**。<br>高 4 位为主版本,低 4 位为次版本。<br>当前 V2.2 对应 **`0x22`**(V2.1 为 `0x21`,V2.0 为 `0x20`)。 |
|
||||
| **21** | **SourceID** | `uint8` | **源设备逻辑 ID** (拓扑解耦的关键)。<br>`0x01`: SPS (主控)<br>`0x10`: DACS-Broadcast<br>`0x11`~`0x1F`: DACS-Unicast |
|
||||
| **22** | **FrameFlags** | `uint16` | **分帧标志位 (Bitmask)**。<br>用于处理跨 UDP 包的巨型数据帧重组。<br>`Bit0`: **SOF** (Start of Frame)<br>`Bit1`: **EOF** (End of Frame)<br>`Bit2-15`: Reserved (0) |
|
||||
| **24** | **Reserved** | `uint8[8]` | **对齐填充**。<br>必须全填 `0x00`。确保 Header 总长为 32 字节,且后续 Payload 起始地址满足 8 字节对齐。 |
|
||||
| **24** | **HCS** | `uint16` | **Header Checksum**。<br>用于校验 Header 前 24 字节,防止 `PayloadLen/PacketType` 位翻转导致解析异常。计算规则见 2.3.4。 |
|
||||
| **26** | **Epoch** | `uint16` | **会话代号 / SessionID**。<br>SPS 每次启动/链路重建递增,用于区分“新会话”与旧包残留,并解决设备重启后 `SeqID` 回绕导致的幂等性冲突。 |
|
||||
| **28** | **DestID** | `uint8` | **目的设备逻辑 ID**。<br>用于多阵面环境下的快速过滤与防错发。广播可使用 `0x10`。 |
|
||||
| **29** | **Reserved** | `uint8[3]` | **对齐保留**。<br>必须全填 `0x00`。确保 Header 总长为 32 字节。 |
|
||||
|
||||
---
|
||||
|
||||
@@ -165,7 +169,7 @@ V2.1 在 V2.0 的基础上补齐了 **Status/ACK 报文规范**,明确 **SeqID
|
||||
+-----------------------------+-----------------------------+
|
||||
| PayloadLen | PacketType | Ver | SrcID | FrameFlags | <--- 紧凑信息区
|
||||
+-----------------------------+-----------------------------+
|
||||
| Reserved (8 Bytes) |
|
||||
| HCS (2B) | Epoch (2B) | DestID (1B) | Reserved (3B) |
|
||||
+-----------------------------+-----------------------------+
|
||||
```
|
||||
|
||||
@@ -173,43 +177,48 @@ V2.1 在 V2.0 的基础上补齐了 **Status/ACK 报文规范**,明确 **SeqID
|
||||
|
||||
#### **2.3.0 SeqID 作用域与回绕处理(必须)**
|
||||
|
||||
- **Direction 的定义**:本协议中 `Direction` 为“**报文在系统角色维度上的单向方向**”,由 `PacketType` 与系统角色隐含确定:
|
||||
`SeqID` 规范(必须):
|
||||
|
||||
- `SeqID` 为 **按逻辑流递增** 的序列号,递增作用域为 `(SourceID, PacketType, Direction)`。
|
||||
- `Direction` 由系统角色与 `PacketType` 隐含确定:
|
||||
- Control(`0x01`):SPS → DACS
|
||||
- Data(`0x03`):DACS → SPS
|
||||
- Status/ACK(`0x02`):通常为 DACS → SPS(对 Control/RMA 的确认与遥测);若实现需要也可 SPS → DACS 发送 Telemetry/Keepalive,但必须使用独立的 SeqID 流。
|
||||
- RMA(`0xFF`):双向(SPS ↔ DACS),两方向必须视为两条独立 SeqID 流。
|
||||
|
||||
- **回绕(Wraparound)处理(必须)**:`SeqID` 为 32-bit 无符号计数器,比较必须采用模 $2^{32}$ 的“半区间”规则,禁止用简单的 `>` 直接比较(避免回绕后误判)。定义:
|
||||
- 回绕比较 **必须** 使用模 $2^{32}$ 的半区间规则(禁止用 `>` 直接比较):
|
||||
- 令 $\Delta = (SeqID_{new} - SeqID_{last})\bmod 2^{32}$(以 `uint32` 自然溢出实现)。
|
||||
- 当 $0 < \Delta < 2^{31}$ 时,判定为 **新包**。
|
||||
- 当 $\Delta = 0$ 时,判定为 **重复包**。
|
||||
- 当 $2^{31} \le \Delta < 2^{32}$ 时,判定为 **旧包/乱序包**。
|
||||
|
||||
- **建议实现**:FPGA/软件统一采用上述规则,确保在 `SeqID` 发生回绕时依然能保持幂等与去重正确性。
|
||||
实现建议:FPGA/软件统一采用上述规则,确保回绕时幂等/去重一致。
|
||||
|
||||
#### **2.3.1 版本控制 (ProtoVer) —— 解决“协议锁死”**
|
||||
|
||||
- **机制**:接收端解析器首先检查 `ProtoVer`。
|
||||
- 若 `ProtoVer == 本地版本`:正常全速解析。
|
||||
- 若 `ProtoVer > 本地版本`:进入兼容模式或报错,防止将新版新增字段误读为乱码,避免未定义的行为(Undefined Behavior)。
|
||||
- **优势**:支持全系统的灰度发布。例如,SPS 可以先升级到 V2.1,同时兼容旧版 V2.0 的 DACS 硬件,无需强制停机全网升级。
|
||||
规范(必须):接收端 **必须** 先检查 `ProtoVer`。
|
||||
|
||||
- `ProtoVer == 本地版本`:按本规范解析。
|
||||
- `ProtoVer > 本地版本`:接收端 **不得** 继续按旧格式“猜测解析”;应进入兼容模式或直接丢弃并告警。
|
||||
- `ProtoVer < 本地版本`:接收端应按向后兼容策略解析(至少保证通用头字段语义不变),并忽略未定义/保留字段。
|
||||
|
||||
#### **2.3.2 源标识 (SourceID) —— 解决“拓扑依赖”**
|
||||
|
||||
- **机制**:彻底解耦 IP 地址。SPS 接收逻辑不再依赖 `src_ip` 进行设备区分。
|
||||
- **ID 分配表**:
|
||||
规范(必须):接收端设备识别 **必须** 以 `SourceID` 为准,不得依赖 `src_ip`。
|
||||
|
||||
ID 分配表:
|
||||
- `0x01`: Signal Processing System (SPS)
|
||||
- `0x11`: DACS - Array 01 (Front)
|
||||
- `0x12`: DACS - Array 02 (Left)
|
||||
- `0x13`: DACS - Array 03 (Right)
|
||||
- **优势**:
|
||||
- **离线分析**:在 Wireshark 脱机分析(pcap 回放)时,即使没有 IP 环境信息,也能精确识别数据来源。
|
||||
- **动态部署**:支持 DHCP 环境下的即插即用,硬件更换无需重新绑定 IP。
|
||||
|
||||
说明:离线分析与 DHCP 环境下均可保持一致识别。
|
||||
|
||||
#### **2.3.3 帧标志 (FrameFlags) —— 解决“数据拼图”**
|
||||
|
||||
- **背景**:一个完整的相干处理间隔(CPI)回波数据可能高达数 MB,远超 UDP MTU(1500/9000 Bytes),必须拆分为多个 UDP 包传输。
|
||||
- **逻辑定义**:
|
||||
规范(推荐):`FrameFlags` 用于显式标记同一“帧”的边界。
|
||||
|
||||
- 一条待重组的上层数据帧(典型为单脉冲回波序列;也可扩展到 CPI 级帧)可能远超 MTU,需拆分为多个 UDP 包。
|
||||
- 标志定义:
|
||||
- **单包帧 (Single Packet)**: 数据很小,一个包发完。
|
||||
- 设置 `SOF=1`, `EOF=1`。
|
||||
- **多包帧 - 首包 (First Packet)**:
|
||||
@@ -218,7 +227,26 @@ V2.1 在 V2.0 的基础上补齐了 **Status/ACK 报文规范**,明确 **SeqID
|
||||
- 设置 `SOF=0`, `EOF=0`。
|
||||
- **多包帧 - 尾包 (Last Packet)**:
|
||||
- 设置 `SOF=0`, `EOF=1`。
|
||||
- **优势**:接收端无需解析 Payload 内容即可在链路层判断帧边界,并能快速发现“帧内丢包/截断”。对于 Data 包,接收端应优先按 6.3 执行相干补零以保持时间轴;对于 Control/RMA 包,校验失败/缺失则由超时重传机制闭环处理。
|
||||
|
||||
接收端处理建议:对 Data 包优先按 6.3 的相干补零策略保持时间轴;对 Control/RMA 由超时重传闭环。
|
||||
|
||||
> 约定说明(推荐):对于 PacketType=0x03 (Data),若实现需要使用 `FrameFlags`,建议将其“帧”边界按 4.4 的 `Key` 维度(即单脉冲回波序列)定义;若仅依赖 `Sample Offset/Sample Count` 重组,则可将 `FrameFlags` 置 0。
|
||||
|
||||
#### **2.3.4 HCS / Epoch / DestID(V2.2 新增)**
|
||||
|
||||
- **HCS (Header Checksum)**:
|
||||
- **覆盖范围**:Header 的前 24 字节(Offset 0..23),即从 `Magic Word` 到 `FrameFlags`。
|
||||
- **算法(必须)**:CRC-16/CCITT-FALSE(Poly `0x1021`,Init `0xFFFF`,RefIn=false,RefOut=false,XorOut `0x0000`)。
|
||||
- **校验失败处理(必须)**:接收端必须直接丢弃该包(静默丢弃),不得继续解析 `PayloadLen`。
|
||||
- **Epoch (SessionID)**:
|
||||
- SPS 必须在每次启动或链路重建时递增 `Epoch`(16-bit 自然回绕)。
|
||||
- DACS/SPS 在做幂等去重与乱序处理时,应将 `Epoch` 视为逻辑流键的一部分;当 `Epoch` 变化时,应重置该流的 `Last_Executed_SeqID` 等状态。
|
||||
- **DestID**:
|
||||
- `DestID` 为目的设备逻辑 ID,用于快速过滤与防错发。
|
||||
- 推荐约定:
|
||||
- SPS → DACS 单播 Control/RMA:`DestID = 0x11..0x13`(目标阵面)
|
||||
- SPS → DACS 广播 Control:`DestID = 0x10`
|
||||
- DACS → SPS Data/Status:`DestID = 0x01`
|
||||
|
||||
---
|
||||
|
||||
@@ -256,6 +284,18 @@ V2.1 在 V2.0 的基础上补齐了 **Status/ACK 报文规范**,明确 **SeqID
|
||||
4. **自闭环调度**: 引入 `Pulse Count` 字段。FPGA 收到指令后,将严格执行指定数量的脉冲发射,完成后自动停止发射并转入空闲状态,消除因网络延迟导致的波束过时或“长发”风险。
|
||||
5. **并发任务 (TaskID)**: 为支持“并发多任务”(多个 CPI/Pulse 流交错),控制面下发 `TaskID`,数据面回传同一 `TaskID` 以实现无歧义重组。
|
||||
|
||||
参数校验规范(必须):
|
||||
|
||||
- DACS 在执行控制指令前 **必须** 完成关键字段的范围与一致性检查;检查失败则 **不得执行**,并通过 Status/ACK 返回 `Applied=0` 且 `ErrorCode=BadParam`。
|
||||
- 关键一致性最小集合(必须):
|
||||
- `Pulse Width` 必须满足 $PulseWidth < 10^9/PRF$(单位换算后等价于脉宽小于 PRI),否则拒绝;
|
||||
- `Sample Points > 0` 且不得超过硬件上限(实现需给出上限常量);
|
||||
- `Pulse Count > 0` 且不得超过硬件上限;
|
||||
- `Bandwidth > 0` 且不得超过 ADC/DDC 允许带宽;
|
||||
- `Center Freq` 必须落在前端射频工作带内;
|
||||
- `GainTarget_mdB` 必须落在可控增益范围内。
|
||||
- `TaskID` 语义(必须):若上述任一会影响数据平面重组边界/数据长度的参数发生变化(如 `Sample Points`、`Pulse Count`、波形模式),SPS **必须** 分配新的 `TaskID`,不得复用旧 `TaskID`。
|
||||
|
||||
### **3.2 载荷定义 (Control Payload)**
|
||||
|
||||
|**相对偏移 (Offset)**|**字段名 (Field Name)**|**数据类型**|**单位 (Unit)**|**说明与物理定义**|
|
||||
@@ -277,18 +317,26 @@ V2.1 在 V2.0 的基础上补齐了 **Status/ACK 报文规范**,明确 **SeqID
|
||||
|**56**|**Wave_Param1**|`uint32`|-|**波形动态参数 1**。<br>例如 LFM 的调频斜率 (Slope) 或相位编码的初相。|
|
||||
|**60**|**Wave_Param2**|`uint32`|-|**波形动态参数 2**。<br>预留给特定波形的高级控制参数。|
|
||||
|**64**|**TaskID**|`uint32`|-|**并发任务标识**。由 SPS 分配(建议单调递增或随机非零)。用于区分同一时刻交错的多 CPI 流。|
|
||||
|**68**|**Reserved**|`uint8[56]`|-|**扩展保留区**。<br>必须全填 `0x00`。**处于 CRC 保护之下**。|
|
||||
|**68**|**Az_Broaden_Factor**|`uint8`|Index|**方位展宽倍数索引**。<br>`0`: 1x(不展宽); `1`: 2x; `2`: 3x…(具体映射由系统配置表定义)。|
|
||||
|**69**|**El_Broaden_Factor**|`uint8`|Index|**俯仰展宽倍数索引**。<br>编码同上。|
|
||||
|**70**|**PRF_Jitter_Mode**|`uint8`|Enum|**PRF 抖动模式**。<br>`0`: Off; `1`: Deterministic (参差); `2`: Random (随机)。|
|
||||
|**71**|**Reserved_ExtPad0**|`uint8`|-|**对齐填充**,必须为 0。确保后续 `uint32` 4 字节对齐。|
|
||||
|**72**|**Sample_Delay_ns**|`uint32`|ns|**采样起始延迟**。<br>定义采样窗起点相对发射时刻的纳秒延迟,用于波门控制。|
|
||||
|**76**|**Sim_Target_Dist_ns**|`uint32`|ns|**模拟目标距离延迟**(内测/校准)。<br>以等效传播时延(ns)表达。|
|
||||
|**80**|**Sim_Target_Vel_mmps**|`int32`|mm/s|**模拟目标速度**(内测/校准)。|
|
||||
|**84**|**Phase_Init**|`uint32`|-|**脉冲初始相位控制字**(波形精细化)。|
|
||||
|**88**|**Reserved**|`uint8[36]`|-|**扩展保留区(剩余)**。<br>必须全填 `0x00`。**处于 CRC 保护之下**。|
|
||||
|**124**|**CRC32C**|`uint32`|-|**完整性校验**。<br>算法:CRC-32C (Castagnoli)。<br>覆盖范围:`Common Header + Control Payload (不含 CRC 字段本身)`(详见 6.4)。|
|
||||
|
||||
---
|
||||
|
||||
### **3.3 内存布局图解 (Memory Layout)**
|
||||
|
||||
为了满足底层驱动开发(Driver Development)与 FPGA 逻辑校验的需求,本节提供载荷的**RFC 标准比特视图**与**Mermaid 现代化视图**。所有多字节字段(`uint16` / `uint32` / `uint64`)均遵循 **Little-Endian (小端序)** 排列。
|
||||
以下视图用于核对控制载荷的字节偏移与字边界。
|
||||
|
||||
#### **3.3.1 RFC 标准比特视图 (Bit-Level View)**
|
||||
|
||||
此视图主要用于核对字节偏移量(Offset)与字边界(Word Boundary)。每行代表 32-bit (4 Bytes),左侧为起始偏移量。
|
||||
每行代表 32-bit (4 Bytes),左侧为起始偏移量。
|
||||
|
||||
```Plaintext
|
||||
0 1 2 3
|
||||
@@ -318,71 +366,14 @@ V2.1 在 V2.0 的基础上补齐了 **Status/ACK 报文规范**,明确 **SeqID
|
||||
| Wave_Param2 (uint32) | TaskID (uint32) | 0x3C / 0x40
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| |
|
||||
/ Reserved (Total 56 Bytes) /
|
||||
/ Reserved (Total 36 Bytes) /
|
||||
| |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| CRC32C (End) | 0x7C
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
```
|
||||
|
||||
#### **3.3.2 可视化布局 (Mermaid Packet)**
|
||||
|
||||
此视图直观展示了字段在 32-bit 宽度下的连续性,重点体现了 **Reserved_Pad** 带来的对齐效果。
|
||||
|
||||
```mermaid
|
||||
packet-beta
|
||||
title 128-Byte Radar Payload (32-bit Width)
|
||||
0-7: "Cmd Mode (u8)"
|
||||
8-15: "Wave ID (u8)"
|
||||
16-31: "Reserved_Pad (u16)"
|
||||
32-63: "Azimuth_uDeg (i32)"
|
||||
64-95: "Pad0 (u32=0)"
|
||||
96-127: "Elevation_uDeg (i32)"
|
||||
128-159: "Pad1 (u32=0)"
|
||||
160-223: "Center Freq (u64)"
|
||||
224-287: "Bandwidth (u64)"
|
||||
288-319: "Pulse Width (u32)"
|
||||
320-351: "PRF (u32)"
|
||||
352-383: "Sample Points (u32)"
|
||||
384-415: "Pulse Count (u32)"
|
||||
416-447: "GainTarget_mdB (i32)"
|
||||
448-479: "Wave_Param1 (u32)"
|
||||
480-511: "Wave_Param2 (u32)"
|
||||
512-543: "TaskID (u32)"
|
||||
544-991: "Reserved (56 Bytes)"
|
||||
992-1023: "CRC32C"
|
||||
```
|
||||
|
||||
#### **3.3.3 逻辑功能框图 (Functional Block)**
|
||||
|
||||
此视图按照业务逻辑对字段进行分组,便于上层应用开发理解各参数的物理归属。
|
||||
|
||||
```mermaid
|
||||
block-beta
|
||||
columns 4
|
||||
block:header:4
|
||||
CMD["Cmd (u8)"] ID["ID (u8)"] PAD["Pad (u16)"]
|
||||
end
|
||||
block:angles:4
|
||||
AZ["Azimuth_uDeg (i32)"] PAD0["Pad0 (u32=0)"] EL["Elevation_uDeg (i32)"] PAD1["Pad1 (u32=0)"]
|
||||
end
|
||||
block:rf:4
|
||||
FREQ["Center Freq (u64 - 8B)"]:2 BW["Bandwidth (u64 - 8B)"]:2
|
||||
end
|
||||
|
||||
PW["PulseWidth (u32)"] PRF["PRF (u32)"] SAM["Samples (u32)"] CNT["PulseCount (u32)"]
|
||||
GAIN["Gain_mdB (i32)"] P1["Param1 (u32)"] P2["Param2 (u32)"] TID["TaskID (u32)"]
|
||||
block:footer:4
|
||||
RES_BODY["…Reserved (56 Bytes)…"]:3 CRC["CRC32C"]:1
|
||||
end
|
||||
|
||||
style PAD fill:#f9f,stroke:#333,stroke-dasharray: 5 5
|
||||
style CRC fill:#f96,stroke:#333,stroke-width:2px
|
||||
style AZ fill:#bbf
|
||||
style EL fill:#bbf
|
||||
```
|
||||
|
||||
#### **3.3.4 关键字段说明**
|
||||
#### **3.3.2 关键字段说明**
|
||||
|
||||
- **对齐填充 (`Reserved_Pad`)**:
|
||||
- **位置**: Offset 2-3 (2 Bytes)。
|
||||
@@ -406,145 +397,133 @@ block-beta
|
||||
|
||||
## **4. 数据平面 (Data Plane)**
|
||||
|
||||
方向: Data Acquisition Control System (DACS) $\to$ Signal Processing System (SPS)
|
||||
方向: DACS $\to$ SPS
|
||||
|
||||
协议: UDP Unicast
|
||||
|
||||
端口: 30000 (Base Port) + DACS_ID
|
||||
端口: 30000 (Base Port) + DACS_ID(映射规则同 3.0)
|
||||
|
||||
> `DACS_ID` 与 `SourceID` 的映射规则同 3.0。
|
||||
PacketType(必须):`PacketType == 0x03 (Data)`。
|
||||
|
||||
报文结构: [Common Header (32B)] + [Data Specific Header (32B)] + [Pad/Ext Area (64B)] + [RAW Payload]
|
||||
### **4.1 报文格式与校验 (Format & Validation)**
|
||||
|
||||
### **4.1 关键设计准则**
|
||||
报文结构(固定前缀):
|
||||
|
||||
1. **物理闭环 (Physical Scaling)**: 引入 `Scale_uV` 字段(整数微单位)。FPGA 端以整数方式计算/查表得到“每个 ADC LSB 对应的电压微伏数”。后端仅需执行 $V[\mu V] = RawInt16 \times Scale\_uV$(再乘 $10^{-6}$ 转换为 V)即可还原真实物理量。
|
||||
2. **长脉冲支持 (Long Pulse)**: 引入 `Sample Offset` 字段。针对宽带 LFM 长脉冲产生的超大采样数据块(超过单帧 MTU 上限,典型为 1500/9000),通过显式的偏移量指示,确保后端能将乱序到达的 UDP 分片无误地重组到显存的正确位置。
|
||||
3. **质量感知 (Quality Aware)**: 引入 `ADC Status` 字段。实时标记当前脉冲是否存在 ADC 饱和(Clipping)或链路丢数,使后端 DSP 算法能及时剔除无效数据,避免虚假目标生成。
|
||||
4. **扩展保留区 (Pad/Ext Area)**: 数据专用头后固定保留 **64 Bytes** 扩展区(本版本称为 Padding)。
|
||||
- V2.1 中该 64B 必须全填 `0x00`。
|
||||
- 未来版本如需新增数据面头字段,必须**仅在该 64B 内扩展**,并保持“扩展区总长度仍为 64B”,从而确保 RAW Payload 的起始偏移恒为 128B(见 4.3)。
|
||||
- `[Common Header (32B)] + [Data Specific Header (32B)] + [Execution Snapshot (64B)] + [RAW Payload (Variable)]`
|
||||
|
||||
### **4.2 数据专用头 (Data Specific Header)**
|
||||
长度与一致性(必须):
|
||||
|
||||
该头部紧随通用报文头之后,长度固定为 **32 Bytes**。采用紧凑的布局设计,最大化信息密度。
|
||||
- 设 `UdpPayloadBytes` 为 UDP Payload 的实际字节数,则接收端 **必须** 校验:`UdpPayloadBytes == 32 + PayloadLen`。
|
||||
- 对于 Data 包,`PayloadLen` **必须** 满足:
|
||||
- `PayloadLen == 32 + 64 + RawPayloadBytes`
|
||||
- 令 `C = PopCount(Channel Mask)`,`B` 为每个分量的字节数(由 `Data Type` 决定:Int16=2,Int32=4,Float32=4),则:
|
||||
- `RawPayloadBytes == SampleCount * C * (2 * B)`
|
||||
- 任一校验失败:接收端 **必须** 丢弃该包(防止越界重组)。
|
||||
|
||||
#### **4.2.1 RFC 风格比特视图 (Bit View)**
|
||||
对齐(必须):
|
||||
|
||||
- RAW Payload 起始偏移固定为 128 字节($32+32+64$),为 64B Cache Line 的整数倍。
|
||||
|
||||
SeqID(必须):
|
||||
|
||||
- 对于同一逻辑流(按 2.3.0 的 `(SourceID, PacketType, Direction)`),发送端 **必须** 每发送一个 UDP 数据包使 `SeqID` 递增 1(自然回绕按 2.3.0 规则处理)。
|
||||
|
||||
### **4.2 数据专用头 (Data Specific Header, 32B)**
|
||||
|
||||
位置:紧随通用报文头之后,长度固定 32B。
|
||||
|
||||
|**偏移**|**字段名**|**类型**|**规范与语义(必须/推荐)**|
|
||||
|---:|---|---|---|
|
||||
|0|CPI_Index|`uint32`|相干处理间隔索引(同一任务内的宏观时间维度)。|
|
||||
|4|Pulse_Index|`uint32`|脉冲索引(同一 CPI 内从 0 开始)。|
|
||||
|8|Sample_Rate_Hz|`uint32`|采样率(Hz)。推荐与任务上下文一致;不一致时接收端应告警并可丢弃该帧。|
|
||||
|12|SampleCount|`uint32`|本包采样点数(每通道复数点数)。**必须 > 0**。与 `PayloadLen` 的关系必须满足 4.1。|
|
||||
|16|SampleOffset|`uint32`|本包数据在同一重组键 `Key` 对应序列中的起始点号(点数)。首片通常为 0。|
|
||||
|20|Scale_uV|`int32`|当 `Data Type` 为 Int16/Int32 时表示 $\mu V/LSB$;当 `Data Type` 为 Float32 时 **必须为 0**。|
|
||||
|24|ChannelMask|`uint16`|通道掩码。`Bit0`=$\Sigma$,`Bit1`=$\Delta_{Az}$,`Bit2`=$\Delta_{El}$,`Bit3`=Aux;其余位保留 0。|
|
||||
|26|DataType|`uint8`|`0x00`=Int16,`0x01`=Float32(仅回放/仿真),`0x02`=Int32。|
|
||||
|27|ADC_Status|`uint8`|ADC/链路状态位图(按实现定义扩展)。保留位必须为 0。|
|
||||
|28|TaskID|`uint32`|任务标识(与控制面一致)。用于跨包/跨流重组与跨平面绑定。|
|
||||
|
||||
### **4.3 执行状态快照区 (Execution Snapshot, 64B, V2.2)**
|
||||
|
||||
位置:紧随 Data Specific Header 之后,长度固定 64B。
|
||||
|
||||
规范(必须):
|
||||
|
||||
- 该区长度 **必须固定为 64B**;旧实现可将其视为 Padding 并填 0。
|
||||
- 所有 `Reserved_*` 字段 **必须** 填 0;接收端可告警但不得依赖其非 0 语义。
|
||||
|
||||
字段布局(相对快照区起始偏移):
|
||||
|
||||
|**偏移**|**字段名**|**类型**|**单位**|**说明**|
|
||||
|---:|---|---|---|---|
|
||||
|0|Applied_Freq_Hz|`uint64`|Hz|硬件实际发射/本振频率快照。|
|
||||
|8|Applied_Gain_mdB|`int32`|mdB|接收链路物理增益快照。|
|
||||
|12|Applied_Azimuth_uDeg|`int32`|$\mu^\circ$|硬件实际方位角快照。|
|
||||
|16|Applied_Elevation_uDeg|`int32`|$\mu^\circ$|硬件实际俯仰角快照。|
|
||||
|20|Hardware_Health_Bitmask|`uint32`|-|硬件健康位图(按实现定义)。|
|
||||
|24|Device_Temp_0p1C|`int16`|0.1°C|温度快照。|
|
||||
|26|Reserved_SnapPad0|`uint16`|-|必须为 0。|
|
||||
|28|Broaden_Snapshot|`uint8`|-|展宽实际状态快照。|
|
||||
|29|Data_Source_Attr|`uint8`|-|数据来源属性(示例:0=真实回波,1=内校准)。|
|
||||
|30|Reserved_SnapPad1|`uint16`|-|必须为 0。|
|
||||
|32|Reserved_Snapshot|`uint8[32]`|-|必须为 0。|
|
||||
|
||||
### **4.4 原始载荷 (Raw Payload)**
|
||||
|
||||
位置:紧随 64B 快照区之后(起始偏移固定 128B)。
|
||||
|
||||
排列(必须):按“点交织(Point-Interleaved)+ I/Q 交织”排列:
|
||||
|
||||
```Plaintext
|
||||
0 1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
+---------------------------------------------------------------+
|
||||
| CPI Index (4B) |
|
||||
+---------------------------------------------------------------+
|
||||
| Pulse Index (4B) |
|
||||
+---------------------------------------------------------------+
|
||||
| Sample Rate (4B) |
|
||||
+---------------------------------------------------------------+
|
||||
| Sample Count (4B) |
|
||||
+---------------------------------------------------------------+
|
||||
| Sample Offset (4B) |
|
||||
+---------------------------------------------------------------+
|
||||
| Scale_uV (4B) |
|
||||
| (int32, micro-volts per LSB) |
|
||||
+---------------------------------------------------------------+
|
||||
| Channel Mask | Data Type | ADC Status |
|
||||
| (16 bits) | (8 bits) | (8 bits) |
|
||||
+---------------------------------------------------------------+
|
||||
| TaskID |
|
||||
| (uint32, stream key) |
|
||||
+---------------------------------------------------------------+
|
||||
[I0_Ch0][Q0_Ch0] [I0_Ch1][Q0_Ch1] ... [I0_Ch(C-1)][Q0_Ch(C-1)]
|
||||
[I1_Ch0][Q1_Ch0] [I1_Ch1][Q1_Ch1] ...
|
||||
...
|
||||
```
|
||||
|
||||
#### **4.2.2 字段语义详解**
|
||||
数据类型(必须):
|
||||
|
||||
|**相对偏移 (Offset)**|**字段名 (Field Name)**|**数据类型**|**说明与业务逻辑**|
|
||||
|---|---|---|---|
|
||||
|**0**|**CPI Index**|`uint32`|**相干处理间隔索引**。<br>宏观时间计数,标识当前数据属于哪一次波束驻留任务。|
|
||||
|**4**|**Pulse Index**|`uint32`|**脉冲索引**。<br>微观时间计数,当前 CPI 内的第 N 个脉冲(从 0 开始)。|
|
||||
|**8**|**Sample Rate**|`uint32`|**采样率 (Hz)**。<br>当前数据的 ADC 采样频率,用于时频变换参考。|
|
||||
|**12**|**Sample Count**|`uint32`|**本包采样点数**(每通道的复数点数 N)。<br>设 $C$ 为通道数(等于 `Channel Mask` 中置位 bit 数),$B$ 为每个分量字节数(Int16=2,Int32=4,Float32=4),则:
|
||||
- 每通道每点字节数:$BytesPerComplex = 2 \times B$(I/Q 各一份)
|
||||
- 本包 Raw Payload 总字节数:$PayloadBytes = N \times C \times BytesPerComplex$
|
||||
接收端必须用该公式校验 `PayloadLen` 与实际 UDP 长度,防止越界重组。|
|
||||
|**16**|**Sample Offset**|`uint32`|**采样偏移量**。<br>指示本包数据在完整脉冲回波序列中的起始位置(点数)。<br>首包为 0,后续分片包以此递增。|
|
||||
|**20**|**Scale_uV**|`int32`|**物理归一化因子(微单位整数)**。<br>单位:$\mu V / LSB$。<br>换算:$V[V] = RawInt16 \times Scale\_uV \times 10^{-6}$。|
|
||||
|**24**|**Channel Mask**|`uint16`|**通道掩码**。<br>`Bit0`: $\Sigma$ (和路/主通道)<br>`Bit1`: $\Delta_{Az}$ (方位差)<br>`Bit2`: $\Delta_{El}$ (俯仰差)<br>`Bit3`: Aux (辅助/旁瓣对消)|
|
||||
|**26**|**Data Type**|`uint8`|**数据格式类型**。<br>`0x00`: Int16 (I/Q 交织, 标准格式)<br>`0x01`: Float32 (**仅用于软件回放/仿真,不要求 FPGA 支持**)<br>`0x02`: Int32|
|
||||
|**27**|**ADC Status**|`uint8`|**ADC 健康状态字**。<br>`Bit0`: CH0 Saturation (饱和告警)<br>`Bit1`: CH1 Saturation<br>`Bit7`: Link Error (SerDes 链路失锁)|
|
||||
|**28**|**TaskID**|`uint32`|**并发任务标识**。与控制面 `TaskID` 一致,用于并发多任务流重组。|
|
||||
- Int16:I/Q 为 `int16` Little-Endian。
|
||||
- Int32:I/Q 为 `int32` Little-Endian。
|
||||
- Float32:I/Q 为 IEEE754 `float32`(仅回放/仿真);`Scale_uV` 必须为 0。
|
||||
|
||||
### **4.3 原始载荷 (Raw Payload)**
|
||||
Scale_uV 处理(必须):
|
||||
|
||||
- **布局**: 紧随 64 字节的扩展保留区(Padding/Ext Area)之后。
|
||||
- **内存对齐**: 由于扩展保留区总长度固定为 64B,RAW Payload 的起始偏移恒为 $32+32+64 = 128$ 字节。这是 64-byte Cache Line 的整数倍,适配 CPU/GPU 的 DMA 突发传输要求,并为未来字段扩展提供兼容空间。
|
||||
- **数据排列 (Int16 模式)**:
|
||||
- 当 `DataType` 为 Int16/Int32:`Scale_uV` 必须非 0,且建议满足 $|Scale\_uV| \le 2^{30}$。
|
||||
- 主机侧换算推荐:乘法在至少 64-bit 精度下进行。
|
||||
|
||||
```Plaintext
|
||||
[I0_Ch0][Q0_Ch0] [I0_Ch1][Q0_Ch1] … [I1_Ch0][Q1_Ch0] …
|
||||
```
|
||||
### **4.5 重组规则 (Reassembly)**
|
||||
|
||||
- **I/Q**: 16-bit Signed Integer (Little Endian).
|
||||
- **多通道**: 按点交织 (Point-Interleaved),即先排所有通道的第 0 点,再排第 1 点。这种排列最利于 GPU SIMD 并行读取。
|
||||
|
||||
#### **4.3.1 Scale_uV 边界与溢出处理(必须)**
|
||||
|
||||
- **取值约束(必须)**:
|
||||
- 当 `Data Type` 为 `0x00 (Int16)` 或 `0x02 (Int32)` 时,`Scale_uV` 表示 $\mu V/LSB$,必须为非零值。
|
||||
- 当 `Data Type` 为 `0x01 (Float32)` 时,`Scale_uV` **必须填 0**,接收端必须忽略该字段。
|
||||
- 推荐范围:$|Scale\_uV| \le 2^{30}$(约 $1.07\times 10^9\ \mu V/LSB$)。超出范围应视为配置/标定异常。
|
||||
- **主机侧计算(必须)**:
|
||||
- SPS 在将 `RawInt16` 还原为电压时,乘法必须在 **至少 64-bit** 精度下进行(例如 `int64`),避免 `int32` 溢出。
|
||||
- **异常处理(必须)**:
|
||||
- 若 `Scale_uV==0` 或超出允许范围,SPS 必须对该帧标记为无效并告警;DACS 侧若检测到标定数据异常也应回传错误状态(可复用 `ADC Status` 的保留位或通过 Telemetry 上报)。
|
||||
|
||||
Float32 说明(必须):
|
||||
|
||||
- 当 `Data Type=0x01 (Float32)` 时,RAW Payload 中 I/Q 为 IEEE 754 `float32`,其物理量单位由软件回放/仿真系统自行约定;协议不要求 FPGA 产生该格式。
|
||||
|
||||
### **4.4 并发多任务重组键 (Reassembly Key)**
|
||||
|
||||
为支持多个 CPI/Pulse 流交错到达,SPS 端的逻辑帧键(唯一标识一条“脉冲回波序列”)定义为:
|
||||
重组键(必须):
|
||||
|
||||
$$
|
||||
Key = (SourceID,\; TaskID,\; CPI\ Index,\; Pulse\ Index,\; Channel\ Mask,\; Data\ Type)
|
||||
Key = (SourceID,\; TaskID,\; CPI\_Index,\; Pulse\_Index,\; ChannelMask,\; DataType)
|
||||
$$
|
||||
|
||||
同一 Key 下,使用 `Sample Offset` 与 `Sample Count` 进行分片写入;缺失区间按 6.3 的规范补零。
|
||||
分片写入(必须):
|
||||
|
||||
### **4.5 FrameFlags 与 Offset 的一致性约定**
|
||||
- 同一 `Key` 下,使用 `SampleOffset` 与 `SampleCount` 将 RAW Payload 写入对应接收缓冲。
|
||||
- 缺失区间必须按 6.3 执行相干补零。
|
||||
- `SeqID` 仅可作为“全局丢包提示”;**不得** 用 `SeqID` 推导某个 `Key` 的缺失 Offset。
|
||||
|
||||
对于 PacketType=0x03 (Data):
|
||||
### **4.6 跨平面绑定与帧边界 (Control Binding)**
|
||||
|
||||
- `SOF` 建议置 1 当且仅当 `Sample Offset == 0`。
|
||||
- `EOF` 建议置 1 当且仅当 `Sample Offset + Sample Count == Sample Points`(其中 `Sample Points` 来自同一 `TaskID` 的控制面下发参数)。
|
||||
- 若实现不便,也可令 `FrameFlags=0`(仅依赖 Offset/Count 重组),但不得与 Offset/Count 语义冲突。
|
||||
任务上下文(必须):
|
||||
|
||||
### **4.5.1 数据平面 SeqID 递增规则(必须)**
|
||||
- 对于任意 Data 包,其 `(SourceID, TaskID)` 必须能在 SPS 侧命中任务上下文(由最近一次成功执行的 Control 指令建立)。
|
||||
- 上下文至少包含:`Sample Points`、`Pulse Count`,(可选)期望 `Sample Rate`、以及用于诊断的中心频率/带宽等。
|
||||
|
||||
- 对于 PacketType=0x03 (Data),发送端必须对同一条逻辑流(按 2.3.0 的 `(SourceID, PacketType, Direction)`)满足:**每发送一个 UDP 数据包,`SeqID` 递增 1**(自然回绕按 2.3.0 规则处理)。
|
||||
- 接收端可使用 `SeqID` 作为快速丢包提示,但**帧重组的最终依据**必须以 4.4/4.6 中的 `Key + Sample Offset/Count` 为准。
|
||||
参数不变性(必须):
|
||||
|
||||
### **4.6 跨平面关联与参数一致性(必须)**
|
||||
- 在同一 `(SourceID, TaskID)` 生命周期内,影响数据长度/帧边界的参数不得漂移;若需要变更,SPS 必须分配新的 `TaskID`。
|
||||
|
||||
数据平面的重组与 EOF 判断依赖控制平面下发的关键参数(尤其是 `Sample Points`、`Pulse Count` 等)。为避免“同一 TaskID 下参数漂移”导致接收端无法正确重组,定义如下强制规则:
|
||||
FrameFlags(推荐):
|
||||
|
||||
1. **TaskID 绑定规则(必须)**:
|
||||
- 对于任意数据包(PacketType=0x03),其 `(SourceID, TaskID)` 必须能在 SPS 侧找到一条“任务上下文(Task Context)”,该上下文由最近一次成功执行的 Control 指令(PacketType=0x01,ACK Applied)建立。
|
||||
- 任务上下文至少包含:`Sample Points`、`Pulse Count`、(可选)`Sample Rate` 期望值、以及用于日志/诊断的 `Center Freq/Bandwidth` 等。
|
||||
|
||||
2. **参数不变性(必须)**:
|
||||
- 在同一 `(SourceID, TaskID)` 生命周期内,DACS 回传的数据包必须使用与该任务上下文一致的 `Sample Points` 语义。
|
||||
- 若 SPS 需要更改 `Sample Points`、`Pulse Count`、波形模式或其它会影响数据长度/重组边界的参数,**必须分配新的 `TaskID`**,不得复用旧 `TaskID`。
|
||||
|
||||
3. **上下文缺失处理(必须)**:
|
||||
- 若 SPS 收到数据包时找不到对应任务上下文(例如控制指令未成功、丢失、或任务已过期),SPS 必须将该 Key 标记为“未绑定任务”,并采取以下之一:
|
||||
- 丢弃该数据帧并上报错误;或
|
||||
- 进入隔离缓冲(Quarantine Buffer)等待上下文补齐(有上限与超时)。
|
||||
- 不允许在缺失 `Sample Points` 约束的情况下,盲目以 `EOF`/长度推断完整帧边界。
|
||||
|
||||
4. **上下文超时(建议)**:
|
||||
- SPS 侧任务上下文应设置超时(例如数秒级,按系统业务节拍配置)。超时后如仍收到相同 `(SourceID, TaskID)` 的数据,视为异常并告警。
|
||||
- 若实现使用 `FrameFlags` 标记边界,则对 Data 包建议满足:
|
||||
- `SOF==1` 当且仅当 `SampleOffset==0`;
|
||||
- `EOF==1` 当且仅当 `SampleOffset + SampleCount == Sample Points`(来自任务上下文)。
|
||||
- 若实现不使用 `FrameFlags`,可置 0,但不得与 `SampleOffset/SampleCount` 语义冲突。
|
||||
|
||||
---
|
||||
|
||||
@@ -657,9 +636,7 @@ $$
|
||||
|
||||
### **6.1 控制平面:幂等性设计 (Idempotency)**
|
||||
|
||||
风险: 由于 UDP ACK 丢包导致的 SPS 重传,可能使 DACS 重复执行增量指令(如“步进 1°”被执行两次变成 2°),导致物理状态与软件状态失步。
|
||||
|
||||
修正: DACS (FPGA) 必须实现基于 SeqID 的指令去重逻辑。
|
||||
规范(必须):控制/维护指令在 UDP 重传场景下 **必须幂等**;DACS 必须按 `SeqID` 去重,重复包只回 ACK 不重复执行。
|
||||
|
||||
#### **6.1.1 FPGA 接收状态机逻辑**
|
||||
|
||||
@@ -684,7 +661,7 @@ FPGA 内部需为每条控制/维护逻辑流维护一个寄存器 `Last_Execute
|
||||
|
||||
#### **6.1.2 ACK/Status 报文(PacketType=0x02)**
|
||||
|
||||
为避免“ACK 未定义导致互操作失败”,本协议统一使用 PacketType=0x02 作为 ACK/状态承载。
|
||||
规范(必须):本协议使用 PacketType=0x02 作为 ACK/状态承载。
|
||||
|
||||
报文结构:`[Common Header (32B)] + [Status Payload (32B)] + [CRC32C (4B)]`
|
||||
|
||||
@@ -708,7 +685,7 @@ SeqID 规则(必须):
|
||||
|
||||
- 对于用于确认/回执的 Status/ACK 报文(`StatusType=ControlAck` 或 `RmaAck`),**Common Header 的 `SeqID` 必须等于 `AckSeqID`**。
|
||||
- 对于遥测类报文(`StatusType=Telemetry`),`AckSeqID` 必须为 `0`,且其 Common Header 的 `SeqID` 属于 Telemetry 自身的独立序列(仍按 2.3.0 的规则递增/回绕)。
|
||||
- 设计目的:避免 ACK 自身引入额外的独立 SeqID 流,同时避免 Telemetry 被强行绑定到不存在的 `AckSeqID`。
|
||||
|
||||
|
||||
ErrorCode 建议(可扩展):
|
||||
|
||||
@@ -723,9 +700,7 @@ ErrorCode 建议(可扩展):
|
||||
|
||||
### **6.2 控制平面:重传与超时 (Retransmission Strategy)**
|
||||
|
||||
现状: 通用操作系统(Linux/Windows 非实时核)的线程调度抖动通常在 10ms~20ms 量级。过激的超时设置会导致虚假重传。
|
||||
|
||||
修正: 采用宽松的超时阈值,配合安全互锁机制。
|
||||
规范(推荐):采用固定超时 + 有界重试;超时/重试达到上限后进入链路故障处理,并触发安全互锁。
|
||||
|
||||
#### **6.2.1 计时器参数**
|
||||
|
||||
@@ -757,22 +732,26 @@ ErrorCode 建议(可扩展):
|
||||
|
||||
### **6.3 数据平面:丢包处理 (Data Loss Handling)**
|
||||
|
||||
风险: UDP 回波数据丢失会导致时间轴断裂。如果直接跳过丢失的数据块,会导致后续脉冲压缩(匹配滤波)输出的峰值位置偏移,从而产生巨大的测距误差。
|
||||
|
||||
修正: 必须采用 " 相干补零 (Coherent Zero-Padding)" 策略。
|
||||
规范(必须):数据平面丢包后 **必须** 执行相干补零(缺失采样等价为复数 0),以保持时间轴与相位一致性。
|
||||
|
||||
#### **6.3.1 补零规范**
|
||||
|
||||
当 SPS 检测到丢包(通过 `SeqID` 跳变或 `Pulse/Offset` 不连续)时,必须在接收 Buffer 中填充数据,填补空缺,维持时间轴对齐。
|
||||
当 SPS 在同一重组键 `Key` 下检测到丢包(通过 `Sample Offset/Sample Count` 不连续)时,必须在接收 Buffer 中填充数据,填补空缺,维持时间轴对齐。
|
||||
|
||||
> 注意:在允许多个 `Key` 交织到达的前提下,`SeqID` 跳变只能说明数据平面“全局存在丢包”,**无法唯一定位**是哪个 `Key` 缺失,因此不得单独据此计算缺失区间并补零。
|
||||
|
||||
- **填充内容**: **复数零 ($0 + j0$)**。
|
||||
- I 路 = 0 (`0x0000`)
|
||||
- Q 路 = 0 (`0x0000`)
|
||||
- **填充长度**: 严格等于丢失的采样点数(每通道复数点数)$N_{lost}$。
|
||||
- 设上一包参数为 $(Offset_{prev}, Count_{prev})$,当前包为 $Offset_{curr}$,则:
|
||||
|
||||
$$
|
||||
N_{lost} = Offset_{curr} - (Offset_{prev} + Count_{prev})
|
||||
|
||||
|
||||
$$
|
||||
|
||||
- 当 $N_{lost} > 0$:在该 Key 对应的接收缓冲中补 $N_{lost}$ 个复数零(对每个通道均补齐)。
|
||||
- 当 $N_{lost} \le 0$:表示重复包或乱序到达;SPS 仍可选择“最后写入覆盖”或“忽略”,但必须保持输出长度一致。
|
||||
|
||||
@@ -782,7 +761,7 @@ ErrorCode 建议(可扩展):
|
||||
|
||||
### **6.4 校验和 (Checksum)**
|
||||
|
||||
为了在应用层确保数据完整性,抵御链路误码(Bit-flip)和总线错误:
|
||||
校验规范:
|
||||
|
||||
1. **控制/维护/状态包**: 强制开启 **CRC-32C**(包尾)。
|
||||
|
||||
@@ -804,13 +783,13 @@ ErrorCode 建议(可扩展):
|
||||
|
||||
#### **6.5.2 生产环境安全要求(至少满足其一,必须)**
|
||||
|
||||
为在不破坏 V2.1 报文格式的前提下实现可落地的安全闭环,生产环境必须至少采用以下一种方式提供**加密与认证**:
|
||||
为在不破坏 V2.2 报文格式的前提下实现可落地的安全闭环,生产环境必须至少采用以下一种方式提供**加密与认证**:
|
||||
|
||||
1. **链路层安全(推荐)**:MACsec (802.1AE)
|
||||
2. **网络层安全(推荐)**:IPsec(Transport/Tunnel 均可)或等效的专用加密隧道
|
||||
3. **物理隔离专网(最低要求)**:控制/维护网络必须与办公网/互联网严格隔离,并采用 ACL/白名单限制可达性
|
||||
|
||||
> 注:若系统未来需要在不可信网络上直接跑 UDP 明文,则应在后续版本引入协议级认证(例如 HMAC-SHA256),并配套密钥管理与重放防护。本条为 V2.1 的落地约束,不在本版本报文格式中强制定义具体认证字段。
|
||||
> 注:若系统未来需要在不可信网络上直接跑 UDP 明文,则应在后续版本引入协议级认证(例如 HMAC-SHA256),并配套密钥管理与重放防护。本条为 V2.2 的落地约束,不在本版本报文格式中强制定义具体认证字段。
|
||||
|
||||
#### **6.5.3 RMA 通道风险控制(必须)**
|
||||
|
||||
|
||||
Reference in New Issue
Block a user