前回はGPSのMNEAだけでNTPサーバという内容だった。
今回はなるべく簡単にPPS信号を使って精度を高めようという記事。
先ず、GPSモジュールからのTime Pulse(1PPS)信号をNanoPiに受け取らせたい。
前回と同じNanoPi NEOのピン配置図を見るとGPIOという割にすべてのピンに何らかの役割がアサインされている。
取り敢えず今回はGPIO18番ピンを使いたいと思う。18番ピンは上の図の右端の下から4番めのPG9と書かれたところ。これは本来はUART1のフロー制御用のピン。そのままではPPS入力用としては使えないのでGPIOのアサイン制御を行う。
その際、Linux側からは物理的なピン番号は使わずLinux gpio番号を使う。
各GPIOピン番号に対応するLinux gpio番号は上のピン配置図の画像をクリックして表示されるWikiページに書いてある。linux gpio番号の求め方(計算方法)というものもあるようだが憶える意味がないのでWikiのページを見るだけで。
GPSモジュールのPPS出力からNanoPi NEOの18番ピンを接続した。黄色の線。
# echo "201" > /sys/class/gpio/export # echo "in" > /sys/class/gpio/gpio201/direction # cat /sys/class/gpio/gpio201/direction ←確認 in ←inが表示されたらOK
/sys/class/gpio/export に対して制御したいLinux gpio番号の"201"を送信する。
Linux gpio201番を受信用(in)にする。今回は受信用だけど、信号を出力する用途ならinの代わりにoutを指定する。
書くまでもないことだが、デジタルなので信号の値は1 (Hi)、0 (Low)の2種類だけ。
現在のLinux gpio201番への入力の値を確認する。
$ cat /sys/class/gpio/gpio201/value
0 ←現在の値は0 (Low)
PPS信号を入力していると基本は0の筈だが連続して繰り返すと値が1になる瞬間に当たる筈。
今回は入力専用でしか使わないが、出力用にセットした場合は値をセット(信号を出力)できる。
$ echo 1 > /sys/class/gpio/gpio201/value #Hiを出力 $ echo 0 > /sys/class/gpio/gpio201/value #Lowを出力
PPS信号入力(出力)用としての利用をやめる時は下のように開放する。
# echo "201" > /sys/class/gpio/unexport
rpi_gpio_ntpdのインストール
rpi_gpio_ntpdはGPIOからの入力をNTPに渡してくれるツール。1秒ごとにピコンピコンと来るのをセンテンスにしてNTPに渡すのかな。rpi_gpio_ntpdは名前にrpiと付いているので元々はラズパイ用のツール。NanoPiシリーズでも使用できるとは書いてないけどOrangePiで使えるんだからNanoPiでもイケる。(GPIOを使える状態にしてから実行しないとダメみたいだけど)
rpi_gpio_ntpdのビルドには特に追加しなければならないパッケージは無いので以下3行の実行で終わる。(所要時間1分以内)
# git clone https://github.com/flok99/rpi_gpio_ntpd.git # cd rpi_gpio_ntpd # make install
rpi_gpio_ntpの使用方法
# /usr/local/bin/rpi_gpio_ntp -h
rpi_gpio_ntp v1.5, (C) 2013-2015 by folkert@vanheusden.com
-N x x must be 0...3, it is the NTP shared memory unit number
-g x gpio pin to listen on
-G x explicit path to the gpio-pin-path, for special cases like the cubieboard1 (/sys.../gpio1_pg9 instead of /sys.../gpio1). Note: you need to "export" and configure the pin in this use-case by hand.
-d debug mode
-F x fudge factor (in microseconds)
-p x when enabled, toggle GPIO pin x so that you can measure delays using a scope
-f do not fork
-b handle both on rising/falling but ignore falling
-P use polling - for when the device does not support interrupts on gpio state changes
-i x polling: how long shall we sleep (part of a second) and not poll for interrupts. e.g. 0.95
rpi_gpio_ntpの動作確認
先にgpioを念の為開放して入力モードにする。
# echo "201" > /sys/class/gpio/unexport # ←開放 # echo "201" > /sys/class/gpio/export # ←使用開始 # echo "in" > /sys/class/gpio/gpio201/direction # ←入力モードセット
# /usr/local/bin/rpi_gpio_ntp -g 201 -d
rpi_gpio_ntp v1.5, (C) 2013-2015 by folkert@vanheusden.com
NTP unit : 0
GPIO pin : 201
GPIO pout: -1
Fudge : 0.000000000
"Fork into the background" disabled because of debug mode.
1489463315.000045988] interrupt #1, 0 wraps, offset 0.000046s nan/0.000046/nan
1489463316.000037482] interrupt #2, 0 wraps, offset 0.000037s 0.000037/0.000042/nan
1489463317.000006725] interrupt #3, 0 wraps, offset 0.000007s 0.000022/0.000030/nan
1489463318.000021552] interrupt #4, 0 wraps, offset 0.000022s 0.000022/0.000028/nan
1489463319.000007224] interrupt #5, 0 wraps, offset 0.000007s 0.000018/0.000024/nan
1489463320.000021080] interrupt #6, 0 wraps, offset 0.000021s 0.000019/0.000023/nan
1489463321.000023681] interrupt #7, 0 wraps, offset 0.000024s 0.000019/0.000023/0.000024
1489463322.000010403] interrupt #8, 0 wraps, offset 0.000010s 0.000017/0.000022/0.000024
1489463323.000028576] interrupt #9, 0 wraps, offset 0.000029s 0.000017/0.000023/0.000026
1489463324.000001205] interrupt #10, 0 wraps, offset 0.000001s 0.000015/0.000020/0.000026
1489463325.000010702] interrupt #11, 0 wraps, offset 0.000011s 0.000015/0.000020/0.000026
1489463326.000010529] interrupt #12, 0 wraps, offset 0.000011s 0.000014/0.000019/0.000026
1489463327.000020516] interrupt #13, 0 wraps, offset 0.000021s 0.000014/0.000019/0.000024
1489463328.000007457] interrupt #14, 0 wraps, offset 0.000007s 0.000013/0.000018/0.000024
1489463329.000026186] interrupt #15, 0 wraps, offset 0.000026s 0.000013/0.000019/0.000025
1489463330.000019952] interrupt #16, 0 wraps, offset 0.000020s 0.000013/0.000019/0.000024
1489463331.000023795] interrupt #17, 0 wraps, offset 0.000024s 0.000013/0.000019/0.000024
1489463332.000034301] interrupt #18, 0 wraps, offset 0.000034s 0.000013/0.000020/0.000025
1489463333.000014637] interrupt #19, 0 wraps, offset 0.000015s 0.000014/0.000020/0.000025
1489463334.000019262] interrupt #20, 0 wraps, offset 0.000019s 0.000014/0.000020/0.000025
1489463335.000019454] interrupt #21, 0 wraps, offset 0.000019s 0.000014/0.000020/0.000025
1489463336.000029841] interrupt #22, 0 wraps, offset 0.000030s 0.000014/0.000020/0.000026
1489463337.000002309] interrupt #23, 0 wraps, offset 0.000002s 0.000014/0.000019/0.000026
1489463338.000030650] interrupt #24, 0 wraps, offset 0.000031s 0.000014/0.000020/0.000026
停止させるのはCtrl+C
上にも書いたが、物理的なピン番号は18だが制御するのはLinux gpio番号の201。
使用した後はgpio201を開放する。
# echo "201" > /sys/class/gpio/unexport
ntpdのビルド (不要)
カーネルPPSを使用する場合はarmbianのパッケージでインストールしたntpdはPPSに非対応なので自分でビルドすることになるが、今回はrpi_gpio_ntpなのでビルドの必要は無い。でも、ビルドしたい場合は下
# apt-get install libcap-dev pps-tools # /etc/init.d/ntp stop # apt-get remove ntp $ wget http://archive.ntp.org/ntp4/ntp-4.2.8p8.tar.gz $ tar zxvf ntp-4.2.8p8.tar.gz $ cd ntp-4.2.8p8 $ ./configure --enable-linuxcaps $ make -j4 # make install # ln -s /usr/local/sbin/ntpd /usr/sbin/ntpd # ln -s /usr/local/bin/ntpdc /usr/bin/ntpdc #必要なら # ln -s /usr/local/bin/ntpq /usr/bin/ntpq #必要なら # ln -s /usr/local/bin/ntpsweep /usr/bin/ntpsweep #必要なら # ln -s /usr/local/bin/ntptrace /usr/bin/ntptrace #必要なら
/etc/ntp.confにPPS用の設定を追記する。
このとき、カーネルPPSであれば127.127.22.*を指定するが、rpi_gpio_ntpを使用する場合は、NMEAと同じく127.127.28.*を使用する。前回(今回も引き続き)MNEA用として127.127.28.0を使用しているのでPPS用は1足して127.127.28.1を指定。
1 2 | server 127.127.28.1 minpoll 4 maxpoll 4 prefer
fudge 127.127.28.1 refid PPS
|
準備完了
# echo "201" > /sys/class/gpio/unexport # ←GPIO201開放(念の為) # echo "201" > /sys/class/gpio/export # ←同使用開始 # echo "in" > /sys/class/gpio/gpio201/direction # ←入力モードセット # /usr/local/bin/rpi_gpio_ntp -N 1 -g 201 # ←rpi_gpio_ntp開始 # /etc/init.d/ntp start # ←ntp開始
暫く待ってから確認。
$ ntpq -p
remote refid st t when poll reach delay offset jitter
==============================================================================
+SHM(0) .NMEA. 0 l 10 16 377 0.000 1.471 0.153
*SHM(1) .PPS. 0 l 9 16 377 0.000 0.001 0.006
+ntp1.jst.mfeed. 133.243.236.17 2 u 14 64 377 14.508 3.409 0.184
+ntp2.jst.mfeed. 133.243.236.17 2 u 15 64 377 13.886 2.908 0.229
+ntp3.jst.mfeed. 133.243.236.17 2 u 19 64 377 14.500 1.873 0.161
上手く行ったらシステム起動時に自動実行できるように/etc/rc.localに追記。
1 2 3 | echo "201" > /sys/class/gpio/export
echo "in" > /sys/class/gpio/gpio201/direction
/usr/local/bin/rpi_gpio_ntp -N 1 -g 201
|
最後のexit 0より前に3行挿入する。
ただ、これだとちょっと雑過ぎて最初に大きな時間のズレが出るようなので要改良。ntpdateとか挟む方が良いかも。
カーネルPPSではないが精度はまぁまぁな感じ。でも、offsetの値に落ち着きがない印象。
やっぱりカーネルをビルドしようかしら?
2017年3月15日追記:
armbianで配布しているパッケージでカーネルを4.10.0に更新するとUART1が無効になる。そこで以下1行追記。
overlays=sun8i-h3-uart1
ついでにPPS-GPIOモジュールを有効にしたい。こちらも1行追記
# vi /etc/modulespps-gpio
システムを再起動する。
# lsmod
Module Size Used by
sunxi_cir 3825 0
cfg80211 192770 0
rfkill 10928 1 cfg80211
evdev 9979 0
sun8i_codec_analog 13766 0
snd_soc_core 115473 1 sun8i_codec_analog
snd_pcm_dmaengine 4221 1 snd_soc_core
snd_pcm 70145 2 snd_pcm_dmaengine,snd_soc_core
sun8i_ths 3134 0
gpio_keys 8517 0
uio_pdrv_genirq 3354 0
cpufreq_dt 3522 0
uio 8012 1 uio_pdrv_genirq
thermal_sys 43232 2 cpufreq_dt,sun8i_ths
pps_gpio 2833 0
g_serial 3737 0
libcomposite 34692 1 g_serial
fuse 70718 1
上の例では下から4行目にpps_gpioが表示されている。
ここまでは上手くいったが/dev/pps*が生えてこなくて詰んだ。
追記ここまで。
- NanoPi NEOとGPSモジュールでNTPサーバ PPS検証編
- NanoPi NEOとGPSモジュールでNTPサーバ PPS解決編
- NanoPi NEOの時刻のズレを直したい
- NanoPi NEOとGPSモジュールでNTPサーバ 高精度PPS編
- NanoPi NEOとGPSモジュールでNTPサーバ 簡易PPS編 ←いまここ
- NanoPi NEOにGPSモジュールを繋いでNTPサーバ
- GPSモジュール
- GPSレシーバーでStratum 1なNTPサーバ
- アッチッチなNanoPi NEO3を冷やしたい パッド交換
- NanoPi NEO3冷却力強化後のUnixBench
- アッチッチなNanoPi NEO3を冷やしたい
- NTPサーバの時刻ソースに対するズレの調整
- NanoPi NEO3をv6プラスのルーターにする systemd-networkd + nftables
- NanoPi NEO3のUSB3.0ポートのネットワーク速度
- NanoPi NEO3でArmbian よきところでUnixBench
- NanoPi NEO3が届いた
- NanoPi NEOにRTCモジュールを付ける
- 新しい中華GPSモジュールとChronyで作るNTPサーバ (中編)
- 新しい中華GPSモジュールとChronyで作るNTPサーバ (前編)
- Prometheus2とGrafana6によるシステム監視 シングルボードコンピュータの温度表示
- NanoPi NEOでNTPサーバ再構築 (全まとめ)
- NanoPi NEO2をv6プラスのルーターにする 後編
- NanoPi NEO2をv6プラスのルーターにする 前編
- ELK Stackでシステム監視 FilebeatでNTP統計ログ取得 Logstashで加工
- NanoPi NEO2(arm64)用にFilebeatをビルド
- NanoPi NEO2を超コンパクトなアルミケースに入れる
- NanoPi NEO2用armbian 5.41 Debian 9 Stretch next 4.14.18
- NanoPi NEO2を100均の灰皿に入れてみた
- NanoPi NEO2のシステム監視 RPi-Monitorとnetdata
- NanoPi NEOとGPSモジュール用アルミケースを作る
- NanoPi NEO2 + DACで音楽プレーヤーVolumioを使う
- NanoPi NEO2にDACを接続
- NanoPi NEO2の最大クロック引き下げ後のUnixBench 再び
- NanoPi NEO2用armbian 5.32 Debian 9 Stretch 4.13.0-RC6
- NanoPi NEO2用armbian 5.32 Debian jessie 4.13.0-RC6
- NanoPi NEOをSIP電話機にする 後編 (その2)
- NanoPi NEO2とICカードリーダーでタイムレコーダーを作る(実用化編)
- NanoPi NEO2とICカードリーダーでタイムレコーダーを作る