4. 802.1Qbv 门控列表(Gate Control List)基础:定义、格式与调度周期
好,我们直接进入正题。门控列表,也就是 GCL,是整个 802.1Qbv 最核心的东西。你想想看,如果没有 GCL,那时间感知整形就是个空壳子,交换机根本不知道什么时候该开门、什么时候该关门。
我在前几年做某个车载以太网项目时,第一次在示波器上看到严格按照 GCL 跑出来的流量,那个整齐劲儿,真的是让人舒坦。不过,前提是你得把 GCL 写对。这一节,我就把我积累的经验和踩过的坑,都跟你聊聊。
4.1 什么是门控列表?
GCL 说白了,就是一张时间表。它告诉交换机的每个端口,在未来的某个时间点,哪个队列的门是开的,哪个门是关的。
这张表由交换机硬件周期性地读取和执行。硬件按照一个固定的时间循环,在每一个时间点,切换门的状态。
- 条目(Entry):表中的一行。每个条目包含一个时间偏移量和一个门状态数组。
- 时间偏移(TimeInterval):当前条目相对于调度周期起始点的时间。注意,是值,不是增量。
- 门状态数组(GateState):一个 8 位的值。每一位代表一个优先级队列(0~7),1 表示开,0 表示关。
核心观念
GCL 是一个循环执行的静态配置表。它一旦写好,在运行过程中是不会变化的(除非你进行重配置)。
4.2 GCL 的格式与结构
标准的 GCL 格式并没有我们想象得那么复杂。你跟我一起看这个表,基本就能理解了。
| 字段 | 字节长度 | 说明 |
|---|---|---|
| TimeInterval | 4 字节 | 当前条目执行的时间,单位是纳秒。这个时间是以 Cycle Time 的起始点为 0 计算的。 |
| GateState | 1 字节 | 8 个队列的门状态。Bit[0] 对应队列 0(最低优先级),Bit[7] 对应队列 7(最高优先级)。 |
| Reserved | 3 字节 | 保留字段,必须全为 0。我在项目中发现,有些厂商的芯片如果在这个字段写入了非零值,会直接丢弃整个 GCL 配置。 |
嗯,这里要注意一点:时间偏移。很多初学者会把它误解为「持续时间」。其实不是这样的。它是从周期开始到当前条目生效时刻的时间。
举个例子,如果周期是 500us,第一个条目的 TimeInterval 是 0us,表示周期一开始就执行这个状态;第二个条目如果 TimeInterval 是 200us,那表示在周期运行到 200us 时,切换到第二个状态。
我曾经踩过的坑
在某次调试时,我写了一个 GCL,第二个条目的 TimeInterval 是 100us,第三个条目是 200us。但我把第三个条目的 GateState 写成了 0x00(全关),导致 200us 之后所有队列都关门了。结果就是,整个周期的后半段,任何数据都发不出去。排查了很久才找到原因。
所以,在设计 GCL 时,一定要想清楚最后一个时间点之后的数据怎么处理。通常,我们会在最后一个条目之后,保留一个「开门」的状态,或者直接用保护带机制来处理。
4.3 调度周期(Cycle Time)与 GCL 长度
调度周期,是所有 GCL 循环的总长度。这个参数是在端口配置中定义的。GCL 本身并不直接包含周期长度信息,它只是定义了周期内的各个时间点。
GCL 的长度,也就是包含多少个条目,是由应用场景决定的。条目越多,调度粒度越细,但硬件资源的占用也更大。
我个人的习惯是,先确定目标应用的流量模型。比如,对于音视频流,周期通常是 125us;对于工业控制,周期通常是 1ms。然后,再在这个周期内,根据流量的发送时间点,反推 GCL 的条目。
实战建议
在测试过程中,我发现很多设备支持最多 256 个 GCL 条目。但这并不意味着你要用完它们。一般来说,4~16 个条目就足以覆盖 90% 的工业场景了。条目过多,调试起来会比较痛苦。
为什么 GCL 的执行是循环的?因为硬件在每个周期结束时,会重新从第一个条目开始执行。所以,你设计的 GCL 必须是一个闭环。举个例子,如果你的周期是 1ms,那么最后一个条目的 TimeInterval 加该条目的执行时间,必须等于 1ms?其实不需要。硬件在达到 Cycle Time 后会强制复位。
但是,这里有陷阱。如果最后一个条目的 TimeInterval 加上某个持续时间的总和超过了 Cycle Time 怎么办?标准处理方法是,超出的部分会被丢弃,硬件直接跳到周期起点。如果你的 GCL 最后一个时间点之后还有数据没发完,这些数据就会被截断或推迟到下一周期。
| 参数 | 典型值 | 我常用的值 | 备注 |
|---|---|---|---|
| Cycle Time | 125us / 1ms / 2ms | 1ms | 兼容性最好,大多数交换机都能稳定支持 |
| GCL 条目数 | 4~128 | 8 | 既能精细控制,又不会占用太多硬件资源 |
| 最小时间偏移 | 0 ns | 0 ns | 周期的第一个状态 |
| 最大时间偏移 | < Cycle Time | Step Size 的整数倍 | 必须小于 Cycle Time |