物理层详解¶
本文详细解释 SparkLink SLE 物理层的设计与实现, 覆盖调制波形、帧结构、信道编码和收发流水线, 逐一对标 TXS-10002-2025 标准条款并说明代码中的实现方式。
调制方式¶
SLE 物理层支持两大类调制: 频移键控 (GFSK) 和相移键控 (PSK), 分别用于不同帧类型。
GFSK 调制 (§6.2.1.1)¶
高斯频移键控是 FT1 帧的唯一调制方式。标准规定:
高斯滤波器带宽时间积 BT = 0.5
调制系数 h 在 0.45 至 0.55 范围内, 默认 0.5
比特 1 对应正频偏, 比特 0 对应负频偏
SLE 定义了 7 种带宽配置, 从 0.1 MHz 到 4 MHz:
带宽 |
符号周期 |
最小频偏 |
|---|---|---|
0.1 MHz |
10 \(\mu\)s |
23.125 kHz |
0.25 MHz |
4 \(\mu\)s |
92.5 kHz |
1.0 MHz |
1 \(\mu\)s |
185 kHz |
2.0 MHz |
0.5 \(\mu\)s |
370 kHz |
4.0 MHz |
0.25 \(\mu\)s |
740 kHz |
代码实现: phy.gfsk.GFSKModulator 类。调制过程为 NRZ 映射 → 上采样 → 高斯滤波 → 频率积分 → 复基带:
解调采用非相干的频率鉴别器方案 (GFSKDemodulator), 通过相邻采样点的相位差提取瞬时频率。
PSK 调制 (§6.2.1.2)¶
FT2-FT4 帧使用相移键控, 支持三种调制阶数:
BPSK (每符号 1 bit):
比特 0 → 相位 90°, 比特 1 → 相位 -90°
偶数位符号额外顺时针旋转 90°
QPSK (每符号 2 bit):
00→45°, 01→135°, 11→-135°, 10→-45°
偶数位额外 -45° 旋转
8PSK (每符号 3 bit):
Gray 编码, 22.5° 间隔
偶数位额外 -22.5° 旋转
"偶数位"的定义: 无线帧的第一个符号处于奇数位 (索引 0 = 奇), 索引 1 = 偶, 以此类推。这一额外旋转有助于改善时钟恢复性能。
脉冲成型使用平方根升余弦 (RRC) 滤波器, 滚降系数 \(\beta = 0.4\), 每符号采样数默认 4。收发两端各一个 RRC 滤波器, 级联后满足 Nyquist 无码间干扰准则。
代码实现: phy.psk.PSKModulator 类。星座映射定义在 BPSK_MAP, QPSK_MAP, _8PSK_MAP 等常量中。导频符号共用同一相位查找表, 由 phy.pilot 模块生成。
此外还有一种无旋转 BPSK 映射 (0→0°, 1→180°), 用于同步信号 3/4 中的 m 序列调制, 不参与偶数位旋转。
多音信号 (§6.2.1.3)¶
多音信号由 N 个单音叠加:
主要用于射频校准和测量场景。phy.multitone 模块实现了可配置音数、幅度和初始相位的多音信号生成。
UWB 脉冲 (§6.2.1.4)¶
超宽带脉冲信号采用 Kaiser 窗参考波形 (\(\beta = 10\)), 支持两种带宽:
信号带宽 |
脉冲宽度 \(T_p\) |
窗口 \(T_w\) |
|---|---|---|
\(\geq\) 500 MHz |
2 ns |
0.5 ns |
\(>\) 1300 MHz |
0.75 ns |
0.2 ns |
码片调制 \(c(n) \in \{-1, 0, +1\}\), 最大脉冲重复频率 499.2 MHz。
代码实现: phy.uwb_pulse 模块, 提供参考脉冲生成、码片调制和互相关验证。
帧结构 (§6.3)¶
无线帧的组成¶
每个物理帧由帧头和数据两部分构成:
┌─────────── 帧头 ───────────┐┌───── 数据 ──────┐
│ 前导码 │ 同步序列 │ 控制信息 │ 载荷数据 │ CRC │
└───────┴─────────┴─────────┘└─────────┴───────┘
各帧类型的差异集中在帧头的编码和调制方式上:
FT1 — 广播帧 (§6.3.2)¶
前导码: GFSK, [0,1] 交替, 10 \(\mu\)s
同步序列: sync_signal_1, 32 位→32 个 GFSK 符号
控制信息: A 组, 无 Polar 编码, GFSK 调制
载荷: 不经 Polar 编码, 直接 GFSK 调制
典型用途: 广播、发现、接入请求/响应
FT1 是最轻量的帧类型, 没有前向纠错编码开销。控制信息头部用 BCH 码保护, CRC 种子由同步序列低位确定。
FT2 — 短头数据帧 (§6.3.3)¶
前导码: PSK, [\(\pi/4\), 0] 交替, 10 \(\mu\)s
同步序列: sync_signal_2, 64 位→32 个 QPSK 符号
控制信息: A 组, Polar(64,K) 编码→32 QPSK 符号, 导频间隔 16
载荷: 码块分割 (无段内 CRC) → Polar 编码 → PSK 调制 + 导频
导频: 可选, 间隔 4/8/16
FT3 — 长头数据帧 (§6.3.4)¶
前导码: PSK, [\(\pi/4\), 0] 交替, 12 \(\mu\)s
同步序列: sync_signal_3, 31+31 位→62 个 BPSK 符号 (基于 m31 序列)
控制信息: B 组, Polar(256,K)→128 QPSK 符号, 导频间隔 4
载荷: 码块分割 (含段内 CRC) → Polar 编码 → PSK 调制 + 导频
特点: B 组 CRC 种子 =
0x555555 ^ LLID
FT4 — 扩展头数据帧 (§6.3.5)¶
前导码: PSK, [\(\pi/4\), 0] 交替, 16 \(\mu\)s
同步序列: sync_signal_4, 63+63 位→126 个 BPSK 符号 (基于 m63 序列)
控制信息: B 组, Polar(256,K)→256 BPSK 符号, 导频间隔 4
载荷: 与 FT3 相同的编码方案, 但同步序列更长, 适合低信噪比场景
时序参数¶
系统基础时隙 \(T_{sys} = 125\,\mu s\), 由 30 位计数器表示当前时刻。调度时隙有 25/50/75/100/125 \(\mu\)s 五种选择。帧的空口时长由以下公式决定:
代码实现: phy.frame 模块的 _SYNC_CONFIG 和 _CTRL_CONFIG 字典定义了四种帧类型的完整参数。assemble_frame_bits() 生成比特级帧结构, frame_to_symbols() 完成到调制符号的转换。
物理层控制信息 (§6.4)¶
控制信息是帧头中紧跟同步序列之后的结构化字段, 携带帧类型、载荷长度、MCS 等元信息。
A 组 (FT1/FT2)¶
A 组控制信息使用 CRC12 校验, 种子来自同步序列的低 12 位。定义了 7 种子类型:
类型 |
用途 |
|---|---|
A1 |
广播/发现/接入 |
A2 |
异步数据 (控制面) |
A3 |
异步数据 (数据面) |
A4 |
异步数据 (复用) |
A5 |
同步等时 |
A6 |
半可靠组播反馈 |
A7 |
测量管理 |
B 组 (FT3/FT4)¶
B 组使用 CRC24B 校验, 种子固定为 0x555555, CRC 结果与链路标识 LLID 异或。定义了 5 种子类型 (B1-B5), 对应异步数据、同步等时和测量等场景。
代码实现: phy.control_info 模块提供 ControlInfoA1 至 ControlInfoA7 和 ControlInfoB1 至 ControlInfoB5 等数据类, 各自实现 pack() 和 unpack() 方法。
同步信号 (§6.2.3)¶
同步序列用于接收端定位帧起始位置。SLE 定义了 6 种同步信号:
信号 |
长度 |
调制 |
生成方式 |
帧类型 |
|---|---|---|---|---|
sync_signal_1 |
32 bit |
GFSK |
GoldCode(32) |
FT1 |
sync_signal_2 |
64 bit |
QPSK |
GoldCode(64) |
FT2 |
sync_signal_3 |
62 bit |
BPSK |
m31+m31, pid 控制 |
FT3 |
sync_signal_4 |
126 bit |
BPSK |
m63+m63, pid 控制 |
FT4 |
sync_signal_5 |
32 bit |
GFSK |
安全随机函数 |
FT1 (安全) |
sync_signal_6 |
64 bit |
BPSK |
安全随机函数 |
FT2 (安全) |
sync_signal_3/4 的两段 m 序列由 PID (24 位) 通过哈希选择初始状态, 使得不同链路的同步序列正交。sync_signal_5/6 使用密码学安全随机数生成, 防止被预测。
代码实现: phy.sync_sequence 模块实现全部 6 种信号的生成, common.m_sequence 提供底层 m 序列算法。
前导码 (§6.2.2)¶
前导码位于帧最前端, 用于接收端的载波同步和符号定时恢复:
帧类型 |
波形 |
持续时间 |
样式 |
|---|---|---|---|
FT1 |
GFSK |
10 \(\mu\)s |
[0,1,0,1...] 交替 |
FT2 |
PSK |
10 \(\mu\)s |
[\(\pi/4\), 0, \(\pi/4\), 0...] 交替 |
FT3 |
PSK |
12 \(\mu\)s |
同上 |
FT4 |
PSK |
16 \(\mu\)s |
同上 |
前导码长度随帧类型递增, FT4 最长 (16 \(\mu\)s), 提供更好的同步捕获性能。
代码实现: phy.preamble.generate_preamble() 函数根据帧类型自动选择波形和时长。
导频 (§6.7)¶
导频符号是已知相位的参考符号, 周期性插入数据符号流中, 用于接收端进行信道估计和相位跟踪。
导频相位与该调制阶数的标准相位一致: BPSK 90°, QPSK 45°, 8PSK 22.5°。偶数位导频执行与数据符号相同的额外旋转。
插入规则: 每 \(N\) 个数据符号后插入 1 个导频, \(N\) 可选 4/8/16。帧末尾的导频可省略。
FT1 不使用导频。FT2 导频可选 (默认间隔 16)。FT3/FT4 强制使用导频 (默认间隔 4)。
代码实现: phy.pilot.insert_pilots() 和 remove_pilots() 函数。
信道编码 (§6.9-6.11)¶
CRC 校验 (§6.9)¶
SLE 使用四种 CRC:
类型 |
生成多项式 |
用途 |
|---|---|---|
CRC12 |
\(D^{12}+D^{11}+D^3+D^2+D+1\) |
A 组控制信息 |
CRC24A |
\(D^{24}+D^{23}+D^{18}+D^{17}+D^{14}+D^{11}+D^{10}+D^7+D^6+D^5+D^4+D^3+D+1\) |
载荷段, B组 |
CRC24B |
(同 24A 不同多项式) |
码块分割段内 CRC |
CRC32 |
标准 CRC-32 |
长载荷 |
CRC 计算支持种子值, A 组种子来自同步序列, B 组种子 = 0x555555 ^ LLID。
代码实现: common.crc.crc_calculate(), 支持 Rust 加速 (_HAS_RUST_CRC 自动检测)。
Polar 编码 (§6.10.1)¶
SLE 的前向纠错采用 Polar 码, 核心参数:
母码长度 \(N\): 32, 64, 128, 256, 512, 1024
信息位数 \(K\): 由 MCS 索引和载荷长度决定
可靠性序列: 标准附录 C 给出 1024 阶固定排序
编码器执行蝶形 GF(2) 变换, 解码器采用逐次消除 (SC) 算法, 辅以 SSC 剪枝 (rate-0/rate-1 子树快速路径)。
代码实现: common.polar.PolarEncoder / PolarDecoder, 均支持 Rust 加速 (PyO3 扩展 nearlink_sdr_accel)。编码加速约 10 倍, 解码加速约 10 倍。
码块分割 (§6.10.2)¶
当载荷超过单个 Polar 码块容量时, 进行码块分割:
无段内 CRC (FT2): 载荷等分为多个码块, 每块独立 Polar 编码
含段内 CRC (FT3/FT4): 每个码块附加额外 CRC, 增强可靠性
代码实现: common.code_block_seg 模块的 segment_without_crc() 和 segment_with_crc() 函数。
BCH 编码 (§6.11)¶
FT1 控制信息头部使用 BCH 码保护:
BCH(31,26): 可纠正 1 位错误
BCH(63,24): 可纠正更多错误, 用于更长的控制字段
代码实现: common.bch 模块。
信道比特加扰 (§6.10.4)¶
加扰使用 7 位 Galois LFSR, 多项式 \(x^7 + x^4 + 1\), 周期 127。种子 (whitening_seed) 在控制信息中标明, 收发端使用相同种子即可还原。
代码实现: common.scrambler.scramble(), 内部预计算一个周期的加扰序列后用 tile 扩展。
MCS 表 (§6.10.5-6.10.6)¶
调制与编码方案 (MCS) 索引决定了一次传输的调制阶数和码率:
MCS |
调制 |
每符号比特 |
码率 |
|---|---|---|---|
0 |
BPSK |
1 |
1/4 |
1 |
BPSK |
1 |
1/3 |
2 |
BPSK |
1 |
1/2 |
3 |
BPSK |
1 |
2/3 |
4 |
BPSK |
1 |
3/4 |
5 |
QPSK |
2 |
1/2 |
6 |
QPSK |
2 |
2/3 |
7 |
QPSK |
2 |
3/4 |
8 |
(无编码 FT1) |
1 |
1 |
9 |
8PSK |
3 |
1/2 |
10 |
8PSK |
3 |
2/3 |
11 |
8PSK |
3 |
3/4 |
MCS 8 用于 FT1 的不编码直通模式。速率匹配通过重复或打孔将 Polar 编码输出适配到目标资源数。
代码实现: common.mcs 模块定义了完整的 MCS 表和速率匹配参数。
跳频 (§6.10.3, §8.1)¶
SLE 窄带系统在 2402-2480 MHz 频段内使用 79 个信道 (1 MHz 步进)。跳频序列由伪随机数生成器驱动, 每个调度点切换一次信道。
关键参数:
跳频种子: 24 位, 决定序列的随机性
跳频地图: 79 位 bitmap, 标记每个信道的可用状态
最少可用信道: 有下限门限, 防止可用信道过少
代码实现: phy.freq_hopping 模块的 FreqTable, 管理信道列表、跳频序列和屏蔽操作。
发射流水线 (§6.10)¶
完整的 TX 处理链路 (phy.tx_pipeline.tx_chain):
应用数据
↓
CRC 附加 ← common.crc
↓
码块分割 ← common.code_block_seg
↓ (FT2-4)
Polar 编码 ← common.polar
↓
比特加扰 ← common.scrambler
↓
符号映射 ← phy.psk / phy.gfsk
↓ (FT2-4)
导频插入 ← phy.pilot
↓
帧组装 ← phy.frame
(前导 + 同步 + 控制信息 + 载荷)
↓
脉冲成型 ← RRC / GFSK 滤波
↓
复基带 IQ 信号输出
发射参数通过 TxConfig 配置, 包含帧类型、MCS 索引、PID、加扰种子、CRC 长度和导频间隔等。
接收流水线 (§6.10)¶
RX 处理链路 (phy.rx_pipeline.rx_chain) 是发射的逆操作:
复基带 IQ 信号输入
↓
匹配滤波 ← RRC / GFSK 频率鉴别
↓
帧同步 ← 同步序列互相关
↓
头部提取与解码
符号解映射 → 解扰 → Polar 解码 → CRC 校验
↓
导频去除 ← phy.pilot
↓
载荷解调与解码
符号解映射 → 解扰 → Polar 解码 → 码块重组 → CRC 校验
↓
数据比特输出 + CRC 状态
帧同步通过滑动互相关检测同步序列的峰值位置, 超过门限则认为检测到帧。
测量帧 (§6.3.6-6.3.11)¶
SLE 定义了多种专用测量帧, 用于定位和感知:
类型 |
结构 |
用途 |
|---|---|---|
测量帧类型 1 |
前导+同步+均衡保护+切换间隔+测量信号 |
窄带测距 |
测量帧类型 2 |
仅测量信号 |
简化测量 |
测量帧类型 3 |
前导+同步+均衡保护 |
信道探测 |
测量帧类型 4 |
完整数据帧+测量信号 |
通信+测量混合 |
UWB 脉冲测量帧 |
UWB 脉冲序列 |
超宽带测距 |
代码实现: phy.measurement_frame, phy.measurement, phy.measurement_tx 模块。
射频合规 (§8)¶
phy.rf_compliance 模块实现了标准第 8 章的射频参数校验:
发射机: 输出功率等级、GFSK 调制精度 (频偏容限)、PSK 调制精度 (EVM)、GFSK 杂散发射、PSK 频谱模板
接收机: 灵敏度与最大输入电平、信道选择性、杂散发射、RSSI 测量精度
UWB: 信道参数合规、频谱掩模、归一化均方根误差
这些校验函数返回合规/不合规的判定, 可用于仿真结束后的自动验证。