2.10 不仅是相位对齐:频率同步的秘密
两个时钟,两个“心跳“
想象两个跑步者在跑道上跑步。
情况一:两个人跑得一样快,但位置不同。
- 跑步者A在起点
- 跑步者B在起点前10米
这是相位偏差。解决方案:让B后退10米,两人就同步了。
上一节讲的相位调整,就是这个“后退10米“。
情况二:两人位置相同,但速度不同。
- 跑步者A每秒跑10米
- 跑步者B每秒跑10.1米
这是频率偏差。即使现在位置相同,10秒后B就会领先1米。
相位调整只解决了“现在并排“,但没有解决“一直并排“。
这一节,我们深入探讨频率同步——如何调整时钟的“心跳速度“。
什么是频率偏差?
频率偏差(Frequency Offset):从时钟的走时速度与主时钟走时速度的差异。
符号:y 或 Δf/f
单位:无量纲(ppm、ppb等)
比喻:两个跑步者,一个每秒跑10米,一个每秒跑10.01米。这0.01米/秒的差异就是频率偏差。
关键洞察:
相位偏差是频率偏差累积的结果:
相位偏差 = ∫ 频率偏差 dt
示例:
频率偏差 = +10 ppm(从时钟比主时钟快万分之一)
经过1000秒
相位偏差 = 10 ppm × 1000秒
= 10 × 10⁻⁶ × 1000
= 0.01秒
= 10毫秒
即使相位调整让时钟对齐了,频率偏差会让它们重新分开。
为什么频率同步如此重要?
场景一:保持模式(Holdover)
假设从时钟同步到主时钟,相位偏差接近0。
突然,主时钟故障,从时钟失去参考。
如果从时钟没有频率同步:
- 本地晶振频率偏差:+10ppm
- 每秒累积误差:10微秒
- 每分钟累积误差:600微秒
- 每小时累积误差:36毫秒
如果频率已同步:
- 知道频率补偿值:-10ppm
- 即使失去主时钟,仍可以应用这个补偿
- 误差累积速度大大降低
场景二:减少同步报文频率
如果从时钟的频率已经同步到主时钟:
- 频率偏差接近0
- 相位偏差累积很慢
- 可以减少Sync报文频率
好处:
- 降低网络负载
- 降低CPU负载
- 仍能保持精度
场景三:长期稳定
相位调整只能暂时对齐时钟。
如果没有频率同步:
- 每隔几秒就要调整一次
- 时钟不断跳变
- 系统不稳定
有了频率同步:
- 相位偏差累积很慢
- 调整频率降低
- 系统长期稳定
PTP中的频率同步机制
方法一:从相位偏差推导频率偏差
原理:通过多次测量相位偏差,计算变化率。
公式:
频率偏差 ≈ (offsetₙ - offsetₙ₋₁) / (Tₙ - Tₙ₋₁)
示例:
T₁ = 1000秒,offset₁ = +100ns
T₂ = 1001秒,offset₂ = +110ns
频率偏差 = (110ns - 100ns) / (1001秒 - 1000秒)
= 10ns/秒
= 10ppb
实现:
从时钟持续测量offsetFromMaster,使用滑动窗口平均或低通滤波,提取频率偏差。
优点:
- 不需要额外报文
- 实现简单
缺点:
- 需要多次测量,收敛慢
- 受网络抖动影响
方法二:直接频率测量
原理:直接比较主时钟和从时钟的频率。
Sync报文携带的信息:
- originTimestamp:Sync报文的发送时间
- correctionField:各种校正值
从时钟的处理:
- 接收Sync报文,记录接收时间t2
- 计算校正后的主时钟发送时间:
correctedMasterTime = originTimestamp + correctionField + meanDelay - 记录两次Sync的correctedMasterTime和本地时间
- 计算频率比:
frequencyRatio = (本地时间间隔) / (主时钟时间间隔)
示例:
Sync 1:
- 本地接收时间:t₂₁ = 1000.000000100秒
- 主时钟发送时间(校正后):T₁ = 1000.000000000秒
Sync 2:
- 本地接收时间:t₂₂ = 1001.000000110秒
- 主时钟发送时间(校正后):T₂ = 1001.000000000秒
本地时间间隔 = t₂₂ - t₂₁ = 1.000000010秒
主时钟时间间隔 = T₂ - T₁ = 1.000000000秒
频率比 = 1.000000010 / 1.000000000 = 1.000000010
频率偏差 = 频率比 - 1 = 10ppb
优点:
- 精度高
- 收敛快
缺点:
- 需要准确的meanDelay测量
频率补偿:调整时钟速度
知道了频率偏差,如何调整?
基本方法
目标:让从时钟的走时速度与主时钟一致。
公式:
调整后的时钟速度 = 原时钟速度 × (1 - 频率偏差)
示例:
频率偏差 = +10 ppm(从时钟快了)
调整后的时钟速度 = 原速度 × (1 - 0.00001) = 原速度 × 0.99999
让时钟走得慢一点,与主时钟同步。
软件实现
方法:维护一个频率补偿值,每次读取本地时钟时应用。
double frequency_adjustment = 1.0 - frequency_offset;
Timestamp get_adjusted_time() {
Timestamp raw_time = read_hardware_counter();
return raw_time * frequency_adjustment + phase_offset;
}
硬件实现
方法一:数控振荡器(NCO)
使用数字控制的方式调整振荡器频率。
NCO输出频率 = 参考频率 × (控制字 / 2^N)
精度:
对于32位NCO,频率调整粒度约为:
粒度 = 125 MHz / 2^32 ≈ 0.03 Hz ≈ 0.24 ppb
方法二:锁相环(PLL)
如果主时钟提供1PPS信号,从时钟可以用PLL锁定这个信号,实现频率同步。
渐进调整:通过频率调整消除相位偏差
上一节提到,阶跃调整(直接修改时钟值)会导致时间跳变或倒退。
有没有更平滑的方式?
渐进调整(Slew Adjustment):不直接跳变,而是通过调整时钟速度,逐渐消除相位偏差。
原理
假设offsetFromMaster = -1毫秒(从时钟慢了1毫秒)。
不是直接加1毫秒,而是:
- 在一段时间内(比如1秒)
- 让本地时钟走得稍快一点
- 逐渐“追上“主时钟
数学描述:
调整期间,时钟速度 = 正常速度 × (1 - offsetFromMaster / 调整时间)
示例:
offsetFromMaster = -1毫秒
调整时间 = 1秒
时钟速度调整 = -1毫秒 / 1秒 = -1000ppm
在1秒内,时钟以比正常快1000ppm的速度运行:
- 正常应该走:1秒
- 实际走了:1秒 × (1 + 0.001) = 1.001秒
- 相当于"追回"了1毫秒
1秒后,相位偏差消除,时钟恢复正常速度
与频率补偿的区别
| 特性 | 渐进调整 | 频率补偿 |
|---|---|---|
| 目的 | 消除相位偏差 | 消除频率偏差 |
| 持续时间 | 临时(调整完成后恢复) | 持续(长期应用) |
| 调整幅度 | 较大(可达数千ppm) | 较小(通常数十ppm) |
| 触发条件 | 相位偏差超过阈值 | 频率偏差被测量出来 |
优点
- 时间连续,不跳变,不倒退
- 应用层无感知
- 比阶跃调整更平滑
缺点
- 调整期间时钟精度降低
- 需要更长时间完成调整
- 调整幅度有限(不能太大,否则时钟精度太差)
时钟伺服:动态调整的控制
什么是时钟伺服?
伺服(Servo):一种自动控制系统,通过反馈不断调整输出,使其跟踪目标值。
时钟伺服:一种控制系统,动态调整本地时钟的相位和频率,使其跟踪主时钟。
为什么需要伺服?
相位偏差和频率偏差会不断变化:
- 网络延迟抖动影响相位测量
- 温度变化影响晶振频率
- 其他环境因素
静态的调整值无法应对这些变化。需要动态调整。
伺服的基本结构
┌─────────────┐
主时钟 ----->│ 比较器 │<------ 本地时钟
时间 │ │
│ 计算误差 │
│ (offset) │
└──────┬──────┘
│
▼
┌─────────────┐
│ 控制器 │
│ (PI) │
└──────┬──────┘
│
▼
┌─────────────┐
│ 执行器 │
│ (调整时钟) │
└──────┬──────┘
│
└──────────> 相位调整 + 频率调整
PI控制器
PTP时钟伺服通常使用PI控制器(比例-积分控制器)。
公式:
控制输出 = Kp × offset + Ki × ∫offset dt
其中:
- Kp:比例增益
- Ki:积分增益
- offset:当前的相位偏差
- ∫offset dt:相位偏差的积分(累积误差)
比例项(P项):
Kp × offset
- 响应当前的相位偏差
- 产生相位调整(消除当前偏差)
积分项(I项):
Ki × ∫offset dt
- 响应累积的相位偏差
- 产生频率调整(消除长期累积)
为什么积分项对应频率调整?
积分项是相位偏差的累积:
∫offset dt ≈ 频率偏差 × 时间
频率偏差越大,累积越快。积分项响应这个累积,调整时钟速度。
所以:
- P项 → 相位调整(解决“现在“)
- I项 → 频率调整(解决“未来“)
为什么不用D项?
PID控制器还有微分项(D项):
Kd × d(offset)/dt
但PTP时钟伺服通常不使用D项,原因:
- offset本身有噪声:测量误差、网络抖动等
- 微分项会放大噪声:导致控制输出不稳定
PI参数调节
PI参数的选择是伺服设计的关键。
参数太激进(Kp、Ki大):
- 响应快
- 但容易振荡、不稳定
参数太保守(Kp、Ki小):
- 稳定
- 但响应慢、收敛时间长
经验法则:
| 网络特性 | Kp | Ki | 说明 |
|---|---|---|---|
| 稳定网络(抖动小) | 大 | 大 | 可以激进调整 |
| 不稳定网络(抖动大) | 小 | 小 | 需要保守调整 |
一个完整的频率同步示例
场景
- 主时钟频率:精确的125 MHz
- 从时钟本地晶振:标称125 MHz,实际125.00125 MHz(+10ppm误差)
- Sync报文间隔:1秒
初始阶段
第1个Sync:
- 主时钟发送时间:T₁ = 0秒
- 从时钟接收时间:t₂₁ = 0秒(假设初始相位对齐)
第2个Sync:
- 主时钟发送时间:T₂ = 1秒
- 从时钟接收时间:t₂₂ = 1.00001秒(晶振快了10ppm)
测量相位偏差:
offset = 1.00001 - 1 = 10微秒
计算频率偏差:
频率偏差 = offset / 时间间隔 = 10微秒 / 1秒 = 10ppm
应用频率补偿
PI控制输出:
- P项:产生相位调整(可能使用渐进调整消除10微秒偏差)
- I项:产生频率调整 = -10ppm
应用频率补偿后:
调整后的时钟速度 = 原速度 × (1 - 0.00001) = 原速度 × 0.99999
第3个Sync:
主时钟经过1秒,从时钟原始时间经过1.00001秒。
调整后:
从时钟时间 = 1.00001 × 0.99999 = 1.00000秒
与主时钟一致!频率同步成功。
稳态阶段
第10个Sync:
- offset ≈ 0
- 频率偏差 ≈ 0
- PI控制输出 ≈ 0
时钟保持稳定。
假设温度变化,晶振频率漂移到+11ppm:
- offset开始累积
- PI控制检测到变化
- 调整频率补偿值
持续动态调整,保持长期同步。
小结:频率同步的核心要点
频率偏差:
- 时钟走时速度的差异
- 是相位偏差累积的原因
为什么重要:
- 保持长期稳定
- 支持保持模式
- 减少同步报文频率
频率测量方法:
- 从相位偏差推导
- 直接频率测量
频率补偿:
- 软件:数学调整
- 硬件:NCO、PLL
渐进调整:
- 通过频率调整消除相位偏差
- 平滑,不跳变
时钟伺服:
- PI控制器动态调整
- P项 → 相位调整
- I项 → 频率调整
下集预告
频率同步和相位同步,都依赖于一个关键前提:时间戳精确。
下一节,我们将深入讲解硬件时间戳——PTP纳秒级精度的真正来源。
【悬念留给2.11】
你可能好奇:软件时间戳和硬件时间戳,精度差多少?
答案是:差1000倍以上。
- 软件时间戳精度:微秒级(受中断延迟、调度延迟影响)
- 硬件时间戳精度:纳秒级(直接在PHY层记录)
这个差距,决定了PTP能否达到纳秒级同步。
下一节,我们详细解读。