本記事は、Raspberry Pi 5 を使用して Precision Time Protocol (PTP) による高精度な時刻同期を実現するための基本的な原理と実装方法をまとめたものです。PTPの大きな特徴は、ネットワークインターフェースカード (NIC) が持っている専用の時計 (PHC: PTP Hardware Clock) を活用する点にあります。
PTPとは、ネットワークに接続された複数のデバイス間でマイクロ秒からナノ秒オーダーという非常に高精度な時刻同期を実現するためのプロトコルです。特に、産業オートメーション、金融取引システム、計測・制御システム、マルチメディア同期など、正確な時刻情報が求められる分野で活用されます。Raspberry Pi 4ではPTPに対応していませんでしたが、Raspberry Pi 5から対応となりました。Raspberry Pi 5のPTPを利用した産業システムとして大きなメリットを見出せるかもしれません。
Raspberry Pi 5 と PTP
実はRaspberry Pi 5 は、Gigabit Ethernetコントローラを通じてPTP機能を利用できます。実際のタイムスタンプ精度やサポートレベルは、カーネルバージョンやドライバの実装に依存する場合があります。
まずはethtool -T eth0コマンドでご自身の環境の対応状況を確認することをお勧めします。Raspberry Pi OS (Bookworm以降) では、linuxptpというツールスイートを利用してPTP同期を設定できます。PTP Hardware Clock: 0とインデックス番号が表示されればPTPハードウェアクロックが利用可能です。
tech@raspberrypi:~$ ethtool -T eth0
Time stamping parameters for eth0:
Capabilities:
hardware-transmit
software-transmit
hardware-receive
software-receive
software-system-clock
hardware-raw-clock
PTP Hardware Clock: 0
Hardware Transmit Timestamp Modes:
off
on
onestep-sync
Hardware Receive Filter Modes:
none
all
linuxptpは、PTP (Precision Time Protocol) をLinuxシステムで利用するための一連のツール群です。linuxptp を使ってPTPで高精度な時刻同期を実現する場合、通常は ptp4l と phc2sys の両方のツールを組み合わせて使用します。
また本記事は2025年5月21日時点のものです。Debian GNU/Linux 12 (bookworm) で、カーネルは 6.12.25+rpt-rpi-2712 を使用しています。
tech@raspberrypi:~$ cat /etc/os-release
PRETTY_NAME=”Debian GNU/Linux 12 (bookworm)”
NAME=”Debian GNU/Linux”
VERSION_ID=”12″
VERSION=”12 (bookworm)”
VERSION_CODENAME=bookworm
ID=debian
HOME_URL=”https://www.debian.org/”
SUPPORT_URL=”https://www.debian.org/support”
BUG_REPORT_URL=”https://bugs.debian.org/”
tech@raspberrypi:~$ uname -r
6.12.25+rpt-rpi-2712
tech@raspberrypi:~$
主要なツールとPTP の基本的な仕組みと役割
PTPネットワークは、主に以下の役割を持つデバイスで構成されます。数台の構成であれば、1台をマスター、残りをスレーブとして設定することでPTP同期を実現できます。小規模から中規模のネットワークにおいて高精度なPTPマスターまたはスレーブとして、低価格なRaspberry Pi 5で機能させることができます。主要なツールと用語について説明します。
・ptp4l
ネットワークインターフェースカード (NIC) のPHCをPTPネットワーク上のマスタークロックに同期させたり、自身がマスタークロックとして振る舞ったりするためのデーモンです。
・phc2sys
ネットワークインターフェースカード(NIC)のハードウェアクロック(PHC)と、システムのメインクロック(システムクロック)との間で時刻を同期させるためのプログラムです。NICのPHCとシステムのメインクロックとの間で時刻を同期させるためのデーモンです。
・グランドマスター (Grandmaster Clock)
ネットワーク全体の時刻の基準となる最も正確なクロック源です。
・マスター (Master Clock)
グランドマスターから時刻情報を受け取り、下位のクロック(スレーブ)に時刻を配信するクロックです。
・スレーブ (Slave Clock)
マスタークロックから時刻情報を受け取り、自身のクロックをマスターに同期させるクロックです。
PTPは、これらのデバイス間で時刻情報を交換し、通信経路の遅延などを計算・補正することで、高精度な同期を実現します。より高い精度や信頼性が求められる大規模なシステムや、極めて厳密な時刻精度が要求される専門分野向けには、専用のグランドマスター(数十万円から、高性能なものは数百万円以上はするでしょう)を利用することで時刻の精度、安定性、信頼性において格段に高い性能が期待できます。
専用のグランドマスターには及ばないものの、Raspberry Pi 5にて、小規模から中規模のネットワークにおいては、高精度なPTPマスターまたはスレーブとして機能させることができるのが醍醐味です。アイデア次第では、従来より遥に低いコストでPTPを利用した装置を構築できるかもしれません。
Raspberry Pi 5 での PTP 実装手順概要
1台のRaspberry Pi 5をPTPマスター、もう1台をPTPスレーブとして構成する基本的な手順の概要を示します。まずは共通の準備 (マスター・スレーブ両方)です。linuxptpをインストールして、PTP (Precision Time Protocol) が通信に使用する標準ポート319と320を空けてください。
sudo apt update
sudo apt install linuxptp
sudo apt install ufw
sudo ufw allow 319
sudo ufw allow 320
PTPマスター側の設定
マスターは、自身のシステムクロックを基準にPHCを同期させ、そのPHCをPTPでネットワークに配信します。そのため「私はマスター」と宣言する設定ファイルを作ります。
sudo nano /etc/linuxptp/ptp-master.conf
————
[global]
time_stamping hardware
masterOnly 1
priority1 128
————
次にコンピューター本体の時計を、ネットワークカードの時計に合わせます。PHCとシステムクロックの同期 (phc2sys)とシステムクロック (CLOCK_REALTIME) をソースとして、NIC (eth0) のPHCを同期させます。このコマンドはバックグラウンドで実行し続ける必要があります 。
sudo phc2sys -s CLOCK_REALTIME -c eth0 -O 0 –step_threshold 0.5 -m
実行すると以下のような表示が確認できます。
phc2sys[10753.997]: eth0 sys offset -1058242430566 s0 freq +0 delay 55
phc2sys[10754.997]: eth0 sys offset -1058242483590 s1 freq -53017 delay 37
phc2sys[10755.997]: eth0 sys offset -1262 s2 freq -54279 delay 37
phc2sys[10756.990]: eth0 sys offset 16 s2 freq -53380 delay 37
次にネットワークカードの時計の時刻を、周りの機器に配る設定をします。先ほど作成したconfファイルを実行します。このコマンドもバックグラウンドで実行し続ける必要があります。
sudo ptp4l -f /etc/linuxptp/ptp-master.conf -i eth0 -m
実行した結果は、以下のような表示になります。「assuming the grand master role」という表示が最も重要です。これによりRaspberry Pi 5がグランドマスタークロックとして稼働開始しました。
ptp4l[10922.172]: selected /dev/ptp0 as PTP clock
ptp4l[10922.172]: port 1: INITIALIZING to LISTENING on INIT_COMPLETE
ptp4l[10922.172]: port 0: INITIALIZING to LISTENING on INIT_COMPLETE
ptp4l[10928.257]: port 1: LISTENING to MASTER on ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES
ptp4l[10928.257]: selected local clock 2ccf67.fffe.290682 as best master
ptp4l[10928.257]: port 1: assuming the grand master role
同期の検証を行うために、一時的な確認コマンドとして以下のようなものを作ると便利です。作らなくてもOKです。
sudo nano /etc/linuxptp/ptp-master.sh
———————
#!/bin/bash
sudo ptp4l -f /etc/linuxptp/ptp-master.conf -i eth0 -m > /var/log/ptp4l.log 2>&1 &
sudo phc2sys -s CLOCK_REALTIME -c eth0 -O 0 –step_threshold 0.5 -m > /var/log/phc2sys.log 2>&1 &
———————sudo tail -f /var/log/ptp4l.log
sudo pkill phc2sys
sudo phc2sys -s CLOCK_REALTIME -c eth0 -O 0 –step_threshold 0.5 -m
にてログ確認できます。サービス化する前の一次的なものです。
これらのコマンド群は、PTPマスターを手動で起動し、その動作状況を確認するための一連の手順を示しています。最終的には、これらのプロセスを systemd サービスとして登録し、システムの起動時に自動的に開始するようにする必要があります。
PTPスレーブ側の設定
スレーブは、ネットワーク上のマスターからPTP時刻を受信してPHCを同期し、さらにそのPHCでシステムクロックを調整します。マスターの時刻を、自分のネットワークカードの時計にコピーします。スレーブ専用モードで同期状態のサマリーログを秒ごとに出力するコマンドです。このコマンドはバックグラウンドで実行し続ける必要があります。
sudo ptp4l -i eth0 -s -m –summary_interval 1
実行するとこのように表示されます。
tech@raspberrypi:~ $ sudo ptp4l -i eth0 -s -m –summary_interval 1
ptp4l[4518.538]: selected /dev/ptp0 as PTP clock
ptp4l[4518.538]: port 1: INITIALIZING to LISTENING on INIT_COMPLETE
ptp4l[4518.538]: port 0: INITIALIZING to LISTENING on INIT_COMPLETE
ptp4l[4518.842]: port 1: new foreign master 2ccf67.fffe.290682-1
ptp4l[4522.842]: selected best master clock 2ccf67.fffe.290682
ptp4l[4522.842]: port 1: LISTENING to UNCALIBRATED on RS_SLAVE
ptp4l[4525.842]: rms 5296707 max 5323565 freq -26927 +/- 26927 delay 22171 +/- 1446
ptp4l[4526.842]: port 1: UNCALIBRATED to SLAVE on MASTER_CLOCK_SELECTED
ptp4l[4527.842]: rms 10 max 10 freq -53843 +/- 1
ptp4l[4529.842]: rms 6838 max 9217 freq -47339 +/- 3585 delay 16108 +/- 4616
ptp4l[4531.842]: rms 3926 max 4264 freq -49212 +/- 3270 delay 6362 +/- 0
ptp4l[4533.842]: rms 2783 max 3829 freq -52501 +/- 1595 delay 3374 +/- 936
ptp4l[4535.842]: rms 2931 max 3447 freq -54808 +/- 55 delay 2304 +/- 44
ネットワークカードの時計を、コンピューター本体の時計に合わせます。このコマンドもバックグラウンドで実行し続ける必要があります (デーモン化推奨)。
sudo phc2sys -s eth0 -c CLOCK_REALTIME -O 0 –step_threshold 0.5 -m
以上にてマスターとスレーブの動作が確認できましたらPTP同期の完成です。
それぞれをPTPをサービス化:マスター側のサービス化
systemd サービスファイルに直接コマンドを記述する方法と、シェルスクリプトを作成してそのスクリプトを systemd サービスから呼び出す方法があります。多くの場合、サービスファイルに直接コマンドを記述する方がシンプルで管理しやすいです。シェルスクリプト化は、もし将来的に、PTPサービス起動の前後に非常に多くのカスタム処理が必要になった場合は、検討してください。
以下に、基本的な systemdサービスファイルの例を示します。これらの内容は /etc/systemd/system/ディレクトリに新しいファイルとして保存し(例: ptp4l-master.servic)、その後 sudo systemctl enable [サービス名] および sudo systemctl start [サービス名]で有効化・起動してください。
マスター側の設定例:ptp4l マスター設定
sudo nano /etc/systemd/system/ptp4l-master.service
——–
[Unit]
Description=PTP4L Master Daemon
After=network-online.target
Wants=network-online.target
ExecStartPre=/bin/sleep 10[Service]
Type=simple
ExecStart=/usr/sbin/ptp4l -f /etc/linuxptp/ptp-master.conf -i eth0 -m
Restart=on-failure[Install]
WantedBy=multi-user.target
———
マスター側の設定例:phc2sys システムクロック -> PHC
sudo nano /etc/systemd/system/phc2sys-master.service
—–
[Unit]
Description=PHC2SYS Master Daemon (System Clock to PHC)
After=ptp4l-master.service
Requires=ptp4l-master.service[Service]
Type=simple
ExecStart=/usr/sbin/phc2sys -s CLOCK_REALTIME -c eth0 -O 0 –step_threshold 0.5 -w -m
Restart=on-failure[Install]
WantedBy=multi-user.target
———
サービスの登録と確認コマンドは以下です。
sudo systemctl daemon-reload
sudo systemctl enable ptp4l-master.service
sudo systemctl enable phc2sys-master.servicesudo systemctl start ptp4l-master.service
sudo systemctl start phc2sys-master.servicesudo systemctl stop ptp4l-master.service
sudo systemctl stop phc2sys-master.servicesudo systemctl status ptp4l-master.service
sudo systemctl status phc2sys-master.service
※PTPを利用して高精度な時刻同期を行う際には、他の時刻同期サービス(この場合はsystemd-timesyncd)を停止してください。
PTPは非常に高精度な相対的な同期を実現するプロトコルです。ネットワーク内のデバイス間の時刻を高精度に一致させますが、そのネットワーク全体の時刻が絶対的に正しいかどうかは、グランドマスタークロックの正確性に依存します。PTPネットワーク全体の時刻が世界の標準時刻と同期する必要がある場合はGPSなど何かしらの仕組みが必要です。
sudo systemctl stop systemd-timesyncd
sudo systemctl disable systemd-timesyncd
スレーブ側のサービス化
次はスレーブ側をサービス化します。これらのサービスファイルを適切に設定することで、Raspberry Pi の起動時に自動的にPTP同期が開始されるようになります。
スレーブ側の設定例:ptp4l マスター設定
sudo nano /etc/systemd/system/ptp4l-slave.service
——
[Unit]
Description=PTP4L Slave Daemon
After=network-online.target
Wants=network-online.target
ExecStartPre=/bin/sleep 10[Service]
Type=simple
ExecStart=/usr/sbin/ptp4l -i eth0 -s -m –summary_interval 1
Restart=on-failure[Install]
WantedBy=multi-user.target
——
スレーブ側の設定例:phc2sys システムクロック -> PHC
sudo nano /etc/systemd/system/phc2sys-slave.service
——–
[Unit]
Description=PHC2SYS Slave Daemon (PHC to System Clock)
After=ptp4l-slave.service
Requires=ptp4l-slave.service[Service]
Type=simple
ExecStart=/usr/sbin/phc2sys -s eth0 -c CLOCK_REALTIME -O 0 –step_threshold 0.5 -w -m
Restart=on-failure[Install]
WantedBy=multi-user.target
——–
サービスの登録と確認コマンドは以下です。
sudo systemctl daemon-reload
sudo systemctl enable ptp4l-slave.service
sudo systemctl enable phc2sys-slave.servicesudo systemctl start ptp4l-slave.service
sudo systemctl start phc2sys-slave.servicesudo systemctl stop ptp4l-slave.service
sudo systemctl stop phc2sys-slave.servicesudo systemctl status ptp4l-slave.service
sudo systemctl status phc2sys-slave.service
※PTPを利用して高精度な時刻同期を行う際には、他の時刻同期サービス(この場合はsystemd-timesyncd)を停止してください。
PTPは非常に高精度な相対的な同期を実現するプロトコルです。ネットワーク内のデバイス間の時刻を高精度に一致させますが、そのネットワーク全体の時刻が絶対的に正しいかどうかは、グランドマスタークロックの正確性に依存します。PTPネットワーク全体の時刻が世界の標準時刻と同期する必要がある場合はGPSなど何かしらの仕組みが必要です。
sudo systemctl stop systemd-timesyncd
sudo systemctl disable systemd-timesyncd
PTP同期の確認方法
一番わかりやすい方法は、スレーブ側でのptp4lの出力ログをモニタリング表示です。「master offset」や「delay」などの値が表示されます。
—これだけ見れば基本はOKスレーブ側で
sudo journalctl -u ptp4l-slave.service -f—細かくはマスター側で
sudo journalctl -u ptp4l-master.service -f
assuming the grand master role になっていることを確認—そのあとにマスター側で
sudo journalctl -u phc2sys-master.service -f
マスター側のクロック同期を確認—スレーブ側の同期を確認
sudo journalctl -u ptp4l-slave.service -f
sudo journalctl -u phc2sys-slave.service -f
でスレーブ側もクロック同期しているか確認
以下スレーブ側の同期を確認した結果です。50ナノレベルで同期しており、数十ナノ秒レベルのオフセットという良好な状態です。PTPスレーブがマスタークロックとナノ秒オーダーで非常に良好に同期していることを示しています。
tech@raspberrypi:~$ sudo journalctl -u ptp4l-slave.service -f
5月 16 23:35:01 raspberrypi ptp4l[1718]: ptp4l[5114.428]: rms 51 max 63 freq -53947 +/- 19 delay 2061 +/- 1
5月 16 23:35:01 raspberrypi ptp4l[1718]: [5114.428] rms 51 max 63 freq -53947 +/- 19 delay 2061 +/- 1
5月 16 23:35:03 raspberrypi ptp4l[1718]: ptp4l[5116.428]: rms 52 max 69 freq -53979 +/- 12 delay 2061 +/- 1
5月 16 23:35:03 raspberrypi ptp4l[1718]: [5116.428] rms 52 max 69 freq -53979 +/- 12 delay 2061 +/- 1
しばらく見ていると時折rmsが2000になり、再び収束しました。単位はnsですから2マイクロ秒でしょうか。
1 秒 (s) = 1,000 ミリ秒 (ms)
1 ミリ秒 (ms) = 1,000 マイクロ秒 (µs)
1 マイクロ秒 (µs) = 1,000 ナノ秒 (ns)
以上からナノレベルという結果は、優れたものでした。単位はあってますよね??
あまりに小さい数字でよくわからなくなりました。念のためご自身で確認してくださいませ。
精度向上に関するメモ
Ethernetドライバのデフォルト設定では、パケット処理に遅延が生じる可能性があります。より高い精度を求める場合は、`ethtool -C eth0 tx-usecs 4 rx-usecs 4` のように設定して遅延を最小化することを検討してください。初期設定ではrx-usecs: 49、tx-usecs: 49ぐらいのサイズになっています。適用には永続化が必要です。
Raspberry Pi OSは汎用OSであり、リアルタイムOS (RTOS) ではありません。そのため、PTPによってシステムクロックが高精度に同期されても、個々のタスクやプロセスがミリ秒未満の厳密なタイミングで実行されることは保証されません。非常に厳密なリアルタイム処理が求められるアプリケーションでは、この点を考慮する必要があります。
PTPの精度はネットワーク環境(スイッチの性能、ネットワーク負荷など)に影響を受けます。PTP対応スイッチを使用すると、より高精度な同期が期待できます。
関連資料
詳細な設定やトラブルシューティングについては、linuxptpのマニュアル (man ptp4l、 man phc2sys) や関連ドキュメントをご参照ください。これらを参照して記事を作成しております。
LinuxPTP マニュアルおよび設定ガイド
LinuxPTP GitHub
https://github.com/richardcochran/linuxptp
Raspberry Pi 公式ブログ(PTP対応の発表)
Raspberry Pi 5でのPTP実験レポート
https://forums.raspberrypi.com/viewtopic.php?t=358275