详尽回答问题:
NTP 如何仅根据从服务器接收到的数据包实现 FLL/PLL 混合时钟规则?
需要 90 页的文档:Network Time Protocol Version 4, Reference and Implementation Guide。我将尝试在这里总结一个答案。
简而言之,NTP 客户端从一个或多个服务器接收时间戳并估计要应用的相位校正。然后逐渐应用校正以避免时钟跳跃。
PLL 或 FLL 都可以使用,但是文档说
当网络抖动占主导地位时,PLL 通常工作得更好,而
当振荡器漂移占主导地位时,FLL 工作得更好。
与NTPv3相反,在NTPv4中,PLL和FLL同时使用并结合使用。
反馈控制系统
时钟规则被实现为如图 1 所示的反馈控制系统。
图 1:时钟规则反馈循环
theta_r 表示组合算法生成的参考相位,表示系统时钟偏移相对于一组服务器的最佳估计。
theta_c 表示模拟为可变频率振荡器 (VFO) 的系统时钟的控制相位。
V_d是相位差theta_r - theta_c
V_s是选择最佳偏移样本的时钟滤波器算法的输出。
V_c是环路滤波器产生的信号,它结合了PLL和FLL,如第二张图所示。
图 2:时钟规则循环过滤器
=== 更新 ===
要了解相位偏移和频率偏移计算的详细信息,您必须深入了解参考实现。一个好的起点是packet() 函数
/*
* packet() - process packet and compute offset, delay and
* dispersion.
*/
在广播服务器模式下,计算如下
offset = LFP2D(r->xmt - r->dst);
delay = BDELAY;
disp = LOG2D(r->precision) + LOG2D(s.precision) + PHI * 2 * BDELAY;
其中r 是接收到的数据包指针,s 是系统结构。
然后调用clock_filter函数
/*
* The clock filter contents consist of eight tuples (offset,
* delay, dispersion, time). Shift each tuple to the left,
* discarding the leftmost one. As each tuple is shifted,
* increase the dispersion since the last filter update. At the
* same time, copy each tuple to a temporary list. After this,
* place the (offset, delay, disp, time) in the vacated
* rightmost tuple.
*/
clock_filter 本身会调用clock_select 函数,并且只有在此之后才会调用clock_update 函数。
需要记住的重要一点是,这些算法与多个时钟同步,而不是仅与一个服务器时钟同步。这引入了一层复杂性,如何与一个服务器同步?这个问题没有直接的答案,因为算法是为与多个时钟同步而构建的。
SNTP 协议(Simple NTP)仅使用一个服务器时钟,但没有官方参考实现。