引言
PTPD 是一款开源的时间同步软件,其性能表现受操作系统的不同而有所变化。本文专注于在 QNX 操作系统上执行 PTPD,评估其时间同步精度,并探究影响精度的因素,以期改善时间同步效果。
更多详情请参考:QNX 系统中运行 PTPD 实现 gPTP 同步的问题及解决方案。
关键函数实现
在 QNX 上使用 PTPD 实现时间同步时,PTP4L 被配置为主时钟,PTPD2 作为从时钟。原生 PTPD 使用 SO_TIMESTAMP 方法从网络栈获取时间戳,这导致了每次更新时间的最大延迟为8毫秒,增加了时间同步的不确定性。为了解决这个问题,我们修改了代码,使应用程序直接读取系统时间来标记事件报文的时间戳。
关键代码片段如下:
void getTime(TimeInternal *time) {
struct timespec tp_now;
if (clock_gettime(CLOCK_REALTIME, &tp_now)) {
perror("Error in clock_gettime");
exit(EXIT_FAILURE);
}
time->seconds = tp_now.tv_sec;
time->nanoseconds = tp_now.tv_nsec;
}
验证策略与结果
我们采用了 clockdiff
工具来评估改进后的时间同步效果,结果显示主从时钟间的时间偏差通常在几十至几百微秒范围内,不超过1毫秒。这证明了改进措施显著提升了时间同步的精确度。
此外,我们还编写了一个简单的工具 so_timestamp.c
来观察 SO_TIMESTAMP 的行为模式,发现时间戳在一段时间内固定不变,每隔8毫秒左右跳跃一次,这与之前的误差现象相吻合。
图注:clockdiff
测得的时间同步误差分布
授时误差分析与解决
在测试过程中,我们注意到即使在最佳条件下,最小的时间同步误差也达到了10毫秒。深入研究发现,QNX 内核中 SO_TIMESTAMPING 的8毫秒更新间隔是造成这一问题的主要因素之一。此外,时钟频率调节机制未能及时响应,导致时间戳长时间不变,进而引发较大的时钟跳变。
针对上述问题,我们利用 QNX 提供的 ClockAdjust
函数对时钟进行动态调整,通过编程方式修正时钟频率,以减少时间同步误差。示例代码如下:
if (ClockAdjust(CLOCK_REALTIME, &clockadj, nullptr) == -1) {
fprintf(stderr, "Failed to adjust clock: %s\n", strerror(errno));
}
结论
综合比较 QNX 和 Linux 平台上的 PTPD 表现,可以确定 QNX 在时钟频率调整方面存在限制,这是影响时间同步精度的重要因素。尽管如此,通过适当的软件调整和可能的硬件支持,仍然可以在 QNX 系统上达到理想的授时精度。