我有一个嵌入式Linux设备,它通过串行通信协议与另一个"主"设备接口。主设备定期将其日期传递给从设备,因为稍后从设备将向主设备返回需要准确时间戳的信息。但是,Linux "date"命令仅将系统日期设置为秒内精度。这对于我们的用途来说还不够。
有谁知道如何将 Linux 机器的时间设置得比 1 秒更精确?
其他答案中给出的settimeofday(2)
方法有一个严重的问题:它完全按照你所说的去做。 :)
系统时间的问题在于,如果调整为负数,则可能会混淆在更改之前和之后获取一天中时间的程序。也就是说,他们可以感知时间倒流。
对此的修复方法是adjtime(3)
简单且可移植的,或者adjtimex(2)
复杂,强大且特定于Linux的修复程序。这两个调用都使用复杂的算法在一段时间内缓慢调整系统时间,仅向前调整,直到实现所需的更改。
顺便问一下,你确定你不是在这里重新发明轮子吗?我建议您阅读Julien Ridoux和Darryl Veitch的ACM Queue论文 互联网上的鲁棒计时原理。您正在开发嵌入式系统,因此我希望图 5 中的振铃会让您不寒而栗。你能说"阻尼振荡器"吗? adjtime()
和adjtimex()
使用这种麻烦的算法,所以从某种意义上说,我反对我自己上面的建议,但米尔斯算法仍然比步进调整非算法更好。如果您选择实现RADclock,那就更好了。
settimeofday()
系统调用采用并使用微秒精度。 你必须写一个简短的程序才能使用它,但这很简单。
struct timeval tv;
tv .tv_sec = (some time_t value)
tv .tv_usec = (the number of microseconds after the second)
int rc = settimeofday (&tv, NULL);
if (rc)
errormessage ("error %d setting system time", errno);
-
您可以使用
settimeofday(2)
系统调用;该接口支持微秒级分辨率。#include <sys/time.h> int gettimeofday(struct timeval *tv, struct timezone *tz); int settimeofday(const struct timeval *tv, const struct timezone *tz); struct timeval { time_t tv_sec; /* seconds */ suseconds_t tv_usec; /* microseconds */ };
-
您可以使用
clock_settime(2)
系统调用;接口提供多个时钟,接口支持纳秒级分辨率。#include <time.h> int clock_getres(clockid_t clk_id, struct timespec *res); int clock_gettime(clockid_t clk_id, struct timespec *tp); int clock_settime(clockid_t clk_id, const struct timespec *tp); struct timespec { time_t tv_sec; /* seconds */ long tv_nsec; /* nanoseconds */ }; CLOCK_REALTIME System-wide real-time clock. Setting this clock requires appropriate privileges. CLOCK_MONOTONIC Clock that cannot be set and represents monotonic time since some unspecified starting point. CLOCK_MONOTONIC_RAW (since Linux 2.6.28; Linux-specific) Similar to CLOCK_MONOTONIC, but provides access to a raw hardware-based time that is not subject to NTP adjustments. CLOCK_PROCESS_CPUTIME_ID High-resolution per-process timer from the CPU. CLOCK_THREAD_CPUTIME_ID Thread-specific CPU-time clock.
此接口提供了
clock_getres(2)
调用的细节,它可以准确地告诉您分辨率是什么 - 仅仅因为接口接受纳秒并不意味着它实际上可以支持纳秒分辨率。(我有一个模糊的内存,20 ns大约是许多系统的极限,但没有参考资料支持这一点。
如果您通过串行链路运行支持 IP 的网络协议(例如,哦,PPP),您只需在"主"主机上运行 ntpd,然后在嵌入式设备上使用 ntpd 或 ntpdate 同步时间。 NTP会照顾你。