上一篇推出了对时的数学,也埋了个伏笔:从时钟算偏移要减 correctionField,这个字段到底是什么?

一句话答案:它是报文携带的"时间修正值",记录着从 GM 到你这儿,一路上所有耽搁。 这篇讲清楚三件事:交换机为什么会"偷"时间、偷了多少怎么量、怎么连本带利记进账。

一、交换机每转一手,都在偷时间

设想一条链:GM → 交换机 → 从时钟。GM 在时刻 t1 发出 Sync,报文到了交换机——它不会立刻出去。

存储转发(store-and-forward)是基本操作:交换机得把整个帧收完、查表、决定从哪个口转,这期间报文就压在缓存里。如果出口队列里正好排着别的报文,等得更久。等终于轮到自己出去,时刻已经变成了 t1 + 一堆说不准的延时。

这段"从来到走"的真实墙钟时间,就是 residence time(驻留时间):

residence time = 报文离开交换机的硬件时刻 − 报文进入交换机的硬件时刻

两个端点都由硬件时间戳量,和报文里 Sync 的时间戳同源。

驻留时间有多大?没有固定值——它就是队列深度的函数:

  • 网络空闲:几百 ns 到几 µs
  • 突发拥塞:几十 µs 甚至更多,且每帧都不一样

问题就在这个"每帧都不一样":gPTP 的精度目标是亚微秒,而一跳交换机随随便便就偷走几 µs,还带抖动。如果不处理,Sync 的"时间基准"功能直接作废——下游看到的 t2 里混着一坨随机噪声,offset 抖成筛子。

所以标准给报文开了一个字段:correctionField。交换机每转一手,把自己偷的时间如实记进去,下游减掉就是——偷了不怕,记账就行。

二、记账规则:一笔总账

correctionField 是 64 位无符号整数,单位是 scaledNanoseconds——不是裸纳秒,是纳秒左移 16 位:

1 LSB = 2^-16 ns ≈ 0.0153 ps

为什么要缩放?固定的小数点精度下,既能表示亚 ns 的修正量,又有足够的整数位累加全程延迟——一次换算乘法移位就完成,硬件友好。

记账规则(P2P 机制,gPTP 默认):

Sync 转发时的 correctionField
    = 收到的 Sync 原值
    + 本跳 residence time
    + 本端口 Pdelay 测得的链路延迟
  • residence time:补"在我这儿耗的"
  • 链路延迟:补"进出我这根线路上花的"——每跳的线延迟由各端口独立 Pdelay 测得,转发时顺手加账

于是一次同步结束,从时钟收到的 Sync 里,correctionField 已经累加了"GM → 我这"的全部:

GM 发出 → 交换机1 驻留 → 链路 → 交换机2 驻留 → 链路 → 从时钟收到
    ↓         ↓                    ↓
  原值        +residence1+link1    +residence2+link2

从时钟算偏移时:

offset = (t2 − t1 − correctionField) ... 再按 P2P 规则折算

本质上就是 上一篇的 (t2 − t1) − d——只不过 d 不再由末端一次 Delay_Req 全程测量,而是沿途逐跳记账累计。殊途同归。

one-step 模式下,correctionField 直接由硬件在 Sync 发出那一刻实时填入;two-step 模式下放 Follow_Up 里。

三、关键设计:BC 是"消化",不是"记账"

这里有个容易混淆的点:既然交换机能记账,为什么车载网络还是默认 BC,而不是当个 TC(透明时钟,原样转发 + 记 residence)?

看两种角色的本质区别:

TC(透明时钟)BC(边界时钟)
转发方式原样转发,correctionField 累加下游口以主时钟身份重新生成 Sync
误差走向每跳的驻留测量误差往报文里累加驻留误差在 BC 内部被时钟伺服消化,不进报文
级联表现跳数越多,correctionField 里的噪声项越多下游看到的是"干净的"同步源,误差不级联
下游视角GM 还是那个 GM,只是路远GM 是 BC 自己(stepsRemoved +1)

BC 的玩法:上游口老老实实当从时钟,把本地时钟同步到 GM;下游口摇身一变当主时钟,用本地时钟重新盖 Sync 的 t1 发出去。交换机内部转那一手的驻留时间,压根不出现在报文里——它已经被吸收进"BC 本地时钟对准 GM"这件事里了。

TC 是"账记得多但笔笔带噪声",BC 是"账不往报文记,内部一锤定音"。级联场景 BC 的误差可控性更好,这就是 802.1AS 选 BC 当默认转发姿势的原因。correctionField 的逐跳累加,更多是 TC 方案和 P2P 链路延迟上报的场景。

四、数值感受:补和不补的差距

一条三跳链,每段链路延迟 200 ns,每跳交换机驻留平均 3 µs(抖动 ±1 µs):

不补偿:从时钟看到的"路径延迟" = 200ns×3 + 3µs×3 ≈ 9.6 µs,且抖动 ±3 µs
补偿后:correctionField ≈ 9.6 µs 全额入账
        从时钟减掉后,剩下的误差只有各跳测量噪声 → 几十 ns 量级

亚微秒的精度目标,就是靠这一笔笔账撑起来的。correctionField 不是一个可选的优化字段,它是 gPTP 精度的命脉。

五、排查:correctionField 异常怎么看

抓包时盯这几个现象:

  1. correctionField 跳变不连续:相邻 Sync 的 correctionField 忽大忽小,说明某一跳的驻留测量抽风——查那台交换机的队列拥塞,或者硬件时间戳单元异常
  2. offset 收敛慢且长期抖动:驻留抖动的根源是突发流量,看网络里有没有大流量没走整形(Qbv/CBS),或者控制面报文优先级被压低
  3. offset 稳定但偏大:账少了——某跳交换机没开 gPTP 透传/补偿功能,或者 Pdelay 测量失败导致链路延迟没入账
  4. Follow_Up 的 correctionField 与 Sync 的不一致:两步法下两者本应相等,不等就是实现 bug,换芯片/升级固件

经验之谈:怀疑对时问题时,先在 GM 出口、每跳 BC 出口、末端从时钟三个点同时抓包,看 correctionField 是哪一跳开始不对劲的——分段定位,比看末端 offset 猜高效得多。

六、第一批收官

四篇连起来,gPTP 基本原理就闭环了:

  1. 地图:TSN 协议族里,gPTP 是地基
  2. BMCA:全网靠一套优先级比较规则,收敛到唯一 GM
  3. 对时数学:四个时间戳算出偏移和延迟;gPTP 默认 P2P 逐跳测链路
  4. 本篇:correctionField 逐跳记账,BC 内部消化,补回交换机偷的时间

第二批已开篇:Qbv 时间感知整形器——全网对好表之后,怎么用这张表做确定性调度。那才是 TSN "确定性"的真正兑现,也是和 Qbu 帧抢占、802.1CB 冗余联动的一层。

你们交换机上的 gPTP 是硬件补偿还是软件?offset 实测能压到多少 ns?评论区报个数,下批开写前我想摸摸大家的底。

TSNgPTP802.1AS时间同步correctionField