シリアル通信プロトコルを介して別の「マスター」デバイスと接続する組み込み Linux デバイスがあります。後でスレーブが正確なタイムスタンプを付ける必要がある情報をマスターに返すため、マスターは定期的にその日付をスレーブ デバイスに渡します。ただし、Linux の「date」コマンドは、システムの日付を 1 秒以内の精度でしか設定しません。これは私たちの用途には十分ではありません。
Linux マシンの時間を 1 秒より正確に設定する方法を知っている人はいますか?
シリアル通信プロトコルを介して別の「マスター」デバイスと接続する組み込み Linux デバイスがあります。後でスレーブが正確なタイムスタンプを付ける必要がある情報をマスターに返すため、マスターは定期的にその日付をスレーブ デバイスに渡します。ただし、Linux の「date」コマンドは、システムの日付を 1 秒以内の精度でしか設定しません。これは私たちの用途には十分ではありません。
Linux マシンの時間を 1 秒より正確に設定する方法を知っている人はいますか?
他の回答で与えられたsettimeofday(2)
方法には深刻な問題があります。それはあなたが望むことを正確に行います。:)
システムの時刻を瞬時に直接変更することの問題は、調整が負の場合、変更の前後の時刻を取得するプログラムを混乱させる可能性があることです。つまり、彼らは時間を逆行することを知覚することができます。
これに対する修正は、adjtime(3)
どちらがシンプルで移植可能か、またはadjtimex(2)
どちらが複雑で強力で Linux 固有のものかです。これらの呼び出しは両方とも、洗練されたアルゴリズムを使用して、目的の変更が達成されるまで、一定期間にわたってゆっくりとシステム時間を順方向に調整します。
ところで、本当に車輪の再発明をしているわけではないのですか? Julien Ridoux と Darryl Veitch の ACM Queue 論文Principles of Robust Timing over the Internetを読むことをお勧めします。あなたは組み込みシステムに取り組んでいるので、図 5 のリンギングに寒気がするはずです。「減衰発振器」と言えますか?adjtime()
この問題のあるアルゴリズムをadjtimex()
使用するため、ある意味で上記の私自身のアドバイスに反論していますが、Mills アルゴリズムはステップ調整の非アルゴリズムよりも優れています。代わりに 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様 お世話になります。