こんにちは、インフラエンジニアの井上です。
これは、 TECHSCORE Advent Calendar 2016 の17日目の記事です。
Raspberry Pi 3 Model Bを買ってきたこと、そして、2017年1月1日のうるう秒挿入の件が気になったことをきっかけとして、「時刻をあわせてみる」ことをテーマにしました。
取り組むこと
Raspberry Piを使って、Stratum 1相当のNTPサーバを構築します。具体的にはGPSの電波を受信して、正確な時間を提供するサーバを構築します。
今回の材料について
今回の材料は写真のような組み合わせだけです。Raspberry Pi 3はケースとのセットをシリコンハウスというお店で見つけてきました。その他には、GlobalSat社のUSB接続型GPSレシーバ、そしてI2C接続のDS3231使用RTCモジュール、これらはAmazonにて揃えました。この中でみそなのが、RTCモジュールですね。Raspberry Piは、通常、電源が落ちると時間情報を保持できなくなってしまいます。そこで、電源が落ちても時間情報を保持し続けられるように、今回はあえてRTCモジュールを用意することにしました。
ハードウェアまわりの準備について
今回、私はraspbianをOSとして採用します。実は、このネタは11月初旬から準備を始めていていろいろ試しているうちに2016/11/25に新たなリリースがあり、この記事を書きながら、最新リリースのOSに入れ替えをしています。
そして、GPSレシーバとRTCモジュールこれは、世の中に公開されている情報をもとにPlug&Playに任せられる製品を選んでいます。GPSレシーバも今回選んだものはSiRFstarIVチップを搭載したUSBの製品で、本稿地点の最新raspbianでは刺すだけで認識できます。認識していることは以下の方法で確認できます。
1 2 3 4 5 |
root@raspberrypi:/var/log# tail -f messages (...snip..) Dec 14 11:43:50 raspberrypi kernel: [ 1.991109] usb 1-1.2: Product: USB-Serial Controller D Dec 14 11:43:50 raspberrypi kernel: [ 1.991122] usb 1-1.2: Manufacturer: Prolific Technology Inc. (...snip..) |
USBにGPSレシーバを刺した際、上記のように「Manufacturer: Prolific Technology Inc.」と表示されれば認識できています。また、追認として以下を実行しました。
1 2 3 4 5 6 7 |
root@raspberrypi:/var/log# lsusb Bus 001 Device 005: ID 04d9:4545 Holtek Semiconductor, Inc. Bus 001 Device 004: ID 056e:00cd Elecom Co., Ltd Bus 001 Device 006: ID 067b:2303 Prolific Technology, Inc. PL2303 Serial Port Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp. SMSC9512/9514 Fast Ethernet Adapter Bus 001 Device 002: ID 0424:9514 Standard Microsystems Corp. Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub |
今回のGPSレシーバは「Prolific Technology Inc. PL2303 Serial Port」にあたりますので、USBの認識もできています。
ソフトウェアまわりの準備について
特別なソフトウェアは利用しません。ntpdやchronydなど選択肢はありますが、今回はraspbianのレポジトリから取得できるntpdを使用します。また、今回、GPSを使うということからgpsdも使用します。ともにaptで入手可能です。
設定について
設定を行わな分ければいけないのはgpsdの設定とntpdの設定のみでした。具体的には以下のようになります。
まずはgpsdから行ったことを書かせていただきます。
1 2 3 4 5 6 7 8 9 10 11 |
root@raspberrypi:/etc# cd /etc/default/ root@raspberrypi:/etc/default# cp gpsd /root/ root@raspberrypi:/etc/default# diff gpsd /root/gpsd 11c11 < DEVICES="/dev/ttyUSB0" --- > DEVICES="" 14c14 < GPSD_OPTIONS="-F /var/run/gpsd.sock -b -n" --- > GPSD_OPTIONS="" |
ここで、実際に行っているのは、gpsdの起動オプションの変更と、GPSレシーバのデバイス名設定のみです。では、起動します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
root@raspberrypi:/etc/default# systemctl enable gpsd Synchronizing state for gpsd.service with sysvinit using update-rc.d... Executing /usr/sbin/update-rc.d gpsd defaults Executing /usr/sbin/update-rc.d gpsd enable root@raspberrypi:/etc/default# systemctl status gpsd ● gpsd.service - GPS (Global Positioning System) Daemon Loaded: loaded (/lib/systemd/system/gpsd.service; static) Active: inactive (dead) root@raspberrypi:/etc/default# systemctl start gpsd root@raspberrypi:/etc/default# systemctl status gpsd ● gpsd.service - GPS (Global Positioning System) Daemon Loaded: loaded (/lib/systemd/system/gpsd.service; static) Active: active (running) since Wed 2016-12-14 20:52:07 JST; 1s ago Main PID: 1424 (gpsd) CGroup: /system.slice/gpsd.service mq1424 /usr/sbin/gpsd -N -F /var/run/gpsd.sock -b -n /dev/ttyUSB0 Dec 14 20:52:07 raspberrypi systemd[1]: Started GPS (Global Positioning Syst.... Hint: Some lines were ellipsized, use -l to show in full. |
起動メッセージをみるとGPSが有効になったことがわかります。念のため、得られるGPS情報を確認します。
1 |
root@raspberrypi:/etc/default# cgps -s |
結果は図のようにきちんとGPSからの情報が取得できていました。
では、ntpdの設定を行います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
root@raspberrypi:/etc# cp /etc/ntp.conf /root/ root@raspberrypi:/etc# vi /etc/ntp.conf root@raspberrypi:/var/log# diff /etc/ntp.conf /root/ntp.conf 21,24c21,24 < ### server 0.debian.pool.ntp.org iburst < ### server 1.debian.pool.ntp.org iburst < ### server 2.debian.pool.ntp.org iburst < ### server 3.debian.pool.ntp.org iburst --- > server 0.debian.pool.ntp.org iburst > server 1.debian.pool.ntp.org iburst > server 2.debian.pool.ntp.org iburst > server 3.debian.pool.ntp.org iburst 26,29d25 < < # for GPS < server 127.127.28.0 minpoll 4 < fudge 127.127.28.0 time1 0.183 refid GPS stratum 1 |
こちらも、たいした設定は行っていません。パッケージのデフォルトで設定されているntpサーバの指定をコメントアウトし、GPSレシーバをサーバとして指定しているだけです。
またfudgeとしてクロック調整(0.183はRaspberry Pi3を利用されている方の例を探す中で例として多かったために採用しました)、参照名をGPS、Stratam1の指定をしています。この状態で起動と確認を実施してみました。
1 2 3 4 5 |
root@raspberrypi:/etc# systemctl start ntp root@raspberrypi:/etc# ntpq -p remote refid st t when poll reach delay offset jitter ============================================================================== *SHM(0) .GPS. 1 l 15 16 377 0.000 0.721 1.430 |
想定通り、stratum1相当のntpサーバとして起動できました(今回は外部公開までは扱いません)。
ちなみに、購入した部品リストにRTCモジュールがあった理由がここにあるのですが、ntpdは1000秒以上差異があるとエラーを吐いて停止してしまいますため、いつでもきちんと起動させる目的でRTCモジュールを搭載していました。
GPSとうるう秒挿入の関係について
今回、このテーマに取り組もうと考えたきっかけの1つにうるう秒という話があるのですが、GPS時刻は直接的に修正されることはありません。かわりに
1 |
GPS - UTC |
のオフセットが何秒あるかという情報がNavigation Dataとして含まれるため、これにより、うるう秒対応が行われます。この記事が公開される地点では17sなのですが、うるう秒挿入が発生するとこのオフセット情報が18sにかわります。(2017年うるう秒挿入についての説明として 日本標準時プロジェクト うるう秒の対応 やNavigation CenterのBest Practices for Leap Second Event Occurring on 31 December 2016の第6項e節などでも説明されています)
今回のサーバなら、電波時計もあわせられるはず
今回の取り組みの中では実施しませんでしたが、Raspberry Piだからこそ、電波時計をあわす仕組みを容易に実現できるそうです。
GPIOと接続した回路でLEDを点滅させる際、40KHzの周期の点滅させ、LEDを点滅させるケーブルを電波時計のすぐ近くに置くことで、ケーブルがアンテナの役目を果たし疑似的に福島から送信される周波数の電波を発信させることができるそうです(ケーブルから漏れる程度の電波なので、電波法などに抵触することなく、実現できるということです。これについては検索すればすぐに見つけられる情報ですので、今回、本稿では取り扱っていません)。
まとめ
今回、扱ったRaspberry Piは安価にもかかわらず、できることが多そうで驚いています。また、私がインフラエンジニアということからntpサーバを取り扱いましたが、違った形でエンジョイできる取り組みなどをできるとよいなと感じさせられました。