Files
Share_Li/前端感知系统通信协议 (ICD) V2.1.md
Klein b9acd5004e 上传文件至 /
update: 通信协议更新至2.1版本。
2026-01-09 07:42:42 +00:00

825 lines
54 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.

---
tags: []
aliases:
- "**前端感知系统通信协议 (ICD) V2.1**"
date created: 星期一, 十二月 8日 2025, 9:01:09 上午
date modified: 星期一, 十二月 8日 2025, 6:08:02 晚上
---
# **前端感知系统通信协议 (ICD) V2.1**
文档编号: FES-SW-ICD-002
版本: V2.1 (Integer-Only + TaskID + ACK/Status Clarified)
说明:版本以本页“版本”字段为准;文档编号用于配置管理索引,不随次版本必然变化。
适用架构: Host (CPU/GPU) <-> Device (Pure Logic FPGA)
物理链路: 10Gbps Ethernet (UDP/IP)
---
## **0. 设计变更与迁移指南 (Design Change Log)**
### **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 只能处理整数”的实现约束。
### **0.2 详细变更对照表**
#### **1. 架构与拓扑设计 (Architecture & Topology)**
|**变更维度**|**V0.1 / V1.0 (Legacy)**|**V2.0 (Current)**|**设计动机与技术收益**|
|---|---|---|---|
|**拓扑依赖**|**强耦合 (IP Binding)**<br>依赖 IP 地址 (`192.168.0.x`) 区分阵面。|**完全解耦 (Logical SourceID)**<br>新增 `SourceID` 字段,支持 DHCP 及动态组网。|支持即插即用离线数据分析pcap无需依赖环境 IP 表。|
|**传输单元**|**MTU 1500 (Standard)**<br>未明确定义,默认为标准帧。|**MTU 9000 (Jumbo Frame)**<br>强烈推荐开启巨型帧,且必须兼容 MTU 1500 运行。|在吞吐与部署兼容性之间平衡优先保证可达与稳定运行Jumbo 作为性能增强项。|
|**维护通道**|**无 (None)**<br>仅支持预定义命令。|**RMA Protocol**<br>引入 `OpCode 0xFF`,支持内存/寄存器直接读写。|实现波形文件的动态下载与任意寄存器的带外调试,无需修改协议固件。|
#### **2. 数据结构与内存布局 (Data Structure & Memory)**
|**变更维度**|**V0.1 / V1.0 (Legacy)**|**V2.0 (Current)**|**设计动机与技术收益**|
|---|---|---|---|
|**报文头对齐**|**非对齐 (15 Bytes)**<br>奇数长度头部,导致 Payload 内存错位。|**自然对齐 (32 Bytes)**<br>强制 8 字节对齐,填充至 Cache Line 边界。|适配 FPGA 256-bit 总线与 CPU AVX 指令集,实现零拷贝 (Zero-Copy) DMA。|
|**字节对齐**|**1-Byte Packed**<br>紧凑排列,无填充。|**Hybrid Alignment (混合策略)**<br>控制面紧凑,数据面/关键字段强制对齐。|在节省带宽与降低 CPU 访问开销(避免非对齐异常)之间取得最佳平衡。|
|**校验算法**|**XOR / Sum**<br>抗干扰能力弱,无法检测双位翻转。|**CRC-32C (Castagnoli)**<br>硬件加速指令级校验。|极大地降低漏检率,特别是在雷达高功率发射环境下的突发误码检测。|
|**扩展性**|**无预留**<br>新增字段需破坏现有结构。|**预留保留区 (Reserved)**<br>控制面预留 56 字节,且置于 CRC 保护下。|确保协议升级时旧版固件不崩溃,支持向后兼容。|
#### **3. 物理量定义与精度 (Physics & Precision)**
|**变更维度**|**V0.1 / V1.0 (Legacy)**|**V2.0 (Current)**|**设计动机与技术收益**|
|---|---|---|---|
|**频率定义**|**索引码 (uint8)**<br>`0=15.5GHz`, Step=10MHz。<br>范围锁定,无法捷变。|**绝对物理值 (uint64)**<br>单位Hz。<br>例:`15,500,000,000`。|**解耦硬件**支持任意波段Ku/Ka、任意步进的频率捷变与抗干扰策略。|
|**角度定义**|**量化整数 (int16)**<br>LSB=0.0025°。< br>存在量化噪声GPU 需转换。|**微单位整数 / 浮点接口**<br>传输层:`int32` ($\mu^\circ$)。<br>应用层:`double` (Deg)。|**消除量化误差**:精度提升至 $10^{-6}$ 度,满足 AI 波束成形算法的高精度需求。|
|**增益控制**|**量化步进 (uint16)**<br>LSB=0.5dB。<br>依赖硬件非线性特性。|**物理增益 (int32)**<br>单位mdB。<br>FPGA 查表映射。|**算法闭环**:后端直接下发期望增益,底层自动校准,简化业务逻辑。|
|**回波归一化**|**无 (None)**<br>仅传 ADC 原始值 (Int16)。<br>后端无法计算 RCS。|**Scale Factor (int32 微单位)**<br>随包下发物理归一化因子(整数微单位)。|**数据自描述**GPU 可直接还原真实电压/功率,无需同步查询增益状态,且 FPGA 侧不需要浮点。|
#### **4. 可靠性与时序控制 (Reliability & Timing)**
|**变更维度**|**V0.1 / V1.0 (Legacy)**|**V2.0 (Current)**|**设计动机与技术收益**|
|---|---|---|---|
|**幂等性**|**缺失**<br>ACK 丢包会导致指令重复执行(如电机步进 2 次)。|**SeqID 去重**<br>FPGA 缓存 `Last_SeqID`,重复包仅回 ACK 不执行。|**防止状态过冲**:确保控制指令在不可靠网络下的绝对确定性执行。|
|**超时策略**|**激进 (未定义/短)**<br>易受 OS 调度抖动影响触发重传。|**宽松 (20ms)**<br>适配 Windows/Linux 非实时核调度。|**减少网络风暴**:避免因系统卡顿导致的虚假超时与不必要的重传。|
|**丢包处理**|**无规范**<br>直接拼接或补零。|**相干补零 (Coherent Zero-Pad)**<br>严格补复数零 ($0+j0$)。|**保障信号完整性**:防止时域数据缺失导致的脉冲压缩相位错位与测距误差。|
|**自闭环调度**|**开环 (Open Loop)**<br>发多少脉冲依赖“停止”指令。|**Pulse Count (自闭环)**<br>指令携带脉冲数FPGA 计数自动停止。|**消除网络延迟风险**:防止因网络拥塞导致的发射机“长发”事故。|
#### **5. 字段级优化细节 (Field Optimization)**
- **废弃 (Deprecated)**: `Bit-fields` (位域) —— 调试困难易引发竞态条件。V2.0 全面改为 `uint8` 枚举。
- **废弃 (Deprecated)**: `FreqCode` (频率码) —— 扩展性极差。
- **新增 (New)**: `Token` (事务令牌) —— 支持异步非阻塞驱动模型(主要用于 RMA
- **新增 (New)**: `TaskID` (任务标识) —— 支持并发多任务/多 CPI 流交错传输与无歧义重组。
- **新增 (New)**: `ADC Status` (状态字) —— 实时标记饱和与链路质量。
- **新增 (New)**: `Sample Offset` (采样偏移) —— 支持超长脉冲乱序重组。
---
## **1. 总则与约束 (General Provisions)**
### **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。波束解算与相位控制将全部通过高效的整数位移与乘加运算完成。
### **1.2 物理量数据类型定义**
所有控制指令中的物理量必须遵循以下严格的类型与单位定义:
|**物理量分类**|**协议数据类型**|**基础单位 (Unit)**|**换算公式 (Software View)**|**FPGA 处理逻辑**|**示例**|
|---|---|---|---|---|---|
|**频率 (Freq)**|`uint64`|**Hz** (赫兹)|$Val_{phy} = Val_{raw}$|直接写入 DDS 频率控制字 (FCW)|15.5GHz $\to$ `15,500,000,000`|
|**角度 (Angle)**|`int32`|**$\mu^\circ$** (微度)|$Val_{phy} = Val_{raw} \times 10^{-6}$|整数乘法 + 移位计算移相器状态|45.0° $\to$ `45,000,000`|
|**增益 (Gain)**|`int32`|**mdB** (毫分贝)|$Val_{phy} = Val_{raw} \times 10^{-3}$|查表 (LUT) 映射衰减器电压|30.5dB $\to$ `30,500`|
|**时间 (Time)**|`uint64`|**ns** (纳秒)|$Val_{phy} = Val_{raw} \times 10^{-9}$ (sec)|直接与 PTP 计数器比较|1 秒 $\to$ `1,000,000,000`|
|**带宽 (BW)**|`uint64`|**Hz** (赫兹)|$Val_{phy} = Val_{raw}$|用于配置 DDC 抽取率|100MHz $\to$ `100,000,000`|
### **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 接收缓冲)抵消分片增多带来的开销。
### **1.4 混合对齐策略 (Hybrid Alignment)**
为平衡传输带宽与处理效率,协议在不同平面采用不同的对齐策略:
1. **控制平面 (SPS $\to$ DACS)**
- 采用 **1-Byte Packed (紧凑模式)**
- **理由**控制指令数据量小FPGA 解析状态机FSM处理逐字节提取Shift-Register非常高效且无需关心 CPU 的缓存行对齐问题。
2. **数据平面 (DACS $\to$ SPS)**
- 采用 **8-Byte Natural Alignment (自然对齐)**
- **理由**:高通量回波数据必须适配主机 CPU/GPU 的内存访问特性。数据包头Header将填充至 Cache Line 边界,确保后续的原始 I/Q 载荷Payload起始地址严格对齐从而支持 **Zero-Copy DMA****GPU Direct Storage** 技术。
---
## **2. 通用报文头 (Common Header)**
设计原则:
所有 UDP 报文(包括控制、状态、回波数据及 RMA 维护包)均强制包含此标准头。该头部长度严格固定为 32 Bytes (256 bits),且内部关键字段均按 8-Byte 自然对齐 排列。这一设计不仅适配 64 位 CPU 的内存访问特性,更完美契合 FPGA 内部常见的 256-bit AXI-Stream 数据总线,确保硬件解析实现“零填充、零移位”的高效处理。
### **2.1 报文头结构定义**
| **偏移 (Offset)** | **字段名 (Field Name)** | **数据类型** | **说明与约束** |
| --------------- | -------------------- | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| **0** | **Magic Word** | `uint32` | 协议同步魔数,固定为 **`0x55AA55AA`**。<br>用于从二进制流中快速定位帧首,防止滑窗错误。 |
| **4** | **SeqID** | `uint32` | **按流递增的包序列号**(非全局)。<br>递增作用域:**(SourceID, PacketType, Direction)** 组成的一条逻辑流。接收端用于丢包检测与乱序重排。 |
| **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`)。 |
| **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 字节对齐。 |
---
### 2.2 内存布局图解 (Memory Layout)
```plaintext
| 0 1 2 3 | 4 5 6 7 | (Byte Offset)
+-----------------------------+-----------------------------+
| Magic Word | Seq ID |
+-----------------------------+-----------------------------+
| Timestamp (Lo) |
+-----------------------------+-----------------------------+
| Timestamp (Hi) |
+-----------------------------+-----------------------------+
| PayloadLen | PacketType | Ver | SrcID | FrameFlags | <--- 紧凑信息区
+-----------------------------+-----------------------------+
| Reserved (8 Bytes) |
+-----------------------------+-----------------------------+
```
### **2.3 关键字段语义详解**
#### **2.3.0 SeqID 作用域与回绕处理(必须)**
- **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}$ 的“半区间”规则,禁止用简单的 `>` 直接比较(避免回绕后误判)。定义:
- 令 $\Delta = (SeqID_{new} - SeqID_{last})\bmod 2^{32}$(以 `uint32` 自然溢出实现)。
- 当 $0 < \Delta < 2^{31}$ 判定为 **新包**
- $\Delta = 0$ 判定为 **重复包**
- $2^{31} \le \Delta < 2^{32}$ 判定为 **旧包/乱序包**
- **建议实现**FPGA/软件统一采用上述规则确保在 `SeqID` 发生回绕时依然能保持幂等与去重正确性
#### **2.3.1 版本控制 (ProtoVer) —— 解决“协议锁死”**
- **机制**接收端解析器首先检查 `ProtoVer`
- `ProtoVer == 本地版本`正常全速解析
- `ProtoVer > 本地版本`进入兼容模式或报错防止将新版新增字段误读为乱码避免未定义的行为Undefined Behavior)。
- **优势**支持全系统的灰度发布例如SPS 可以先升级到 V2.1同时兼容旧版 V2.0 DACS 硬件无需强制停机全网升级
#### **2.3.2 源标识 (SourceID) —— 解决“拓扑依赖”**
- **机制**彻底解耦 IP 地址SPS 接收逻辑不再依赖 `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
#### **2.3.3 帧标志 (FrameFlags) —— 解决“数据拼图”**
- **背景**一个完整的相干处理间隔CPI回波数据可能高达数 MB远超 UDP MTU1500/9000 Bytes必须拆分为多个 UDP 包传输
- **逻辑定义**
- **单包帧 (Single Packet)**: 数据很小一个包发完
- 设置 `SOF=1`, `EOF=1`
- **多包帧 - 首包 (First Packet)**:
- 设置 `SOF=1`, `EOF=0`
- **多包帧 - 中间包 (Middle Packet)**:
- 设置 `SOF=0`, `EOF=0`
- **多包帧 - 尾包 (Last Packet)**:
- 设置 `SOF=0`, `EOF=1`
- **优势**接收端无需解析 Payload 内容即可在链路层判断帧边界并能快速发现帧内丢包/截断”。对于 Data 接收端应优先按 6.3 执行相干补零以保持时间轴对于 Control/RMA 校验失败/缺失则由超时重传机制闭环处理
---
## **3. 控制平面 (Control Plane)**
方向: Signal Processing System (SPS) $\to$ Data Acquisition Control System (DACS)
协议: UDP Unicast
端口: 20000 (Base Port) + DACS_ID
报文总长: 固定 160 Bytes (32 Bytes Common Header + 128 Bytes Control Payload)
### **3.0 端口与阵面映射约定**
- 服务器侧通过 4 10GbE 采集卡接入其中 3 口分别对应 3 个阵面数据口
- `DACS_ID` 取值范围`1..3`阵面编号)。
- `SourceID` `DACS_ID` 映射固定约定
- `DACS_ID=1` -> `SourceID=0x11`Array 01 / Front
- `DACS_ID=2` -> `SourceID=0x12`Array 02 / Left
- `DACS_ID=3` -> `SourceID=0x13`Array 03 / Right
广播约定(必须):
- `SourceID=0x10 (DACS-Broadcast)` 为广播语义保留 ID。
- 本版本中,广播仅用于 **控制平面下行SPS → DACS** 的“同参同步”场景SPS 可向 UDP 目的端口 **20000Base Port** 发送一份控制指令DACS 侧必须同时监听 **20000广播端口****20000 + DACS_ID单播端口**
- DACS 对广播控制指令的 Status/ACK 响应必须使用各自的单播 `SourceID=0x11..0x13` 回传,禁止使用 `0x10` 回传。
- 数据平面30000+ID与 RMA40000+ID不定义广播语义。
### **3.1 设计约束**
1. **整数/微整数 (Integer-Only)**: 控制面所有关键物理量字段均采用 `int32/uint32/uint64` 等整数表达(角度使用 $\mu^\circ$,增益使用 mdB。FPGA 侧无需、也不允许实现 IEEE 754 浮点解析与运算。
2. **偏移稳定 (Offset-Stable)**: 为减少固件改动风险,本版本尽量保持 `Center Freq` 等关键 `uint64` 字段偏移不变;在角度字段之间使用显式保留字以保持对齐与兼容。
3. **末尾校验 (Tail Checksum)**: 校验字段 `CRC32C` 固定在载荷最末尾Offset 124。该字段用于对**整个 UDP 载荷**进行完整性校验(见 6.4 统一 CRC 覆盖规则)。
4. **自闭环调度**: 引入 `Pulse Count` 字段。FPGA 收到指令后,将严格执行指定数量的脉冲发射,完成后自动停止发射并转入空闲状态,消除因网络延迟导致的波束过时或“长发”风险。
5. **并发任务 (TaskID)**: 为支持“并发多任务”(多个 CPI/Pulse 流交错),控制面下发 `TaskID`,数据面回传同一 `TaskID` 以实现无歧义重组。
### **3.2 载荷定义 (Control Payload)**
|**相对偏移 (Offset)**|**字段名 (Field Name)**|**数据类型**|**单位 (Unit)**|**说明与物理定义**|
|---|---|---|---|---|
|**0**|**Command Mode**|`uint8`|-|**工作模式**。<br>`0`: Standby (待机/静默)<br>`1`: Search (搜索)<br>`2`: Track (跟踪)<br>`3`: Calibrate (内/外校准)|
|**1**|**Waveform ID**|`uint8`|Index|**基础波形索引**。<br>指向 FPGA 内部 DDR 预存的波形表(如 LFM 基带数据)。|
|**2**|**Reserved_Pad**|`uint8[2]`|-|**对齐填充**。<br>必须填 `0x00`。确保后续 `Azimuth` 从 Offset 4 开始。|
|**4**|**Azimuth_uDeg**|`int32`|**$\mu^\circ$**|**方位角 ($\theta$)**。范围 `[-90°, 90°]`。软件换算:$\theta[deg] = Val_{raw} \times 10^{-6}$。|
|**8**|**Reserved_AnglePad0**|`uint32`|-|**对齐保留**(必须为 0。用于保持后续字段偏移稳定并便于硬件解析。|
|**12**|**Elevation_uDeg**|`int32`|**$\mu^\circ$**|**俯仰角 ($\phi$)**。范围 `[-90°, 90°]`。软件换算:$\phi[deg] = Val_{raw} \times 10^{-6}$。|
|**16**|**Reserved_AnglePad1**|`uint32`|-|**对齐保留**(必须为 0。|
|**20**|**Center Freq**|`uint64`|**Hz**|**载波中心频率**。<br>绝对物理值(如 `15,500,000,000`),直接控制本振 (LO)。|
|**28**|**Bandwidth**|`uint64`|**Hz**|**信号瞬时带宽**。<br>用于配置接收机 DDC 滤波器的抽取率与带宽。|
|**36**|**Pulse Width**|`uint32`|**ns**|**脉冲宽度 ($\tau$)**。<br>发射波形的有效持续时间,决定雷达盲区与平均功率。|
|**40**|**PRF**|`uint32`|**Hz**|**脉冲重复频率**。<br>决定最大无模糊距离。|
|**44**|**Sample Points**|`uint32`|Count|**快拍数 (Range Gates)**。<br>单次脉冲回波的 ADC 采样点数(如 4096。|
|**48**|**Pulse Count**|`uint32`|Count|**驻留脉冲数 ($N_{cpi}$)**。<br>本次 CPI 包含的脉冲总数。FPGA 计数达到此值后自动停止。|
|**52**|**GainTarget_mdB**|`int32`|**mdB**|**期望增益**。软件换算:$G[dB] = Val_{raw} \times 10^{-3}$。DACS 通过 LUT/标定表映射为模拟衰减/增益控制量。|
|**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 保护之下**。|
|**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),左侧为起始偏移量。
```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
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Command Mode | Waveform ID | Reserved_Pad (0x0000) | 0x00
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Azimuth_uDeg (int32) | 0x04
| Reserved_AnglePad0 (uint32=0) | 0x08
| Elevation_uDeg (int32) | 0x0C
| Reserved_AnglePad1 (uint32=0) | 0x10
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Center Freq (uint64) | 0x14
+ +
| (8 Bytes Total) | 0x18
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Bandwidth (uint64) | 0x1C
+ +
| (8 Bytes Total) | 0x20
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Pulse Width (uint32) | PRF (uint32) | 0x24 / 0x28
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Sample Points (uint32) | Pulse Count (uint32) | 0x2C / 0x30
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| GainTarget_mdB (int32) | Wave_Param1 (uint32) | 0x34 / 0x38
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Wave_Param2 (uint32) | TaskID (uint32) | 0x3C / 0x40
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
/ Reserved (Total 56 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 关键字段说明**
- **对齐填充 (`Reserved_Pad`)**:
- **位置**: Offset 2-3 (2 Bytes)。
- **作用**: 强制将当前的写入指针推移至 Offset 4使后续字段保持偏移稳定并对齐友好。
- **值约束**: 必须填 `0x0000`
- **物理量整数编码 (`Azimuth_uDeg` / `Elevation_uDeg` / `GainTarget_mdB`)**:
- 角度采用 $\mu^\circ$(微度)整数编码,避免量化误差与 FPGA 浮点。
- 增益采用 mdB毫分贝整数编码满足 0.001 dB 级别控制分辨率。
- **末尾校验 (`CRC32C`)**:
- **位置**: Offset 124 (最后 4 字节)。
- **覆盖范围**: `Common Header + Payload不含 CRC 字段)`
- **封闭性**: 这种设计使得整个 128 字节结构体是一个自包含的“安全胶囊”。任何对保留区的无意篡改(如内存越界写)都能被 CRC 检出。
### **3.4 ACK/Status 机制概述(必须)**
- 控制平面基于 UDP 运行,必须通过 `SeqID` 去重 + `PacketType=0x02 (Status/ACK)` 回执 + 超时重传来构建确定性闭环。
- **执行成功的唯一判据**SPS 必须以收到的 ACK`StatusFlags.Applied=1``ErrorCode==0`)作为“指令已执行”的判据;任何未被 ACK 确认的控制指令不得假定已生效。
- Status/ACK 的完整载荷格式定义见 **6.1.2**
---
## **4. 数据平面 (Data Plane)**
方向: Data Acquisition Control System (DACS) $\to$ Signal Processing System (SPS)
协议: UDP Unicast
端口: 30000 (Base Port) + DACS_ID
> `DACS_ID` 与 `SourceID` 的映射规则同 3.0。
报文结构: [Common Header (32B)] + [Data Specific Header (32B)] + [Pad/Ext Area (64B)] + [RAW Payload]
### **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)。
### **4.2 数据专用头 (Data Specific Header)**
该头部紧随通用报文头之后,长度固定为 **32 Bytes**。采用紧凑的布局设计,最大化信息密度。
#### **4.2.1 RFC 风格比特视图 (Bit View)**
```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) |
+---------------------------------------------------------------+
```
#### **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=2Int32=4Float32=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` 一致,用于并发多任务流重组。|
### **4.3 原始载荷 (Raw Payload)**
- **布局**: 紧随 64 字节的扩展保留区Padding/Ext Area之后。
- **内存对齐**: 由于扩展保留区总长度固定为 64BRAW Payload 的起始偏移恒为 $32+32+64 = 128$ 字节。这是 64-byte Cache Line 的整数倍,适配 CPU/GPU 的 DMA 突发传输要求,并为未来字段扩展提供兼容空间。
- **数据排列 (Int16 模式)**:
```Plaintext
[I0_Ch0][Q0_Ch0] [I0_Ch1][Q0_Ch1] … [I1_Ch0][Q1_Ch0] …
```
- **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 下,使用 `Sample Offset` 与 `Sample Count` 进行分片写入;缺失区间按 6.3 的规范补零。
### **4.5 FrameFlags 与 Offset 的一致性约定**
对于 PacketType=0x03 (Data)
- `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 递增规则(必须)**
- 对于 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 跨平面关联与参数一致性(必须)**
数据平面的重组与 EOF 判断依赖控制平面下发的关键参数(尤其是 `Sample Points`、`Pulse Count` 等)。为避免“同一 TaskID 下参数漂移”导致接收端无法正确重组,定义如下强制规则:
1. **TaskID 绑定规则(必须)**
- 对于任意数据包PacketType=0x03其 `(SourceID, TaskID)` 必须能在 SPS 侧找到一条“任务上下文Task Context该上下文由最近一次成功执行的 Control 指令PacketType=0x01ACK 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)` 的数据,视为异常并告警。
---
## **5. 维护平面 (RMA Protocol)**
方向: 双向 (SPS $\leftrightarrow$ DACS)
协议: UDP Unicast
端口: 40000 (Base Port) + DACS_ID
> `DACS_ID` 与 `SourceID` 的映射规则同 3.0。
报文结构: [Common Header (32B)] + [RMA Header (16B)] + [Data Payload] + [CRC32C (4B)]
### **5.1 关键设计准则**
1. **强制对齐 (Alignment Enforcement)**: RMA 头部长度被扩充并锁定为 **16 Bytes**。结合 32 Bytes 的通用头Payload 的绝对起始偏移量为 **48 Bytes**。这既是 8 字节的倍数也是 16 字节的倍数,确保 CPU AVX 指令集与 FPGA AXI 总线 DMA 引擎均能以最高效率进行突发读写。
2. **异步事务 (Async Transaction)**: 引入 `Token` 字段。SPS 驱动层可为每个读写请求分配唯一的令牌(如 UUID Hash 或自增 IDDACS 在响应时必须原样回传该令牌。这使得上层软件能够采用高效的**异步 Promise/Future 模式**,无需阻塞等待 IO彻底消除了并发请求下的乱序匹配风险。
3. **显式状态 (Explicit Status)**: 引入 `Status` 字段。DACS 不再仅仅是“沉默的执行者”,而是具备了反馈能力。针对地址越界、写保护或硬件超时等异常情况,能明确返回错误码,极大降低了系统集成的调试难度。
### **5.2 RMA 专用头 (RMA Specific Header)**
该头部紧随通用报文头之后,长度固定为 **16 Bytes**。
#### **5.2.1 RFC 风格比特视图 (Bit View)**
```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
+---------------------------------------------------------------+
| OpCode (8) | Target (8) | Status (8) | Reserved (8) |
+---------------------------------------------------------------+
| Token (32 bits) |
| (Transaction ID for Async Match) |
+---------------------------------------------------------------+
| Address (32 bits) |
| (Target Memory/Register Offset) |
+---------------------------------------------------------------+
| Length (32 bits) |
| (Payload Size in Bytes) |
+---------------------------------------------------------------+
| |
| Data Payload (Variable) |
| (Start at Offset 48, Aligned) |
| |
+---------------------------------------------------------------+
| CRC32C (4B) |
| (Covers Common Header + RMA Header + Data Payload, no CRC) |
+---------------------------------------------------------------+
```
#### **5.2.2 字段语义详解**
|**相对偏移 (Offset)**|**字段名 (Field Name)**|**数据类型**|**说明与业务逻辑**|
|---|---|---|---|
|**0**|**OpCode**|`uint8`|**操作码**。<br>**请求 (Req)**: `0x01`=Write, `0x02`=Read<br>**响应 (Resp)**: `0x81`=Write Ack, `0x82`=Read Resp|
|**1**|**Target**|`uint8`|**目标区域**。<br>`0x00`: FPGA Regs (32-bit MMIO)<br>`0x01`: Waveform DDR (Bulk Memory)<br>`0x02`: Flash (Firmware Update)|
|**2**|**Status**|`uint8`|**响应状态码** (仅响应包有效,请求包填 0)。<br>`0x00`: Success (成功)<br>`0x01`: Invalid Addr (地址无效/越界)<br>`0x02`: Write Protected (写保护)<br>`0x03`: Hardware Timeout (硬件超时)<br>`0x04`: Bad Length (长度非法)|
|**3**|**Reserved**|`uint8`|**对齐填充**。<br>必须填 `0x00`。|
|**4**|**Token**|`uint32`|**事务令牌**。<br>由主机驱动生成建议单调递增。FPGA 必须在响应包中原样拷贝此字段,用于软件层的 Request-Response 匹配。|
|**8**|**Address**|`uint32`|**目标地址**。<br>对于寄存器 (`Target=0x00`),为寄存器偏移量。<br>对于 DDR/Flash为绝对字节地址。|
|**12**|**Length**|`uint32`|**载荷长度**。<br>单位:字节。<br>对于写操作Payload 的实际长度。<br>对于读操作:请求读取的长度。|
> **长度与校验约定**
>
> - `Length` 仅指 **Data Payload** 的字节数(不包含 RMA Header 与 CRC32C
> - `PayloadLen`Common Header包含`RMA Header (16B) + Data Payload (Length) + CRC32C (4B)`。
> - `CRC32C` 为包尾追加字段,计算范围覆盖 `Common Header + RMA Header + Data Payload`(不含 CRC 字段本身)。
### **5.3 典型交互流程 (Transaction Flow)**
#### **场景 1波形下载 (Write Waveform)**
1. **SPS 发送**:
- `OpCode`: `0x01` (Write)
- `Target`: `0x01` (DDR)
- `Token`: `0x12345678`
- `Address`: `0x10000000`
- `Length`: `4096`
- `Payload`: [4KB Waveform Data…]
2. **DACS 响应**:
- `OpCode`: `0x81` (Write Ack)
- `Status`: `0x00` (Success)
- `Token`: `0x12345678` (原样返回)
- `Length`: `0` (无 Payload)
#### **场景 2并发状态轮询 (Async Read)**
1. **SPS 发送请求 A (读温度)**: `Token=101`, `Addr=0x10` (Temp Reg)
2. **SPS 发送请求 B (读电压)**: `Token=102`, `Addr=0x20` (Volt Reg)
3. **DACS 响应 B (先返回)**: `Token=102`, `Status=Success`, `Payload`=[电压值]
- _软件驱动层_: 唤醒 Promise B 的回调。
4. **DACS 响应 A (后返回)**: `Token=101`, `Status=Success`, `Payload`=[温度值]
- _软件驱动层_: 唤醒 Promise A 的回调。
---
## **6. 校验与可靠性 (Reliability & Timing)**
适用范围: 全系统 (SPS + DACS)
目标: 确保在 UDP 不可靠传输协议之上构建满足雷达战术指标的确定性Determinism与安全性Safety
### **6.1 控制平面:幂等性设计 (Idempotency)**
风险: 由于 UDP ACK 丢包导致的 SPS 重传,可能使 DACS 重复执行增量指令(如“步进 1°”被执行两次变成 2°导致物理状态与软件状态失步。
修正: DACS (FPGA) 必须实现基于 SeqID 的指令去重逻辑。
#### **6.1.1 FPGA 接收状态机逻辑**
FPGA 内部需为每条控制/维护逻辑流维护一个寄存器 `Last_Executed_SeqID`(按 2.3.0 的逻辑流维度独立,初始化为 0。当收到新的控制指令PacketType=0x01 或 RMA=0xFF必须按 2.3.0 的回绕安全比较规则判定(令 $\Delta=(SeqID_{new}-SeqID_{last})\bmod 2^{32}$
1. **新指令($0 < \Delta < 2^{31}$**
- **动作**:立即执行指令。
- **更新**`Last_Executed_SeqID \leftarrow SeqID_{new}`。
- **回复**:发送 ACKPacketType=0x02`AckSeqID=SeqID_{new}`,并携带执行结果)。
2. **重传指令($\Delta = 0$**
- **动作****严禁重复执行**Drop Payload
- **更新**:保持不变。
- **回复****重发 ACK**PacketType=0x02`AckSeqID=SeqID_{new}`,并携带与首次执行一致的结果)。
3. **旧包/乱序包($2^{31} \le \Delta < 2^{32}$**
- **动作**:丢弃。
- **回复**:无需回复。
#### **6.1.2 ACK/Status 报文PacketType=0x02**
为避免“ACK 未定义导致互操作失败”,本协议统一使用 PacketType=0x02 作为 ACK/状态承载。
报文结构:`[Common Header (32B)] + [Status Payload (32B)] + [CRC32C (4B)]`
Status Payload 定义(固定 32B
|**相对偏移**|**字段名**|**类型**|**说明**|
|---|---|---|---|
|0|StatusType|`uint16`|`0x0001`: ControlAck, `0x0002`: RmaAck, `0x0003`: Telemetry|
|2|StatusFlags|`uint16`|Bit0: Applied(已执行)Bit1: Duplicate(重复包未执行);其余保留 0|
|4|AckSeqID|`uint32`|被确认/关联的命令 SeqIDControl/RMA 请求的 SeqID|
|8|Token|`uint32`|RMA 用 TokenControlAck 填 0|
|12|TaskID|`uint32`|ControlAck 用 TaskIDRmaAck 填 0 或实现自定义|
|16|ErrorCode|`uint32`|`0`: Success非 0 表示错误码(见下)|
|20|Detail0|`uint32`|可选细节(如错误地址低 32 位、校验失败计数等),无则填 0|
|24|Detail1|`uint32`|可选细节(无则填 0|
|28|Reserved|`uint32`|必须填 0|
CRC32C 规则:覆盖 `Common Header + Status Payload`(不含 CRC 字段)。
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 建议(可扩展):
- `0x00000000`: Success
- `0x00000001`: BadCRC
- `0x00000002`: BadParam (非法参数/越界)
- `0x00000003`: Busy (资源忙/暂不可用)
- `0x00000004`: Unsupported (不支持的模式/波形)
- `0x00000005`: InternalError
---
### **6.2 控制平面:重传与超时 (Retransmission Strategy)**
现状: 通用操作系统Linux/Windows 非实时核)的线程调度抖动通常在 10ms~20ms 量级。过激的超时设置会导致虚假重传。
修正: 采用宽松的超时阈值,配合安全互锁机制。
#### **6.2.1 计时器参数**
|**参数项**|**推荐值**|**说明**|
|---|---|---|
|**Initial Timeout**|**20ms**|初始等待时间。涵盖了 "RTT + FPGA 处理时间 + **OS 调度抖动**"。|
|**Max Retries**|**3 次**|最大重试次数。|
|**Link Down Time**|**100ms**|判定链路断开的总时间阈值 ($20ms \times (1+3) + \Delta$)。|
#### **6.2.2 故障处理流程**
1. **SPS 发送**: 发出指令,启动 20ms 计时器。
2. **SPS 等待**:
- 若收到 ACK 且 `AckSeqID == Cmd.SeqID` 且 `ErrorCode==0`: 事务成功,清除计时器。
- 若 20ms 超时: `Retry_Cnt++`重发指令SeqID 不变)。
3. **SPS 放弃**:
- 若 `Retry_Cnt > 3`: 判定链路故障 (Link Down)。
- **安全互锁 (Safety Interlock)**: SPS 必须立即停止后续波束调度,并向上层业务软件抛出 `E_LINK_LOST` 异常。若系统包含硬件看门狗DACS 应在 100ms 无指令后自动切断发射机高压。
4. **DACS 侧强制互锁(必须)**:
- DACS 必须实现独立于 SPS 的安全闭环:当连续 **100ms** 未收到“有效控制指令”(至少要求 CRC 校验通过;若系统启用网络层安全/认证,则还必须通过对应安全校验)时,必须自动进入 `Standby` 并关闭发射相关使能(包括但不限于发射机高压/功放使能/波形播放)。
- 该互锁应优先由硬件看门狗或等效的 FPGA 计时逻辑实现,禁止仅依赖主机软件。
---
### **6.3 数据平面:丢包处理 (Data Loss Handling)**
风险: UDP 回波数据丢失会导致时间轴断裂。如果直接跳过丢失的数据块,会导致后续脉冲压缩(匹配滤波)输出的峰值位置偏移,从而产生巨大的测距误差。
修正: 必须采用 " 相干补零 (Coherent Zero-Padding)" 策略。
#### **6.3.1 补零规范**
当 SPS 检测到丢包(通过 `SeqID` 跳变或 `Pulse/Offset` 不连续)时,必须在接收 Buffer 中填充数据,填补空缺,维持时间轴对齐。
- **填充内容**: **复数零 ($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 仍可选择“最后写入覆盖”或“忽略”,但必须保持输出长度一致。
> **补零后处理**:为减小窗函数旁瓣污染,允许在缺失区间附近对加权窗做平滑过渡(例如对缺失位置两侧若干点的窗系数做插值/衰减),但不得改变“缺失采样等价为 0”的相干约束。
---
### **6.4 校验和 (Checksum)**
为了在应用层确保数据完整性抵御链路误码Bit-flip和总线错误
1. **控制/维护/状态包**: 强制开启 **CRC-32C**(包尾)。
- DACS 收到包后,**硬件计算** CRC32C。若校验失败**直接静默丢弃**,不回 NACK防止 NACK 风暴。SPS 会因超时自动重传。
- CRC32C 覆盖范围统一为:`Common Header + Payload不含 CRC 字段)`。
2. **高速数据包**: 依赖链路层Ethernet FCS校验。
- 应用层不额外增加 CRC 字段,以节省 FPGA 逻辑资源并降低 PCIe 带宽开销。链路层校验错误的包会被网卡NIC直接丢弃SPS 软件层通过 Sequence ID 即可感知丢包。
---
### **6.5 安全性与访问控制(必须)**
#### **6.5.1 基本原则**
- 本协议基于 UDP 设计,`SourceID`/`SeqID`/`CRC32C` 仅用于**互操作与误码检测**,不具备任何身份认证或抗伪造能力。
- 生产/外场部署中,必须假设存在:伪造控制指令、重放、篡改、以及通过 RMA 获取“等价远程管理权限”的风险。
#### **6.5.2 生产环境安全要求(至少满足其一,必须)**
为在不破坏 V2.1 报文格式的前提下实现可落地的安全闭环,生产环境必须至少采用以下一种方式提供**加密与认证**
1. **链路层安全(推荐)**MACsec (802.1AE)
2. **网络层安全(推荐)**IPsecTransport/Tunnel 均可)或等效的专用加密隧道
3. **物理隔离专网(最低要求)**:控制/维护网络必须与办公网/互联网严格隔离,并采用 ACL/白名单限制可达性
> 注:若系统未来需要在不可信网络上直接跑 UDP 明文,则应在后续版本引入协议级认证(例如 HMAC-SHA256并配套密钥管理与重放防护。本条为 V2.1 的落地约束,不在本版本报文格式中强制定义具体认证字段。
#### **6.5.3 RMA 通道风险控制(必须)**
RMA 可读写寄存器/DDR/Flash等价于高权限维护接口。为避免误用或被滥用
- **默认关闭(必须)**DACS 上电后 RMA 功能应处于关闭或只读受限状态;仅在满足运维流程的情况下才允许开启。
- **网络分区(必须)**RMA 流量必须运行在独立的维护网络/VLAN 中,禁止与数据平面同网段直连。
- **访问控制(必须)**
- 至少实施基于五元组/ACL 的白名单(限定 SPS 主机 IP/MAC、端口范围
- 并建议加入“物理在场”要素(例如拨码开关/跳线/维护口使能)以降低远程攻击面。
- **最小权限(建议)**:对 Flash 写入等高风险操作(固件升级)应要求额外的人工确认流程与分段校验。