少しディープなところにダイブする(バスタブ レベルだが)。一般的なNICカードでサポートされているPTPハードウェアタイムスタンプが具体的に何をしてくれるのか、いまひとつ把握できていなかった。ここでは、特に、タイムスタンプ送信に関する実装について調べる。なお、PTPの原理そのものは、ここでは追わない。
概要
Precision Time Protocol (PTP) は、隣接ノード間(距離には依存しない)でマイクロ秒オーダの誤差範囲で時刻同期するプロトコル。PCで普通に実施できるNetwork Time Protocolより精度が高く、スマホ基地局間タイミング同期、ロボットアーム同期、オーディオスピーカ同期等で適用される。10年前ならホットな技術だったかもしれないが、今は成熟し枯れている様子。LinuxでのPTPデーモンは2種類あり、主要ディストリビューションでは両方のパッケージがある。なお、OSの上でPTP時刻同期を実施しても、精度面での効果は無く、従来のNTPで十分である。
パッケージ名 |
デーモン名 |
Hard Time Stamp |
linuxptp |
ptp4l |
対応有り |
ptpd, ptpd2 |
ptpd, ptpd2 |
対応無し |
ptp4lの「4l」は「for Linux」の略。
PTPの伝送レイヤも2種類ある。業界毎にプロファイルがあり、サポート範囲が異なる。原則はマルチキャストだが、UDPはユニキャストでも対応できる様子。
調査H/W
INTEL 82574Lを搭載したPCIe NICカード とする。デバイスがどこまで対応しているかは、ethtool -Tコマンドで確認できる。但し、ここでの表示はあらかじめソースに埋め込まれた内容を表示しているにすぎず、レジスタアクセス等は無い様子。
driver: e1000e
version: 3.2.6-k
firmware-version: 1.8-0
Time stamping parameters for enp1s0:
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: 1
Hardware Transmit Timestamp Modes:
off (HWTSTAMP_TX_OFF)
on (HWTSTAMP_TX_ON)
Hardware Receive Filter Modes:
none (HWTSTAMP_FILTER_NONE)
all (HWTSTAMP_FILTER_ALL)
ptpv1-l4-sync (HWTSTAMP_FILTER_PTP_V1_L4_SYNC)
ptpv1-l4-delay-req (HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ)
ptpv2-l4-sync (HWTSTAMP_FILTER_PTP_V2_L4_SYNC)
ptpv2-l4-delay-req (HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ)
ptpv2-l2-sync (HWTSTAMP_FILTER_PTP_V2_L2_SYNC)
ptpv2-l2-delay-req (HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ)
ptpv2-event (HWTSTAMP_FILTER_PTP_V2_EVENT)
ptpv2-sync (HWTSTAMP_FILTER_PTP_V2_SYNC)
ptpv2-delay-req (HWTSTAMP_FILTER_PTP_V2_DELAY_REQ)
データシートの内容
82574Lのデータシート 7.7.2項や7.7.3.2項によれば、送信ディスクリプタExtCMD bit0(TimeStamp)をセットすると、PTPフィールドにタイムスタンプが刻印されると解釈できる。82574LにはPTPクロック専用のH/Wカウンタが内蔵されており、phc_ctl コマンドによって、OS時間やRTCとは別の時刻が刻まれている様子を確認できる。phc_ctlはlinuxptpのS/Wパッケージに含まれている。
~# echo "OS TIME:"; date; echo "RTC TIME:"; hwclock; echo "PTP TIME:"; phc_ctl eth0 get
OS TIME:
2019年 6月 20日 木曜日 21:45:03 JST
RTC TIME:
2019-06-20 21:45:36.827508+0900
PTP TIME:
phc_ctl[3345.712]: clock time is 1561034696.559877320 or Thu Jun 20 21:44:56 2019
82574Lよりも新しいI350では、PTPに関連付けたGPIO/SDPピン出力を定義できる。この信号上のタイミングに基づくエッジでのデバイス制御が王道の使い方だろう。
ここに、送信ディスクリプタ ExtCMD bit0(E1000_TXD_EXTCMD_TSTAMP)をセットするLinuxデバイスドライバのソース実体がある。ptp4lを使った場合、/etc/linuxptp/ptp4l.confにおけるtime_stampingの設定が「hardware」ならばこのビットがセットされ、「software」ならセットされないことを確認した。
つまり、S/WはPTP送信フレームを生成するが、ディスクリプタにマークすれば、あとはH/Wが内蔵64bitカウンタを元によろしくやってくれるという感じである。
なお、インテルのNIC/Ethernetコントローラを本格的なPTPシステムに含める場合、ドライバS/Wをメーカのホームページから入手し更新するべきである。
現時点のまとめ・解釈
他のオフロード機能と同様、PTPについてもNIC(またはEthernetコントローラ)がフレームの上位機能に介入する。フレームはS/Wが作るが、NICは勝手に判断して正確なタイムスタンプを付与する。その時、UDPの内部が変わるので、当然、UDPチェックサムも(再)生成/付与される。
試しに82574L搭載のUbuntuマシンで「sudo apt install linuxptp」を実行したら、何の設定も無しに1秒に2〜3フレームのPTPをマルチキャストし始めた。このPTP時刻精度を評価するには、高精度なマスタークロック源に同期した上で、専門の測定機材での評価が必要。
備考1
linuxptpをインストールすると、phc2sys (ptp hardware clock to the system)もインストールされる。実運用では、これの使い方、要否についても把握しておく必要がある。たいていは不要と判断できる。
備考2: ptp4lの設定
ptp4lデーモンが起動しない場合、下記ファイルをチェックする。
/etc/linuxptp/ptp4l.conf ## time_stamping を software にすることも可
/lib/systemd/system/ptp4l.service ## -i でPTP対応のLANポートを指定
## ptp4l.serviceを更新したら、systemctl daemon-reload ; systemctl restart ptp4l
その他、redhatのマニュアルも見ておくと良い。
備考3: ラズパイでptpスレーブ
ラズパイをPTPスレーブにして同期させる手早い方法。
apt install ptpd
ptpd -i eth0 -s -C
その他
OS上だけでPTPを実施してもPTP本来の精度的には無意味だが、例えば、狭いネットワーク内の機器でログ時刻を合わせたいといったシーンはよくある。そうしたシーンではPTPはお手軽な時刻合わせ手段となる。但し、Windowsで動く手軽なPTPソフトは見つかっていない(仮想マシン上のLinuxでは動く)。