2. TSN核心协议栈解析:时间同步、整形、抢占与冗余
好,咱们进入正题。TSN 协议栈听起来高大上,其实拆开来看,核心就四个协议:802.1AS(时间同步)、802.1Qbv(时间感知整形)、802.1Qbu(帧抢占)、802.1CB(冗余管理)。这四个家伙配合起来,才能让以太网从「尽力而为」变成「确定性传输」。
我个人习惯,学协议栈一定要先搞懂「为什么需要它」。不然你光看标准文档,很容易被绕晕。咱们一个一个来。
2.1 802.1AS:时间同步——整个TSN的「心跳」
说白了,TSN 所有的时间敏感调度,都依赖一个前提:全网设备的时间必须一致。你想想看,如果 A 设备说「8点整发数据」,B 设备说「8点整收数据」,但两个设备的时钟差了几微秒,那调度就全乱套了。
802.1AS 就是干这个的。它基于 IEEE 1588 精确时间协议(PTP),但针对桥接网络做了优化。我当年第一次调这个协议时,踩过一个坑:你以为同步精度只跟硬件有关,其实软件处理时间戳的位置更关键。
具体怎么工作的?简单说三步:
- 主时钟选举:网络里选一个「老大」(Grandmaster),其他设备都跟它对齐。
- 延迟测量:测量链路传播延迟,消除线缆长度带来的误差。
- 时钟同步:每个从设备根据主时钟的 Sync 报文,调整自己的本地时钟。
嗯,这里要注意:802.1AS 用的是「两步法」——先发 Sync 报文,再发 Follow_Up 报文携带精确时间戳。为什么这么麻烦?因为硬件打时间戳需要时间,不能把时间戳塞在 Sync 报文里一起发出去。
2.2 802.1Qbv:时间感知整形——给数据流排个「红绿灯」
有了统一的时间,接下来就要解决「谁先发、谁后发」的问题。传统以太网是 CSMA/CD,大家抢着发,撞了就退避。这在工业控制里是灾难——你永远不知道一个关键指令会不会被堵在路上。
802.1Qbv 的思路很直接:把时间切成一个个小窗口,每个窗口只允许特定优先级的数据通过。就像十字路口的红绿灯,时间到了,该谁走谁走。
具体实现上,每个端口有 8 个队列(对应 8 个优先级),每个队列有一个「门控列表」(Gate Control List, GCL)。GCL 里定义了每个时刻,哪个队列的门是开的,哪个是关的。
// 一个典型的 GCL 配置示例(伪代码)
// 周期 1ms,分成 4 个时间槽
GCL:
Slot 0: 0us - 200us, Gate[7] = OPEN, 其他 = CLOSE // 最高优先级,时间敏感流
Slot 1: 200us - 500us, Gate[5] = OPEN, 其他 = CLOSE // 音视频流
Slot 2: 500us - 800us, Gate[3] = OPEN, 其他 = CLOSE // 普通数据流
Slot 3: 800us - 1000us, Gate[0] = OPEN, 其他 = CLOSE // 尽力而为流
你可能会问:那时间槽的边界怎么对齐? 这就回到 802.1AS 了。所有设备的 GCL 都基于同一个主时钟,所以全网的门控动作是同步的。我曾经调试过一个系统,因为 802.1AS 没调好,导致两个交换机的 GCL 相位差了 100 微秒,结果时间敏感流在中间节点被堵了整整一个周期。
2.3 802.1Qbu:帧抢占——别让大包堵了小包的路
好,现在时间槽分好了,但还有一个问题:如果一个长帧(比如 1500 字节的普通数据)正在发送,突然来了一个高优先级的时间敏感帧,怎么办? 按照传统以太网,必须等长帧发完,时间敏感帧才能发。这一等可能就是几十微秒,对于要求微秒级抖动的应用来说,不可接受。
802.1Qbu 的解决方案是:允许高优先级帧「打断」低优先级帧的发送。低优先级帧被拆成两段,先发一个片段,等时间敏感帧发完,再发剩下的片段。
具体机制是这样的:
- 低优先级帧在发送前,先检查是否有高优先级帧在等待。
- 如果有,低优先级帧在下一个「可抢占点」暂停,发送一个「片段结束」标记。
- 高优先级帧插入发送。
- 高优先级帧发完后,低优先级帧从暂停点继续发送剩余部分。
嗯,这里有个关键点:不是所有帧都能被抢占。802.1Qbu 规定,只有长度超过 128 字节的帧才允许被抢占。而且被抢占的帧在接收端需要重组,这要求接收端硬件支持帧重组功能。
2.4 802.1CB:冗余管理——别让一根线断了就完蛋
工业场景里,可靠性是命根子。一根网线断了,生产线停了,损失可能上百万。802.1CB 就是解决这个问题的——通过冗余传输,确保即使一条路径断了,数据也不会丢。
它的思路其实不复杂:
- 序列号标记:发送端给每个数据包打上一个序列号(Sequence Number)。
- 冗余传输:同一个数据包,通过两条(或多条)不同的路径发送。
- 去重接收:接收端根据序列号,只保留第一个到达的包,丢弃重复的包。
你可能会想:这不就是简单的双发选收吗? 对,但 802.1CB 把这件事标准化了,包括序列号的编码方式、冗余标签的格式、去重的算法等等。
具体到帧格式,802.1CB 在原始以太网帧里插入了一个「冗余标签」(Redundancy Tag, R-Tag),包含序列号和路径标识。接收端根据这个标签做去重。
// 802.1CB 帧结构示意
+----------------+----------------+----------------+----------------+
| 目的MAC (6B) | 源MAC (6B) | R-Tag (6B) | 原始数据 (46-1500B) |
+----------------+----------------+----------------+----------------+
| | 序列号 (2B) | 路径标识 (4B) |
+----------------+----------------+----------------+----------------+
2.5 四个协议如何协同工作?
好了,四个协议都讲完了。但它们是各自为战吗?当然不是。我画个简单的逻辑链:
- 802.1AS 提供统一的时间基准。
- 802.1Qbv 基于这个时间基准,做门控调度。
- 802.1Qbu 在门控调度的间隙,处理突发的高优先级帧。
- 802.1CB 确保整个链路在物理故障时依然可靠。
举个例子你就明白了:一个工业机器人控制器,每 1ms 要发送一个位置指令。这个指令走的是 802.1Qbv 的最高优先级时间槽。如果此时有个大文件正在传输(低优先级),802.1Qbu 会打断它,让指令先走。同时,这个指令通过 802.1CB 在两条冗余链路上同时发送,确保万无一失。而这一切,都建立在 802.1AS 的精确时间同步之上。
好了,这一章的内容就到这。下一章咱们会深入 802.1Qbv 的 GCL 配置,手写一个简单的门控调度器。到时候我会分享一些我在 Linux 内核里调试 Qbv 驱动时踩过的坑,保证让你少走弯路。