TSN 专题 · 第二批 · 开篇:第一批把 gPTP 讲完了——全网对好了表。这篇讲这张表的第一个大用途:Qbv 时间门。
第一批四篇讲完,全网还挂着同一条时间轴。光有时间还不够——时间只是原料,把原料做成"确定性"的,是 Qbv。
这篇讲 802.1Qbv:每个出口队列一道门、按时刻表开合,把"尽力而为"的排队变成"排班表"式的转发。
一、普通交换机为什么给不出"有界延迟"
传统交换机的出口调度就两招:FIFO 和严格优先级(SP)。两招都有同一个致命问题——延迟无界。
严格优先级下,只要高优先级队列不空,低优先级就一直等。高优流量一个突发涌进来,低优报文能等到天荒地老。你指着一个报文问"你最坏什么时候发出去",没人答得上来。控制流被堵几十毫秒,在车载场景就是事故。
AVB 时代的信用整形(Qav)按信用额度平滑突发,缓解了拥塞,但延迟依然没有硬界。TSN 的要求反过来:每条流的最坏延迟必须算得出来。怎么做到?答案是——别再让队列"抢",让队列"排班"。
二、Qbv 的核心:每队列一道门,按时刻表开合
802.1Qbv 的大名是 Time-Aware Shaper(TAS,时间感知整形器)。机制一句话:
每个出口有 8 个优先级队列(对应 802.1Q 的 priority 0–7),每个队列门口一道"门"。所有门的开合由一张按时间推进的时刻表控制——到点该开的开、该关的关。
这张表学名叫 GCL(Gate Control List,门控列表)。结构极简,每条目就两类信息:哪些门开、开多久。一个周期(cycle time)内排满,然后循环:
| 条目 | 开哪些门 | 持续 | 用意 |
|---|---|---|---|
| 1 | 仅 Q7 | 60 µs | 安全控制流专属窗口 |
| 2 | Q6 | 100 µs | 周期控制流窗口 |
| 3 | Q4 | 60 µs | 音视频流窗口 |
| 4 | 全部 | 30 µs | 兜底:尽力而为 + 剩余流量 |
| — | 合计 | 250 µs | 一个 cycle,到头自动回到条目 1 |
cycle = 250 µs(循环)
[ Q7 开 60µs ][ Q6 开 100µs ][ Q4 开 60µs ][ 全开 30µs ]
几个要点:
- 门是位图:一个 8 比特向量,每比特对应一道门,1 开 0 关。一个条目里可以同时开多道门——同时开着的队列之间再用严格优先级(或权重)分胜负
- cycle time 是节奏锚:典型值 125 µs / 250 µs / 500 µs / 1 ms,一般取流周期的公约数,保证每条流每个周期恰好被服务一次
- 起点必须对齐 gPTP 时间:时刻表有 base time(起始时刻),全网站点以 GM 时间为基准同步启动。各跳的"开门点"对不齐,Qbv 就是摆设——这就是为什么第一篇就讲 gPTP
- 切换粒度有硬件下限:条目时长有最小分辨率(常见 1 µs 量级,视芯片而定),芯片里 GCL 条目数也有限(几十到几百条),排表时都是硬约束
三、保护带:门不能"说关就关"
理想很美满:60 µs 到点关 Q7 开 Q6。现实是——帧不可打断。
以太网帧一旦开始发送就要发完(没有 Qbu 抢占的话,1500 字节在千兆车载链路上要占约 12 µs)。门在帧发送中途关闭,要么把帧憋回去(撕裂帧,上层不可接受),要么等它发完。标准选后者:门的关闭动作延迟到当前帧的帧边界生效。
于是有个坑:你说"60 µs 关 Q7",可 59.9 µs 时 Q7 刚捞起一帧 1500B 开始发,这帧要占到 72 µs——下一个条目被推迟 12 µs,下一条流的窗口被啃掉一口。
对策是 保护带(guard band):每个条目的预留时长里,除了本队列的预计发送时间,还要额留一段"够最大帧发完"的时间。这段保护期为当前帧的收尾兜底,本质是用带宽换确定性。
保护带是纯开销:1500B 的帧在千兆下保护带就要约 12 µs,一个 250 µs 的周期里每条目都留,带宽利用率肉眼可见地往下掉。这正是 802.1Qbu 帧抢占存在的理由——把小帧从大帧屁股后面捞出来,保护带才能从"一整个大帧"缩到"一个碎片"。下一篇讲它。
四、最坏延迟:从"看运气"到"算得出来"
Qbv 上值的不是"平均延迟低",而是最坏延迟有界且可算。一个报文从进队列到发出,最坏情况由这几段构成:
| 段 | 说明 | 上界怎么来 |
|---|---|---|
| 等当前帧 | 出口正在发的帧要发完 | 最大帧长 / 链路速率 |
| 排队 | 本队列里排在前面的同队列帧 | 每个窗口内本队列的配额 |
| 保护带 | 切换条目前的收尾等待 | 同上,最大帧发送时间 |
| 自身发送 | 自己的帧发出去 | 帧长 / 链路速率 |
更关键的是跨队列的干扰被时刻表封死了:高优先级流只能在给它开的窗口里发,窗口外再急也得等着——干扰量 = 对方窗口内可能排队的帧数 × 帧发送时间,是个排表时就算得出来的数。
对比一下:同样两条流,严格优先级下低优流的最坏延迟取决于"高优流在整个测量窗口内能塞多少帧",突发一大就没边;Qbv 下取决于"对方窗口配额内能塞多少帧",排表时即封顶。
这就是"确定性"的工程含义:不是平均更快,是 worst case 可证明。功能安全评审时,你要拿得出的正是这个数。
五、时刻表从哪来:这是个调度问题
GCL 不是拍脑袋填的,它是一个调度问题:给定一组流的周期、deadline、帧长,给每条流分配窗口,使所有 deadline 满足。这事儿计算上不简单(装箱加时序约束),工程上三条路:
- 手工排:流少(十几条以内)、周期整齐时,表格排得过来——很多早期车载项目就是这么干的
- 离线工具算:求解器或芯片厂的配置工具,喂进流规格表,吐出 GCL
- 在线集中式计算(802.1Qcc):由中央控制器(CNC)统一算好全网每台交换机的 GCL 再下发,流的增删改全走控制面,转发面只管执行
无论哪条路,排表心法就一条:周期取公约数、deadline 留余量、保护带按最大帧算。排得再漂亮的表,保护带漏算,现场一定翻车。
六、工程上的几个坑
- base time 没对齐:各站点 GCL 起点各说各话,门控互相错位——现象是"同步明明达标了,延迟抖得像没开 Qbv"。先查 OperBaseTime 是否已同步生效
- Admin/Oper 两张表:Qbv 的配置分 admin(你想配的)和 oper(实际在跑的)两套,配完不立刻生效,要等 ConfigChange 触发的切换点。抓包看不到这个,去查芯片寄存器
- 周期和流周期对不齐:cycle time 没取流周期的公约数,某条流隔周期被饿一顿——deadline 超标,一查是排表的锅
- GCL 条目数超限:芯片条目数有上限,表排得太细直接刷不进去,降粒度或者砍流
- 忘了 Qbu:保护带按最大帧留,带宽白白流走——车载千兆链路上这不是小数目
七、结语
Qbv 把交换机的出口从"抢麦克风"改成了"排班表":每个流知道自己几点几分能上场,最坏延迟算得出来。配上第一批 gPTP 对好的表,TSN 的"确定性"到这里才算真正落地——时间是原料,门控是工艺。
下一篇讲 Qbu 帧抢占:怎么把保护带从"一整个大帧"缩到"一个碎片",以及它和 Qbv 怎么配合。这对组合拳打完,车载低延迟控制的最后一块短板才补上。
你们项目里 GCL 是手排的还是工具算的?cycle time 一般取多少?评论区报个数。
TSN 专题 · 第二批(门控与抢占)
(一)本篇:802.1Qbv 时间门基本原理 ·(二)Qbu 帧抢占
第一批(gPTP 基本原理):(一)全景 · (二)BMCA · (三)对时数学 · (四)correctionField