Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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:各种校正值

从时钟的处理

  1. 接收Sync报文,记录接收时间t2
  2. 计算校正后的主时钟发送时间:
    correctedMasterTime = originTimestamp + correctionField + meanDelay
    
  3. 记录两次Sync的correctedMasterTime和本地时间
  4. 计算频率比:
    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项,原因:

  1. offset本身有噪声:测量误差、网络抖动等
  2. 微分项会放大噪声:导致控制输出不稳定

PI参数调节

PI参数的选择是伺服设计的关键。

参数太激进(Kp、Ki大)

  • 响应快
  • 但容易振荡、不稳定

参数太保守(Kp、Ki小)

  • 稳定
  • 但响应慢、收敛时间长

经验法则

网络特性KpKi说明
稳定网络(抖动小)可以激进调整
不稳定网络(抖动大)需要保守调整

一个完整的频率同步示例

场景

  • 主时钟频率:精确的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能否达到纳秒级同步。

下一节,我们详细解读。