ユーザ用ツール

サイト用ツール


raspberrypi:log20171231_rpi3_ntp_stratum_1

文書の過去の版を表示しています。


Raspberry Pi 3 で NTP Stratum-1 Server を作る(Raspbian jessie)

こちらで紹介した NTP Stratum-1 Server は,3年10ヶ月ほど正確な時間を刻み続けていましたが,2017-12-23 に起動不能になり正確な時刻を刻み続けることができなくなりました.

この後継サーバとして Raspberry Pi 3 で NTP Stratum-1 Server を製作したので,ノートとして記録します.

●変更履歴

* 執筆中

●まとめ

  • Raspberry Pi 3 に GPS 時刻情報と PPS 信号を入れることで,GPS と数マイクロ秒程度で同期させることが出来ます.

●GPSボード

GPSボードは前回と同じものをそのまま再利用します. 下記URLから入手できるのですが,私が購入したのはもう3年以上前なので,今のGPSボードと変わっているようです.

Raspberry Pi GPS Addon Board
http://ava.upuaut.net/store/index.php?route=product/product&product_id=95

●必要なスキル

  • カーネルの再コンパイルが出来る事

前回と異なり,今回は ntpd のコンパイルは行わず,Raspbian にパッケージされている ntpd をそのまま使います.

Linux ディストリビューションは Raspbian jessie です. http://www.raspberrypi.org/downloads から得られる Raspbian Raw Images を SD カードに書き込みます.私は 2017-11-29-raspbian-stretch-lite.img を書き込みました.

よく知られていることとして,Raspbian をイメージから書き込んだ場合のデフォルトユーザーは pi です. ここ数年,Raspbian のデフォルトユーザーを狙った ssh 不正ログイン試行がインターネット上で多発していますから pi ユーザのパスワードは必ず変更しましょう!

●カーネル再コンパイル

前回と同様に,NTP Stratum-1 に合うようにRaspberry Pi 3 の Linux カーネルをコンパイルします. カーネルコンパイルの方法は, https://www.raspberrypi.org/documentation/linux/kernel/building.md の“Cross-compiling” 記載されている手順で進めました.

標準の bcm2709_defconfig と NTP Stratum-1 向けの .config の差を掲載します.前回と似ていますが,以下のようにします.

  1. CONFIG_NO_HZ を無効にする.(# CONFIG_NO_HZ is not set)
    私の環境では,CONFIG_HZ_PERIODIC=y にしています.
  2. CONFIG_PPS を有効にする.
    bcm2709_defconfig では,すでに CONFIG_PPS=m でした.
  3. CONFIG_NTP_PPS を有効にする.
.config-NTP-1.patch
--- .config.org	2017-12-24 18:21:17.166881242 +0900
+++ .config-NTP-1	2017-12-24 18:32:49.820830852 +0900
@@ -77,11 +77,10 @@
 # Timers subsystem
 #
 CONFIG_TICK_ONESHOT=y
-CONFIG_NO_HZ_COMMON=y
-# CONFIG_HZ_PERIODIC is not set
-CONFIG_NO_HZ_IDLE=y
+CONFIG_HZ_PERIODIC=y
+# CONFIG_NO_HZ_IDLE is not set
 # CONFIG_NO_HZ_FULL is not set
-CONFIG_NO_HZ=y
+# CONFIG_NO_HZ is not set
 CONFIG_HIGH_RES_TIMERS=y
 
 #
@@ -2555,6 +2554,7 @@
 #
 CONFIG_PPS=m
 # CONFIG_PPS_DEBUG is not set
+CONFIG_NTP_PPS=y
 
 #
 # PPS clients support

カーネル再コンパイルが済めば, https://www.raspberrypi.org/documentation/linux/kernel/building.md の手順通りにコピーとして Raspberry Pi 3 が新しいカーネルで起動するかを確認します.

●ntp 導入前の初設定

●ソフトを最新状態へ

$ sudo apt-get update
$ sudo apt-get upgrade

●使用しないサービスの停止

$ sudo systemctl stop triggerhappy.service
$ sudo systemctl disable triggerhappy.service
$ sudo systemctl stop triggerhappy.socket
$ sudo systemctl disable triggerhappy.socket
$ sudo systemctl stop hciuart.service
$ sudo systemctl disable hciuart.service

●UART を未使用にして,pps-goioを使えるようにする

sudo raspi-config を実行して, Interfacing Options→Serial を選択し,以下のようにします.

Would you like a login shell to be accessible over serial? <No>
Would you like the serial port hardware to be enabled? <No>

The serial login shell is disabled
The serial interface is disabled

また, /boot/cmdline.txt をテキストエディタで開き,console=serial1,115200 を削除します. これでコンソールと UART を切り離します.

次に, /boot/config.txt をテキストエディタで開き,以下を追加します.

/boot/config.txt
enable_uart=1
dtoverlay=pi3-miniuart-bt
dtoverlay=pps-gpio,gpiopin=18

これで再起動後,以下のようになっていれば,/dev/ttyAMA0 が GPS NMEA 入力として利用できます.

$ ls -al /dev/serial*
lrwxrwxrwx 1 root root 7 Dec 30 16:02 /dev/serial0 -> ttyAMA0
lrwxrwxrwx 1 root root 5 Dec 30 16:02 /dev/serial1 -> ttyS0

もし,ttyAMA0 と ttyS0 が逆転している場合,設定を再度見直してください.

●CPU周波数の設定

CPU周波数を,常に一定で動作させるようにします.

$ sudo apt-get install cpufrequtils

/etc/default/cpufrequtils を開き(無ければ新規作成),以下のようにします.

/etc/default/cpufrequtils
GOVERNOR=“performance"

●デバイスファイルのパーミッション・シンボリックリンク設定

UARTやPPSデバイスファイルを ntpd で参照できるようにします.

テキストエディタで /etc/udev/rules.d/09.pps.rules を開き(無い場合は新規作成),以下のようにします.

/etc/udev/rules.d/09.pps.rules
KERNEL=="ttyAMA0", SYMLINK+="gps0"
KERNEL=="pps0", OWNER="root", GROUP="dialout", MODE="0660", SYMLINK+="gpspps0"

●再起動してチェック

一度 Raspberry Pi 3 を再起動して,以下をチェックします.

●UARTとPPSの状態

$ ls -al /dev/serial* /dev/ttyAMA0 /dev/gps0 /dev/pps0 /dev/gpspps0 
lrwxrwxrwx 1 root root          7 Dec 30 16:02 /dev/gps0 -> ttyAMA0
lrwxrwxrwx 1 root root          4 Dec 30 16:02 /dev/gpspps0 -> pps0
crw-rw---- 1 root dialout 245,  0 Dec 30 16:02 /dev/pps0
lrwxrwxrwx 1 root root          7 Dec 30 16:02 /dev/serial0 -> ttyAMA0
lrwxrwxrwx 1 root root          5 Dec 30 16:02 /dev/serial1 -> ttyS0
crw-rw---- 1 root dialout 204, 64 Dec 30 16:02 /dev/ttyAMA0
$

●CPU 周波数の状態

$ cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
performance
performance
performance
performance
$ 

●PPSドライバの動作確認

Linux カーネルのPPSドライバが,GPSモジュールのPPSを読み取っているかを確認するには,pps-tools をインストールします.

  $ sudo apt-get install pps-tools
  $ sudo ppstest /dev/pps0

GPSモジュールが測位している(PPS LEDが点滅している)と,ppstest ではそのPPS周期で出力を出していくはずです.

●NTPサーバの導入と設定

NTPサーバをインストールします.冒頭で記載した通り,今回は Raspbian jessie の NTP サーバをそのまま使います.

$ sudo apt-get install ntp

Raspbian jessie では systemd-timesyncd が SNTP クライアントとして動作していますが,NTP サーバをインストールして再起動すると,systemd-timesyncd は起動しないようになっています.

sudo vigr を実行して, dialout グループに ntp ユーザを所属させます.これにより,ntp サーバが /dev/ttyAMA0/dev/pps0 にアクセス出来るようになります.

/etc/group
...
dialout:x:20:pi,ntp
...

ここで,一旦 NTP サーバを再起動します.

/etc/ntp.conf をテキストエディタで開き,GPS と PPS を利用するようにします.

ntp.conf.patch
--- /etc/ntp.conf.orig	2017-12-30 02:35:45.487712787 +0000
+++ /etc/ntp.conf	2017-12-31 05:25:28.673876659 +0000
@@ -3,24 +3,30 @@
 driftfile /var/lib/ntp/ntp.drift
 
 # Enable this if you want statistics to be logged.
-#statsdir /var/log/ntpstats/
+statsdir /var/log/ntpstats/
 
-statistics loopstats peerstats clockstats
+#statistics loopstats peerstats clockstats
+#filegen loopstats file loopstats type day enable
+#filegen peerstats file peerstats type day enable
+#filegen clockstats file clockstats type day enable
+statistics loopstats sysstats
 filegen loopstats file loopstats type day enable
-filegen peerstats file peerstats type day enable
-filegen clockstats file clockstats type day enable
+filegen sysstats file sysstats type day enable
 
 
 # You do need to talk to an NTP server or two (or three).
 #server ntp.your-provider.example
+server 127.127.20.0 mode 17 minpoll 4 maxpoll 4 prefer
+fudge 127.127.20.0 refid GPS
+fudge 127.127.20.0 flag1 1 flag3 1
 
 # pool.ntp.org maps to about 1000 low-stratum NTP servers.  Your server will
 # pick a different set every time it starts up.  Please consider joining the
 # pool: <http://www.pool.ntp.org/join.html>
-pool 0.debian.pool.ntp.org iburst
-pool 1.debian.pool.ntp.org iburst
-pool 2.debian.pool.ntp.org iburst
-pool 3.debian.pool.ntp.org iburst
+#pool 0.debian.pool.ntp.org iburst
+#pool 1.debian.pool.ntp.org iburst
+#pool 2.debian.pool.ntp.org iburst
+#pool 3.debian.pool.ntp.org iburst
 
 
 # Access control configuration; see /usr/share/doc/ntp-doc/html/accopt.html for

主な変更点は以下のとおりです.

  1. ntpd の loopstats,sysstats ログを記録する
  2. Generic NMEA GPS Receiver の設定
  3. 外部 NTP サーバを参照しないようにする

●Generic NMEA GPS Receiver の設定について

上記の ntp.conf の設定のうち,Generic NMEA GPS Receiver 部分を再掲します.

ntp.conf
server 127.127.20.0 mode 17 minpoll 4 maxpoll 4 prefer
fudge 127.127.20.0 refid GPS
fudge 127.127.20.0 flag1 1 flag3 1

NTPサーバの Generic NMEA GPS Receiverの設定は, https://www.eecis.udel.edu/~mills/ntp/html/drivers/driver20.html に詳細が記載されています.

まず, 127.127.20.u が Generic NMEA GPS Receiver を指し,server 行の mode 17は,9600bps で GPS と接続し,NMEA の $GPRMC センテンスを使用する事を示します.

fudge 127.127.20.0 refid GPS は,参照先の名称を GPS にします.

fudge 127.127.20.0 flag1 1 flag3 1flag1 1 は,PPSを使う事を示します.

flag2 は PPS信号パルスを立ち上がり(rising edge)で処理するか立ち下がり(falling edge)で処理するかを設定するもので,デフォルトでは立ち上がりで処理します.これはこのまま(デフォルトのまま)使用するので設定していません.

●NTPサーバの動作検証

ntpq を実行します.

$ ntpq -p
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
oGPS_NMEA(0)     .GPS.            0 l    4   16  377    0.000    0.000   0.002

重要なのは,先頭に 'o' が出ているかどうかです.これが出ていれば,PPS同期できています.

以下のように, ntpq -c clockvar を実行すると,クロック元(GPS)の情報が得られます. $GPRMC のところは,実際に受信していたセンテンスが出てきます.

$ ntpq -c clockvar
associd=0 status=0000 no events, clk_unspec,
device="NMEA GPS Clock",
timecode="$GPRMC,......................................,,,D*xx",
poll=2319, noreply=0, badformat=0, baddata=0, stratum=0, refid=GPS,
flags=5

他,ntpq コマンドの使い方は, http://doc.ntp.org/4.2.8/ntpq.html に詳細があります.

このNTPサーバの loopstats をグラフにしたものを提示します.縦軸がリファレンス(GPS)との時間差をマイクロ秒で示し,横軸は1日あたりの経過秒を示します.

loopstats には 5400件のログがあり,その内プラスマイナス1マイクロ秒以上のズレがあったのは76件で,その他はプラスマイナス1マイクロ秒未満でした.割合で述べると,約98%はプラスマイナス1マイクロ秒未満で同期しているようです.2マイクロ秒以上のズレはこの loopstats にはありませんでした.

raspberrypi/log20171231_rpi3_ntp_stratum_1.1514855933.txt.gz · 最終更新: 2018-01-02 10:18 by tosihisa@netfort.gr.jp