PTP(Precision Time Protocol) はNTPに似た方法でより精度の高い時刻同期を提供するしくみで、IEEE 1588で標準化されています。仕様上100ns未満の精度で、Linuxシステムでmsecオーダーの精度を提供します。
通信プロトコルはEtherNet layer 2で定義されており、ネットワークインターフェースによるハードウェアタイムスタンプのサポートが定義されています。ハードウェアタイムスタンプは精度の向上とマイコンのCPUリソースの低減に寄与します。
PTPはNTPほど有名ではありませんが、LANでより精度の高い時刻同期が必要とされる場合は有用です。
Linux環境における設定や動作確認の方法について以下に説明します。
ethtoolの-Tオプションによって確認できます。
# ethtool -T eth0 Time stamping parameters for eth0: Capabilities: hardware-transmit (SOF_TIMESTAMPING_TX_HARDWARE) software-transmit (SOF_TIMESTAMPING_TX_SOFTWARE) hardware-receive (SOF_TIMESTAMPING_RX_HARDWARE) software-receive (SOF_TIMESTAMPING_RX_SOFTWARE) software-system-clock (SOF_TIMESTAMPING_SOFTWARE) hardware-raw-clock (SOF_TIMESTAMPING_RAW_HARDWARE) PTP Hardware Clock: 0 Hardware Transmit Timestamp Modes: off (HWTSTAMP_TX_OFF) on (HWTSTAMP_TX_ON) Hardware Receive Filter Modes: none (HWTSTAMP_FILTER_NONE) ptpv1-l4-event (HWTSTAMP_FILTER_PTP_V1_L4_EVENT) ptpv2-event (HWTSTAMP_FILTER_PTP_V2_EVENT)
ソフトウエアタイムスタンプを使用するには、下記のパラメータが表示されている必要があります。
SOF_TIMESTAMPING_SOFTWARE
SOF_TIMESTAMPING_TX_SOFTWARE
SOF_TIMESTAMPING_RX_SOFTWARE
ハードウエアタイムスタンプを使用するには、下記のパラメータが表示されている必要があります。
SOF_TIMESTAMPING_RAW_HARDWARE
SOF_TIMESTAMPING_TX_HARDWARE
SOF_TIMESTAMPING_RX_HARDWARE
アプリケーションでハードウェアタイムスタンプを取得するにはSO_TIMESTAMPINGソケットオプションを使用します。
ptp-event(UDP 319), ptp-general(UDP 320)でマスターからマルチキャストパケットが一秒おきに送出される。
スレーブからはptp-eventが1秒おきに送出される。
Firewall等の設定ではこれらのポートへの通信は許可しておく必要があります。
必要に応じて、unicastによる通信を選択することも可能となっています。
ptpdとlinuxptpの2つの代表的な実装があるので、それぞれについて説明します。
ubuntuやdebianなどのディストリビューションで採用されている実装です。
現時点(2020/8/31現在)のバージョン2.3.1はハードウェアタイムスタンプに対応していません。
debianでは/etc/default/ptpdに設定ファイルが置かれています。ここで、コマンドラインオプションの設定を行います。systemdには対応していないようです。
設定の詳細については割愛しますが、この例ではバインドするNICの指定と、master/slaveの指定を行っています。
# /etc/default/ptpd # Set to "yes" to actually start ptpd automatically START_DAEMON=yes # Add command line options for ptpd PTPD_OPTS="-i eth0 -s"
# ptpd -i eth0 -s -C -D Runtime debug not enabled. Please compile with RUNTIME_DEBUG 2020-08-31 01:00:07.316787 ptpd2[18637].startup (info) (___) Configuration OK 2020-08-31 01:00:07.327169 ptpd2[18637].startup (info) (___) Successfully acquired lock on /var/run/ptpd2.lock 2020-08-31 01:00:07.330414 ptpd2[18637].startup (notice) (___) PTPDv2 started successfully on eth0 using "slaveonly" preset (PID 18637) 2020-08-31 01:00:07.332890 ptpd2[18637].startup (info) (___) TimingService.PTP0: PTP service init 2020-08-31 01:00:07.339212 ptpd2[18637].eth0 (info) (init) Observed_drift loaded from kernel: 40182 ppb 2020-08-31 01:00:07.442412 ptpd2[18637].eth0 (notice) (lstn_init) Now in state: PTP_LISTENING 2020-08-31 01:00:08.809053 ptpd2[18637].eth0 (info) (lstn_init) New best master selected: dca632fffe729385(unknown)/1 2020-08-31 01:00:08.813397 ptpd2[18637].eth0 (notice) (slv) Now in state: PTP_SLAVE, Best master: dca632fffe729385(unknown)/1 (IPv4:192.168.10.193) 2020-08-31 01:00:09.804580 ptpd2[18637].eth0 (notice) (slv) Received first Sync from Master 2020-08-31 01:00:09.806791 ptpd2[18637].eth0 (critical) (slv) Offset above 1 second. Clock will step. 2020-08-31 14:36:41.914507 ptpd2[18637].eth0 (warning) (slv) Stepped the system clock to: 08/31/20 14:36:41.905679118 2020-08-31 14:36:42.021871 ptpd2[18637].eth0 (notice) (lstn_reset) Now in state: PTP_LISTENING 2020-08-31 14:36:42.905186 ptpd2[18637].eth0 (info) (lstn_reset) New best master selected: dca632fffe729385(unknown)/1 2020-08-31 14:36:42.909169 ptpd2[18637].eth0 (notice) (slv) Now in state: PTP_SLAVE, Best master: dca632fffe729385(unknown)/1 (IPv4:192.168.10.193) 2020-08-31 14:36:43.900990 ptpd2[18637].eth0 (notice) (slv) Received first Sync from Master 2020-08-31 14:36:44.905415 ptpd2[18637].eth0 (notice) (slv) Received first Delay Response from Master 2020-08-31 14:36:49.432288 ptpd2[18637].eth0 (notice) (slv) TimingService.PTP0: elected best TimingService 2020-08-31 14:36:49.432591 ptpd2[18637].eth0 (info) (slv) TimingService.PTP0: acquired clock control
(slv) Now in state: PTP_SLAVE, Best master: dca632fffe729385(unknown)/1 (IPv4:192.168.10.193)
masterが見つかり、自身がslaveとして構成された旨のログ。
この時出力されるmasterのIDの4-5オクテットを除く部分(例だとdca632729385)はmasterのMACアドレスになっている。
時刻が大きくずれているとき、step modeで調整が入る。この時次のメッセージが出る。
(slv) Offset above 1 second. Clock will step.
ptpdは特に動作確認を行うツールは用意されていないので、必要に応じ、デバッグレベルを上げるなどしてトラブルシュートする必要があります。
linuxptpパッケージは、ptp4l, phc2sys という2つのプログラムで構成されています。
ptp4l は boundary clock の機能と ordinary clock の両方の機能を提供しています。ハードウエア側にタイムスタンプ機能が用意されていれば、 ptp4lはデフォルトでハードウェアタイムスタンプを使用します。
phc2sys はシステムクロックをPTP時刻に同期させるために使用します。
デフォルトではコンフィグファイルはありません。systemdでは、/etc/systemd/system/multi-user.target.wants/ptp4l.service
で次のように設定されていると思うので、ここでコマンドラインオプションを指定するか設定ファイルを変更します。
ExecStart=/usr/sbin/ptp4l -f /etc/linuxptp/ptp4l.conf -i eth0
基本的に変更の必要はありませんが、必要ならmaster/slaveを明示的に指定します。
また、ログをかなり頻繁に出力するので、summary_interval=10などを指定する事を推奨します。(2のべき乗[sec]で指定)
ハードウェアがサポートしていれば、ハードウェアタイムスタンプが利用されます。
# ptp4l -i eth0 -m -s ptp4l[52620.241]: selected /dev/ptp0 as PTP clock ptp4l[52620.249]: port 1: INITIALIZING to LISTENING on INIT_COMPLETE ptp4l[52620.254]: port 0: INITIALIZING to LISTENING on INIT_COMPLETE ptp4l[52620.296]: port 1: new foreign master dca632.fffe.729385-1 ptp4l[52624.293]: selected best master clock dca632.fffe.729385 ptp4l[52624.293]: foreign master not using PTP timescale ptp4l[52624.293]: running in a temporal vortex ptp4l[52624.294]: port 1: LISTENING to UNCALIBRATED on RS_SLAVE ptp4l[52626.293]: master offset 73201 s0 freq +49258 path delay 42084 ptp4l[52627.293]: master offset 87920 s1 freq +63978 path delay 42084 ptp4l[52628.293]: master offset -19782 s2 freq +44196 path delay 42084 ptp4l[52628.293]: port 1: UNCALIBRATED to SLAVE on MASTER_CLOCK_SELECTED ptp4l[52629.293]: master offset 212 s2 freq +58255 path delay 38436 ptp4l[52630.293]: master offset -13903 s2 freq +44204 path delay 42084
master offset 以下には、マスターとの時刻差[nsec]が表示されます。
s0 , s1 , s2 の各表示は、クロックサーボの状態を表わしています。それぞれ s0 はロック解除状態を、 s1 はクロックステップを、 s2 はロック済み状態を表わしています。サーボがロック済みの状態 ( s2 ) にある場合、 pi_offset_const オプションが負の値に設定されていると、クロックをステップさせる (大きく変更する) ことは行なわず、徐々に調整するslew modeになります。
freq で示されている値は、クロックの周波数調整値 (単位はppbで、10億あたりの値)を表わしています。
path delay には、マスターから送信された同期メッセージの見積もり遅延時間[nsec]を表わしています。
PTP のマスタークロックと同期が成功すると、クロックサーボのステータスがs2となり、次のメッセージが出力されます。
ptp4l[52628.293]: port 1: UNCALIBRATED to SLAVE on MASTER_CLOCK_SELECTED
ptp4lを動作させただけでは、システムクロックが同期されることはありません。この為にはphc2sysの設定が必要となります。
システムクロックのソースとしては、ptp4lのソフトウェアタイムスタンプ、NICのハードウェアタイムスタンプを選択できます。
自ホストに精度の高いクロック源が接続されている場合、クロックソースを指定することもできます。
phc2sysはログを頻繁に出力するので-u 1000などを設定することを推奨します。
典型的な設定パターンを以下に示します。
# phc2sys -a -r -m phc2sys[97961.628]: reconfiguring after port state change phc2sys[97961.635]: selecting CLOCK_REALTIME for synchronization phc2sys[97961.637]: selecting eth0 as the master clock phc2sys[97961.638]: CLOCK_REALTIME phc offset -51684648605282 s0 freq -100000000 delay 2109 phc2sys[97962.650]: CLOCK_REALTIME phc offset -51684556618893 s1 freq +51714 delay 2154 phc2sys[97963.650]: CLOCK_REALTIME phc offset 15175 s2 freq +66889 delay 1916
クロックサーボのステータスはptp4lと同じです。
例のように、時刻が大きくずれている場合、起動時にstep modeでの調整が行われます。
ptp4lのマネージメントを行うプログラムとしてpmcコマンドが提供されています。これを用いて状態を確認することができます。
# pmc -u -b0 'GET CURRENT_DATA_SET' sending: GET CURRENT_DATA_SET 0479b7.fffe.b16674-0 seq 0 RESPONSE MANAGEMENT CURRENT_DATA_SET stepsRemoved 1 offsetFromMaster 3538.0 meanPathDelay 42642.0 # pmc -u -b0 'GET TIME_STATUS_NP' sending: GET TIME_STATUS_NP 0479b7.fffe.b16674-0 seq 0 RESPONSE MANAGEMENT TIME_STATUS_NP master_offset -4931 ingress_time 1598813396899250986 cumulativeScaledRateOffset +0.000000000 scaledLastGmPhaseChange 0 gmTimeBaseIndicator 0 lastGmPhaseChange 0x0000'0000000000000000.0000 gmPresent true gmIdentity dca632.fffe.729385