简介:这是一份聚焦星上路由交换与处理技术的专业课件,面向卫星通信、航天信息网络方向的学生、研究者和工程技术人员,用于解决星上信息高效传输与交换体制选择等核心问题。课件系统梳理了星上交换的关键概念、实现方法及典型交换体制,涵盖电路交换、分组交换、ATM、IP与MPLS等,并结合IPSTAR-1宽带卫星实例说明不同业务下的交换需求与波束间通信设计。压缩包约4MB,含1个pptx文件,课件内容结构完整,重点介绍了星上交换的意义、需考虑因素、射频交换与基带交换两条技术路线,以及星载电路交换、分组交换的优缺点对比和SS/TDMA、SS/FDMA等工作方式,可直接用于教学或自学。目前已有111人学习浏览,可作为系统理解星上路由交换与处理技术的直观参考。
1. 星上路由交换与处理技术:从透明转发到星上自主转发
一条测控指令从地面站发出去,经过星间链路绕行,再落到另一颗卫星的执行机构,中间要经过几次转发?如果星座里每颗卫星都只是把信号放大后原样扔出去,数据就得落地绕一圈,跨洋时延轻松冲到 400ms 以上,而卫星间激光链路的物理时延其实只有几毫秒。真正的瓶颈不在链路,而在节点上——星上没有路由器在干活。星上路由交换与处理技术,就是把地面网络的路由查表、分组转发、队列调度和协议处理搬进卫星平台,让星座自己完成端到端寻路,而不是依赖地面站中转。这项技术直接决定了星座的响应速度、带宽利用率和抗毁能力,是 LEO 星座、星间组网和高通量卫星绕不开的核心环节。读这篇文章的人,应该是做卫星通信系统、星载电子学或网络协议栈的工程师,你们关心的不是概念,而是靠什么芯片、按什么流程、用哪条命令把转发做出来。
2. 星上路由交换的协议栈组成与转发模型选择
2.1 为什么地面 IP 路由协议不能直接上星
星上网络与地面网络有一个根本差异:拓扑是高速时变的。LEO 卫星相对地面运动速度超过 7km/s,星间链路经常切换和中断,地面路由器之间那种 30 秒一次保持连接、失效要等 3 个 Hello 周期才收敛的机制,在星上会让路由表长期处于抖动状态。OSPF 的链路状态洪泛、BGP 的路径向量协商,设计前提都是链路相对稳定、节点算力充裕,这两条在星上都站不住。
另一个约束是资源。星载计算机的 CPU 主频低、内存容量小、功耗预算通常在几十瓦以内,其中大部分还要分给通信载荷。地面路由器上通过软件跑满动态路由协议、维护大数据量路由表的做法,在这里既不现实,也没有必要——一颗卫星的直接邻居数量一般在 2 到 6 个,整个星座的节点数也只有几十到几百个,完全可以用更收敛的表设计和更轻量的转发逻辑来完成。
这就引出了星上路由交换的核心设计思路:把协议栈分层拆开,感知链路变化的能力放在底层,寻路决策尽量简单化、静态化,把动态调整收敛到链路层切换和局部重路由上,而不是让所有卫星反复交换全星座的路由状态。
2.2 CCSDS 与 DTN 的两层协议适配
星上网络常见做法不是重新发明一套完整路由协议,而是在现有空间数据链路标准上做适配。CCSDS AOS(高级轨道系统,Advanced Orbiting Systems)空间数据链路协议定义了虚拟信道(Virtual Channel)和帧结构,每帧携带虚拟信道标识符 VCID,物理上天然具备多路复用和优先级区分的机制。路由交换的关键就是围绕 VCID 和目的地址做转发决策,而不是像 IP 那样处理完整的分组头。
对于需要容忍长时延和频繁中断的场景,会再叠加 DTN 捆绑层。DTN 的存储-转发(Store-and-Forward)机制让数据在链路中断时先保存在节点上,等链路恢复再发送。它与星上路由交换结合时,路由决策作用在 bundle 头部,转发单元按目的节点 ID 和链路可用性选择出端口。可以这样理解分层关系:DTN 负责端到端的可靠性和链路中断容忍,CCSDS 负责物理链路上的帧封装与多路复用,中间的路由交换模块决定每一帧或每一个 bundle 往哪个方向走。
协议分层上的常见权衡是:是否需要三跳以外节点的完整拓扑信息。对于拓扑可预测的 Walker 星座,每颗卫星的邻居关系是周期性的,完全可以离线计算出时序路由表,星上只做表项切换;只有对于异构星座或存在故障场景,才需要在星上维护一个精简的动态路由进程。
2.3 星上转发表设计与查表规则
转发表容量不大,但表项结构必须精打细算。以一颗卫星四个方向的星间链路端口加一个星地端口为例,一张典型的星上路由转发表字段如下。
| 字段名 | 宽度(bit) | 说明 |
|---|---|---|
| DestNodeID | 16 | 目的卫星或地面站节点标识 |
| PortID | 4 | 输出端口号,对应星间激光终端或星地链路 |
| NextHopID | 16 | 下一跳节点,用于链路层地址解析 |
| Priority | 3 | 转发优先级,决定队列调度权重 |
| Valid | 1 | 表项有效性标志 |
| Timestamp | 32 | 表项更新时间,用于超时管理 |
查表规则上,星上路由交换的地址空间比 IP 小得多,常见做法是直接用目的节点 ID 作为索引做精确匹配,而不是做最长前缀匹配。这样查表时延稳定、硬件实现简单,FPGA 里用一块 BRAM 就能实现查找。只有在需要聚合多个目的节点的地面站出口时,才会引入类似前缀匹配的规则,比如将所有落在地面站 1 的节点统一指到星地端口。
# 星上路由转发表的简化查表实现 class OnboardRouter: def __init__(self): self.fib = {} # 路由转发表:dest_id -> (port, next_hop, priority) self.default_hop = (3, 0, 0) # 默认出口:端口3,无效下一跳,最低优先级 def add_route(self, dest_id, port, next_hop, priority=0): self.fib[dest_id] = (port, next_hop, priority) def lookup(self, dest_id, vcid): # 精确匹配优先,miss 时走默认路由 entry = self.fib.get(dest_id, self.default_hop) port, next_hop, priority = entry # 动态链路检查:如果指定端口当前不可用,尝试备用端口 if not self.is_port_up(port): backup = self.get_backup_port(dest_id) if backup is not None: port, next_hop = backup else: return None return {"port": port, "next_hop": next_hop, "priority": priority} def is_port_up(self, port): # 模拟端口状态,由物理层上报 return port in [0, 1, 2, 3] # 示例实现 def get_backup_port(self, dest_id): # 静态备份路由,在实际系统中预置 return None这段代码体现了三个工程要点:一是转发表容量小,用 dict 模拟哈希查找,硬件里对应 CAM 或 BRAM 查找;二是默认路由兜底,避免查表 miss 导致丢帧;三是查表结果要和链路状态做联动,端口 down 时不是等路由协议收敛,而是立即查备份表项。实际固化进 FPGA 时,lookup 逻辑会被改写成流水线形式,一拍完成地址译码,一拍完成表项输出,整个查表过程控制在两三个时钟周期内。
3. 星上处理技术的工程实现:帧解析、查表与队列调度
3.1 异构计算架构:FPGA 做转发面,CPU 做控制面
星上处理技术落到硬件上,通常不是单一芯片包打天下。转发面要保证线速处理和确定性时延,FPGA 是首选;控制面要跑路由计算和协议交互,需要通用处理能力,用抗辐射加固的 CPU 芯片;如果还涉及信号级处理,比如星上解调、波束成形或者频率变换,再加 DSP 或专用 ASIC。三者通过片内高速互联或 SpaceWire、RapidIO 总线连接。
这种异构架构的分工原则是:报文来了,FPGA 直接从物理接口收帧、做校验、查表、调度、发出,全程不打断 CPU。只有当帧头携带控制信息,比如链路状态通告或者路由更新请求,FPGA 才把帧复制一份给 CPU 处理。CPU 负责维护转发表、计算新路由、下发表项到 FPGA 的存储区。这样做的好处是即使 CPU 因为空间粒子效应发生复位,转发面仍按最后一份有效转发表工作,不至于整星断网。
3.2 帧接收与校验的流水线划分
星上帧处理和地面网卡收包有一个明显区别:地面网卡可以依赖 CPU 中断和 DMA,星上转发更常见的是纯粹的硬件流水线。一级一级的处理环节是:
- 同步头检测:识别 CCSDS 帧同步字(常见 0x1ACFFC1D),完成位同步和字节对齐;
- 帧长校验:读出帧长度字段,和实际接收长度比对,超长帧直接丢弃;
- CRC 校验:CCSDS 标准使用 CRC-16 或 CRC-32,校验失败打错误标记;
- 虚拟信道解析:读取 VCID,做优先级分类和多路解复用;
- 目的地址提取:从应用数据区或自定义子网头部提取目的节点 ID;
- 转发表查询:按目的 ID 做精确匹配;
- 输出端口调度:根据端口和优先级入队。
每一步都是独立的流水级,用寄存器打拍隔开,这样每一级的组合逻辑时延不会成为瓶颈。这里最容易踩的坑是同步头检测的假同步问题——在噪底较高的星间链路上,随机数据里也可能出现与同步字相同的位模式。常见做法是在连续检测到 N 次同步字后才确认入锁,N 一般取 2 或 3,并在失锁后设置重新捕获的退避时间。
// 流水线关键路径的简化描述,用于说明级间寄存器的划分 typedef struct { uint32_t synced : 1; uint32_t crc_ok : 1; uint8_t vcid; uint8_t dest_id; uint8_t out_port; } rx_bus_t; rx_bus_t pipeline_stage[7]; // 每级一个寄存器组 void pipeline_cycle(rx_bus_t *buf_in, frame_t *frame_in) { // stage 0: sync detect pipeline_stage[0].synced = detect_sync(frame_in->header); // stage 1: length check uint16_t plen = frame_in->header.frame_len; pipeline_stage[1].synced = pipeline_stage[0].synced && (plen == frame_in->actual_len); // stage 2: crc check pipeline_stage[2].crc_ok = check_crc(frame_in->payload, frame_in->header.crc); // stage 3: extract vcid and dest pipeline_stage[3].vcid = frame_in->header.vcid; pipeline_stage[3].dest_id = frame_in->header.dest_id; // stage 4: fib lookup pipeline_stage[4].out_port = fib_lookup(pipeline_stage[3].dest_id); // stage 5: queue write enqueue(pipeline_stage[4].out_port, pipeline_stage[3].vcid, frame_in); }这个流水线示例里,每帧在一个时钟周期内只前进一级,七级流水让吞吐率不依赖单级的复杂逻辑。参数上需要注意:帧长字段是 16 位,最大表示 65535,但实际 CCSDS 帧通常不超过 2048 字节,配置帧长上限时如果设太大,会浪费 FIFO 空间;CRC 校验放在长度校验之后、地址提取之前,是为了让非法帧尽早被丢弃,避免在后续流水级浪费处理周期。
3.3 队列管理与加权轮询调度参数
星上链路的出口带宽远小于地面核心路由器,一个 2.5Gbps 的星间激光终端在同一时刻只能发一个帧。因此输出端口的队列调度直接决定不同业务的时延和丢包表现。常见的星上处理层次安排三个队列:高优先级队列放测控指令和信令,中优先级放业务数据,低优先级放遥测和日志。调度算法多采用严格优先级(SP)与加权轮询(WRR)的组合:只有当高优先级队列为空时才服务中优先级队列,中优先级队列中再用权重分配带宽。
队列深度和丢弃门限是两个最需要调的参数。队列深度太浅,瞬时突发就把帧丢了;太深会引入排队时延,影响测控类的实时性。以典型星载交换机为例,单端口队列深度设置为 256 个最大帧长度,高优先级队列采用尾部丢弃,低优先级队列采用随机早期检测(RED)。多个优先级共享缓存时,建议给高优先级划出专用的不受限区域,避免低优先级突发占满整块缓存导致高优先级也丢帧。
4. 本地复现星上路由转发的最小验证环境
4.1 用 Python 搭建三节点星上转发模拟器
完整的星载硬件环境不是每个人手里都有,但在软件里验证路由交换逻辑的算法正确性非常容易。我们写一个只有三个节点(两颗卫星加一个地面站)的离散事件模拟器,把第二节和第三节的核心逻辑跑通,再看端到端时延和丢包率。这个模拟器不能替代硬件仿真,但它能把查表规则、队列调度和链路失效处理的 bug 提前暴露出来。
import simpy import random import statistics class SatelliteNode: def __init__(self, env, name, ports, queue_size=8): self.env = env self.name = name self.ports = ports # 端口列表,例如 [0, 1, 2] self.fib = {} # 目的节点 -> (输出端口,优先级) self.queues = {p: [] for p in ports} # 每个端口一个队列 self.queue_limit = queue_size self.sent_count = 0 self.drop_count = 0 self.delay_samples = [] def add_route(self, dest_id, port, priority=0): self.fib[dest_id] = (port, priority) def process_frame(self, src, dst, payload_len): if dst not in self.fib: self.drop_count += 1 return port, prio = self.fib[dst] if len(self.queues[port]) >= self.queue_limit: self.drop_count += 1 return enqueue_time = self.env.now self.queues[port].append((src, dst, payload_len, enqueue_time, prio)) # 触发发送进程 self.env.process(self.forward(port)) def forward(self, port): while self.queues[port]: frame = self.queues[port].pop(0) src, dst, plen, enqueued, prio = frame # 星间链路处理时延 + 排队时延 + 传播时延 proc_delay = 0.001 # 1ms 处理时延,对应 FPGA 流水线 prop_delay = random.uniform(2, 5) # 星间传播 2-5ms yield self.env.timeout(proc_delay + prop_delay) self.sent_count += 1 self.delay_samples.append(self.env.now - enqueued) receiver = node_map[dst] # 节点间用链路时延模拟 yield self.env.timeout(prop_delay) if dst in receiver.receive_targets: receiver.on_receive(src, dst, plen) def on_receive(self, src, dst, plen): if dst == self.name: pass # 到达目的地 else: self.process_frame(src, dst, plen) env = simpy.Environment() node_A = SatelliteNode(env, "SAT-A", ports=[0, 1]) node_B = SatelliteNode(env, "SAT-B", ports=[0, 1]) node_G = SatelliteNode(env, "GND", ports=[0]) node_map = {"SAT-A": node_A, "SAT-B": node_B, "GND": node_G} # 转发表配置:A 访问 GND 走 B,B 访问 GND 直连 node_A.add_route("GND", 0) node_A.add_route("SAT-B", 0) node_B.add_route("GND", 0) node_B.add_route("SAT-A", 0) node_G.add_route("SAT-A", 0) node_G.add_route("SAT-B", 0) def send_traffic(): for _ in range(100): env.process(node_A.process_frame("SAT-A", "GND", 1400)) yield env.timeout(random.uniform(1, 3)) # 随机到达间隔 1-3ms env.process(send_traffic()) env.run(until=100) print("节点A发送帧数:", node_A.sent_count) print("节点A丢帧数:", node_A.drop_count) print("平均端到端时延(ms):", statistics.mean(node_A.delay_samples))这个模拟器的关键在于:转发表里把 SAT-A 到 GND 的下一跳设为端口 0,指向 SAT-B,由 SAT-B 完成最后一跳转发,复现了星上多跳路由的完整链路;队列限长设为 8 帧,模拟了尾部丢弃策略;处理时延设为 1ms,比真实 FPGA 流水线慢很多,但用来验证排队逻辑足够了。跑完后如果发现丢帧率偏高,优先检查 input traffic 的到达间隔和队列限长的匹配关系。
4.2 验证转发正确性的三个观测点
运行一次模拟后,不要只看丢包率。建议检查三条线索来定位问题:第一,到达目的节点的帧的源地址是否是预期源头,防止查处转发表的环路;第二,队列最大占用是否逼近队列限长,如果队列长期满,说明输出带宽不足或入口突发过大;第三,时延样本的分布是否出现长尾,长尾意味着队列中出现了高优先级帧之外的排队堆积。
下面的参数表整理了这个最小验证环境的推荐初始值和常见调整方向,你可以根据自己的场景先跑通,再逐个修改对比:
| 参数 | 推荐初始值 | 调整方向 |
|---|---|---|
| 帧到达间隔 | 1-3ms 均匀分布 | 间隔越小,越容易触发丢帧 |
| 队列深度 | 8 帧 | 提高可降低丢包,但增加时延 |
| 星间传播时延 | 2-5ms 均匀分布 | 星座高度和星间距离决定 |
| 节点处理时延 | 1ms | FPGA 实现中应低于 0.05ms |
| 转发表 miss 处理 | 丢弃并计数 | 可以改为丢向默认端口 |
5. 让星上路由交换更接近工程态:时敏调度与故障倒换的小技巧
前面的实现能跑通,但离实际入轨的星载交换设备还有一段路。最后一层关键差距在于时间确定性。星上很多业务是严格周期性的,比如星间捕获后的跟踪信标、测距帧、时统同步信号,这类帧不能容忍排队抖动。把地面 IEEE 802.1Qbv 的时间感知整形思想移植到星上是可行方向:为每个输出端口建立时间门控表,在特定时间段内只放行指定 VCID 的帧,其他帧暂存。工程落地时,门控周期通常设置为 125 微秒的整数倍,和 CCSDS AOS 的帧周期对齐,配置错误会导致所有帧被卡住,验证时必须用示波器测量物理端口上的帧间隔。
故障倒换上,建议做两层保护。第一层是端口级的快速检测,用物理层信号丢失或者同步字失锁作为触发条件,将转发表中指向失效端口的表项在微秒级切换到备份端口;第二层是节点级的主备冗余,CPU 通过 SpaceWire 总线同时管理两张转发表,主表故障时直接切换整个表区。切换时间要求取决于业务容忍度,测控业务要求 10ms 内完成,业务数据可以放宽到 1 秒。
最后一个实用技巧是转发表序号的校验机制。CPU 下发转发表到 FPGA 时,数据经过总线可能受到单粒子翻转干扰,所以表项里一定要带上校验和字段。FPGA 加载完表项后回读校验和,与 CPU 计算的期望值比对,不一致就拒绝启用并上报。可以在查表模块中周期性对所有表项做异或校验,这是成本很低但能显著提升可靠性的一招。把这些收尾工作做扎实,星上路由交换与处理技术才算从跑通变成了跑稳。
本文还有配套的精品资源,点击获取