新しい中華GPSモジュールとChronyで作るNTPサーバ (後編)

前編中編で<怪しい中華GPSモジュールとChronyでNTPサーバが動くようになった。
しかし、シリアルポートの通信状況を眺めるとちょっと寒い状態。

  • MNEAセンテンスの流れる速度が遅い。初期値が9600bpsなので当然。
  • 無駄なNMEAセンテンスが大量に出てくる。
  • 出力頻度が異常。

基本的に安い汎用GPSモジュールはこんなの。1PPS無しならこれをそのままNTPサーバ用で使うのはあまり良いとは思わない。1PPS有りでも良くはないけどNMEA側の問題なので1PPSメインなら精度にはおそらく影響しないけど対応はするべきかな。

安く市販されているGPSモジュールの中でもu-bloxまたはその互換チップが載っている場合はUBXプロトコルのバイナリコマンドで制御できる。(u-bloxまたは互換のどのチップで使えるかは判らないけど対応しているのは結構多い)
この記事ではそのUBXコマンドでの制御について書く。その他のチップであればそれぞれ別の制御方法があると思うのでググって。

シリアル通信速度の変更

安いGPSモジュールは多くがシリアル速度の初期値が(4800bpsや)9600bps程度になっている。これでNMEAの複数種類のセンテンスを毎秒1回程度の頻度で流すようになっていたり。GPSアンテナのロケーションが良ければ多くの衛星を捉えられるはずで、この通信速度では無理が過ぎる。
そこで、GPSモジュールと接続するPCやシングルボードコンピュータの両方が対応するシリアル速度の範囲でなるべく速い速度を使うようにしたい。
GPSモジュール側の速度変更にはGPSモジュール(チップ)にコマンドを送信しなければならない。
多くは9600bps(4800bps)が初期値で19200bps, 38400bps, 57600bps, 115200bps程度まで対応。19200bpsまでしか対応しないとか逆に230400bps以上にも対応なんてのもあるけど、速度変更不可な製品もあるので注意。

UBXコマンド

9600bpsに変更
\xB5\x62\x06\x09\x0D\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x17\x2F\xAE

19200bpsに変更
\xB5\x62\x06\x00\x14\x00\x01\x00\x00\x00\xD0\x08\x00\x00\x00\x4B\x00\x00\x07\x00\x03\x00\x00\x00\x00\x00\x48\x57

38400bpsに変更
\xB5\x62\x06\x00\x14\x00\x01\x00\x00\x00\xD0\x08\x00\x00\x00\x96\x00\x00\x07\x00\x03\x00\x00\x00\x00\x00\x93\x90

57600bpsに変更
\xB5\x62\x06\x00\x14\x00\x01\x00\x00\x00\xD0\x08\x00\x00\x00\xE1\x00\x00\x07\x00\x03\x00\x00\x00\x00\x00\xDE\xC9

115200bpsに変更
\xB5\x62\x06\x00\x14\x00\x01\x00\x00\x00\xD0\x08\x00\x00\x00\xC2\x01\x00\x07\x00\x03\x00\x00\x00\x00\x00\xC0\x7E

echoコマンドで送りやすいように \x00のような書き方になってるけどバイナリ(Hex)で00ということね。
Linuxの多くに標準で入っているバックスラッシュでエスケープの-eオプション対応のechoコマンドが使えるなら以下のように送信。

$ sudo echo -e "UBXコマンド" > /dev/シリアルデバイス名
つまり、シリアルポートttyS1に繋がっているGPSモジュールの通信速度(出力速度)を9600bpsに設定するなら
$ sudo echo -e "\xB5\x62\x06\x09\x0D\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x17\x2F\xAE" > /dev/ttyS1

FreeBSDの場合はtcshの内部コマンドとしてのechoと/bin/shが使う/bin/echoの2種類がある。 /bin/echoは知らないが、linuxのechoコマンドのようにバックスラッシュでエスケープすることができるのでなければ個人的にはxxdを使う。

9600bpsに変更
B5 62 06 09 0D 00 FF FF 00 00 00 00 00 00 FF FF 00 00 17 2F AE

19200bpsに変更
B5 62 06 00 14 00 01 00 00 00 D0 08 00 00 00 4B 00 00 07 00 03 00 00 00 00 00 48 57

38400bpsに変更
B5 62 06 00 14 00 01 00 00 00 D0 08 00 00 00 96 00 00 07 00 03 00 00 00 00 00 93 90

57600bpsに変更
B5 62 06 00 14 00 01 00 00 00 D0 08 00 00 00 E1 00 00 07 00 03 00 00 00 00 00 DE C9

115200bpsに変更
B5 62 06 00 14 00 01 00 00 00 D0 08 00 00 00 C2 01 00 07 00 03 00 00 00 00 00 C0 7E

$ echo "UBXコマンド" | xxd -r -p > /dev/シリアルデバイス名
つまり、シリアルポートcuaU0に繋がっているGPSモジュールの通信速度(出力速度)を9600bpsに設定するなら
$ echo "B5 62 06 09 0D 00 FF FF 00 00 00 00 00 00 FF FF 00 00 17 2F AE" | xxd -r -p > /dev/cuaU0

NMEAセンテンスの出力停止・再開

NEMA DTM (Datum Reference)
停止: B5 62 06 01 03 00 F0 0A 00 04 23
再開: B5 62 06 01 03 00 F0 0A 01 05 24

NEMA GBS (GPS Satellite Fault Detection)
停止: B5 62 06 01 03 00 F0 09 00 03 21
再開: B5 62 06 01 03 00 F0 09 01 04 22

NEMA GGA (Global Positioning System Fix Data)
停止: B5 62 06 01 03 00 F0 00 00 FA 0F
再開: B5 62 06 01 03 00 F0 00 01 FB 10

NEMA GLL (Geographic Position - Latitude/Longitude)
停止: B5 62 06 01 03 00 F0 01 00 FB 11
再開: B5 62 06 01 03 00 F0 01 01 FC 12

NEMA GRS (GPS Range Residuals)
停止: B5 62 06 01 03 00 F0 06 00 00 1B
再開: B5 62 06 01 03 00 F0 06 01 01 1C

NEMA GSA (GPS DOP and active satellites)
停止: B5 62 06 01 03 00 F0 02 00 FC 13
再開: B5 62 06 01 03 00 F0 02 01 FD 14

NEMA GST (GPS Pseudorange Noise Statistics)
停止: B5 62 06 01 03 00 F0 07 00 01 1D
再開: B5 62 06 01 03 00 F0 07 01 02 1E

NEMA GSV (Satellites in view)
停止: B5 62 06 01 03 00 F0 03 00 FD 15
再開: B5 62 06 01 03 00 F0 03 01 FE 16

NEMA RMC (Recommended Minimum Navigation Information)
停止: B5 62 06 01 03 00 F0 04 00 FE 17
再開: B5 62 06 01 03 00 F0 04 01 FF 18

NEMA VTG (Track made good and Ground speed)
停止: B5 62 06 01 03 00 F0 05 00 FF 19
再開: B5 62 06 01 03 00 F0 05 01 00 1A

NEMA ZDA (Time & Date - UTC, day, month, year and local time zone)
停止: B5 62 06 01 03 00 F0 08 00 02 1F
再開: B5 62 06 01 03 00 F0 08 01 03 20


NEMA GNS
停止: B5 62 06 01 08 00 F0 0D 00 00 00 00 00 00 0C 7E
再開: B5 62 06 01 08 00 F0 0D 01 01 01 01 01 00 11 92

NEMA THS (True Heading and Status)
停止: B5 62 06 01 08 00 F0 0E 00 00 00 00 00 00 0D 85
再開: B5 62 06 01 08 00 F0 0E 01 01 01 01 01 00 12 99

NEMA VLW (Distance Traveled through Water)
停止: B5 62 06 01 08 00 F0 0F 00 00 00 00 00 00 0E 8C
再開: B5 62 06 01 08 00 F0 0F 01 01 01 01 01 00 13 A0

Linuxの多くに標準で入っているバックスラッシュでエスケープの-eオプション対応のechoコマンドが使えるなら以下のように送信。
$ sudo echo -e "UBXコマンド" > /dev/シリアルデバイス名
つまり、シリアルポートttyS1に繋がっているGPSモジュールのNMEA GSVセンテンスの出力を停止するなら
$ sudo echo -e "\xB5\x62\x06\x01\x03\x00\xF0\x03\x00\xFD\x15" > /dev/ttyS1
echo -e で送信する場合は一覧のコマンドの空白文字部分を\xに置き換える。
FreeBSD等で、バックスラッシュのエスケープが不可なechoを使うなら
% echo "UBXコマンド" | xxd -r -p > /dev/シリアルデバイス名

FreeBSDで、シリアルポートcuaU0に繋がっているGPSモジュールのNMEA GSVセンテンスの出力を停止するなら
% echo "B5 62 06 01 08 00 F0 03 00 00 00 00 00 00 02 38"  | xxd -r -p > /dev/cuaU0

実際にはなんのNMEAセンテンスが流れているか調べてから不要な種類の出力を停止する。
NTPサーバをntpdで動かしてNMEAをntpdで直接受け取って使用する場合、つまりリファレンスクロックドライバ127.127.20.xを使うならmodeで使用するセンテンスの種類を選択するので、RMC, GGA, GLL, ZDA/ZDGから選んで他は捨てる。普通はRMCを使うので他はすべて要らない。
gpsdを使う場合でもRMC(とVTG)以外は要らないんじゃないかしら。

シリアルポートを覗いて、流れているのがこんな感じとする。(u-bloxのUBX-G7020の例)
$GPTXT,01,01,02,u-blox ag - www.u-blox.com*50
$GPTXT,01,01,02,HW  UBX-G70xx   00070000 *77
$GPTXT,01,01,02,ROM CORE 1.00 (59842) Jun 27 2012 17:43:52*59
$GPTXT,01,01,02,PROTVER 14.00*1E
$GPTXT,01,01,02,ANTSUPERV=AC SD PDoS SR*20
$GPTXT,01,01,02,ANTSTATUS=OK*3B
$GPTXT,01,01,02,LLC FFFFFFFF-FFFFFFFD-FFFFFFFF-FFFFFFFF-FFFFFFFD*2E
$GPRMC,124330.00,A,3568.51751,N,13975.28000,E,0.019,,070720,,,A*71
$GPGGA,124330.00,3568.51751,N,13975.28000,E,1,07,0.84,113.9,M,34.9,M,,*58
$GPGSV,3,1,11,05,28,123,31,10,02,310,22,13,41,049,50,15,66,011,38*77
$GPGSV,3,2,11,18,48,270,,20,32,313,22,21,18,313,42,24,57,207,20*74
$GPGSV,3,3,11,28,14,059,36,42,48,165,,50,48,196,*40
$GPGLL,3568.51751,N,13975.28000,E,124330.00,A,A*62
$GPRMC,124331.00,A,3568.51751,N,13975.28000,E,0.013,,070720,,,A*77
$GPGGA,124331.00,3568.51751,N,13975.28000,E,1,07,0.84,114.0,M,34.9,M,,*5A
$GPGSV,3,1,11,05,28,123,30,10,02,310,21,13,41,049,50,15,66,011,37*7A
$GPGSV,3,2,11,18,48,270,,20,32,313,22,21,18,313,42,24,57,207,17*70
$GPGSV,3,3,11,28,14,059,36,42,48,165,,50,48,196,*40
$GPGLL,3568.51751,N,13975.28000,E,124331.00,A,A*6E
$GPRMC,124332.00,A,3568.51751,N,13975.28000,E,0.020,,070720,,,A*71
$GPGGA,124332.00,3568.51751,N,13975.28000,E,1,07,0.84,114.2,M,34.9,M,,*5E
$GPGSV,3,1,11,05,28,123,30,10,02,310,21,13,41,049,50,15,66,011,37*7A
$GPGSV,3,2,11,18,48,270,,20,32,313,22,21,18,313,42,24,57,207,16*71
$GPGSV,3,3,11,28,14,059,36,42,48,165,,50,48,196,*40
$GPGLL,3568.51751,N,13975.28000,E,124332.00,A,A*68
$GPRMC,124333.00,A,3568.51751,N,13975.28000,E,0.032,,070720,,,A*74
$GPGGA,124333.00,3568.51751,N,13975.28000,E,1,07,0.89,114.4,M,34.9,M,,*53
$GPGSV,3,1,11,05,28,123,30,10,02,310,20,13,41,049,49,15,66,011,38*7C
$GPGSV,3,2,11,18,48,270,,20,32,313,22,21,18,313,43,24,57,207,14*72
$GPGSV,3,3,11,28,14,059,36,42,48,165,,50,48,196,*40
$GPGLL,3568.51751,N,13975.28000,E,124333.00,A,A*6E
$GPRMC,124334.00,A,3568.51751,N,13975.28000,E,0.044,,070720,,,A*74
$GPGGA,124334.00,3568.51751,N,13975.28000,E,1,07,0.89,114.6,M,34.9,M,,*50
$GPGSV,3,1,11,05,28,123,30,10,02,310,20,13,41,049,49,15,66,011,38*7C
$GPGSV,3,2,11,18,48,270,,20,32,313,22,21,18,313,43,24,57,207,13*75
$GPGSV,3,3,11,28,14,059,36,42,48,165,,50,48,196,*40
$GPGLL,3568.51751,N,13975.28000,E,124334.00,A,A*6F
$GPRMC,124335.00,A,3568.51751,N,13975.28000,E,0.025,,070720,,,A*76
$GPGGA,124335.00,3568.51751,N,13975.28000,E,1,07,0.84,114.7,M,34.9,M,,*59
$GPGSV,3,1,11,05,28,123,30,10,02,310,20,13,41,049,49,15,66,011,38*7C
$GPGSV,3,2,11,18,48,270,,20,32,313,23,21,18,313,43,24,57,207,13*74
$GPGSV,3,3,11,28,14,059,36,42,48,165,,50,48,196,*40
$GPGLL,3568.51751,N,13975.28000,E,124335.00,A,A*6A
$GPRMC,124336.00,A,3568.51751,N,13975.28000,E,0.015,,070720,,,A*7F
$GPGGA,124336.00,3568.51751,N,13975.28000,E,1,07,0.84,114.8,M,34.9,M,,*5C
$GPGSV,3,1,11,05,28,123,30,10,02,310,19,13,41,049,49,15,66,011,38*76
$GPGSV,3,2,11,18,48,270,,20,32,313,22,21,18,313,43,24,57,207,13*75
RMC以外を停めるとこんな感じ。
$GPTXT,01,01,02,u-blox ag - www.u-blox.com*50
$GPTXT,01,01,02,HW  UBX-G70xx   00070000 *77
$GPTXT,01,01,02,ROM CORE 1.00 (59842) Jun 27 2012 17:43:52*59
$GPTXT,01,01,02,PROTVER 14.00*1E
$GPTXT,01,01,02,ANTSUPERV=AC SD PDoS SR*20
$GPTXT,01,01,02,ANTSTATUS=OK*3B
$GPTXT,01,01,02,LLC FFFFFFFF-FFFFFFFD-FFFFFFFF-FFFFFFFF-FFFFFFFD*2E
$GPRMC,124709.00,A,3568.51751,N,13975.28000,E,0.022,,070720,,,A*7E
$GPRMC,124710.00,A,3568.51751,N,13975.28000,E,0.003,,070720,,,A*76
$GPRMC,124711.00,A,3568.51751,N,13975.28000,E,0.012,,070720,,,A*7A
$GPRMC,124712.00,A,3568.51751,N,13975.28000,E,0.023,,070720,,,A*7F
$GPRMC,124713.00,A,3568.51751,N,13975.28000,E,0.013,,070720,,,A*75
$GPRMC,124714.00,A,3568.51751,N,13975.28000,E,0.018,,070720,,,A*7C
$GPRMC,124715.00,A,3568.51751,N,13975.28000,E,0.015,,070720,,,A*78
$GPRMC,124716.00,A,3568.51751,N,13975.28000,E,0.019,,070720,,,A*77
$GPRMC,124717.00,A,3568.51751,N,13975.28000,E,0.012,,070720,,,A*7E
$GPRMC,124718.00,A,3568.51751,N,13975.28000,E,0.021,,070720,,,A*77
$GPRMC,124719.00,A,3568.51751,N,13975.28000,E,0.003,,070720,,,A*77
$GPRMC,124720.00,A,3568.51751,N,13975.28000,E,0.008,,070720,,,A*76
$GPRMC,124721.00,A,3568.51751,N,13975.28000,E,0.015,,070720,,,A*7B
$GPRMC,124722.00,A,3568.51751,N,13975.28000,E,0.023,,070720,,,A*7B
$GPRMC,124723.00,A,3568.51751,N,13975.28000,E,0.016,,070720,,,A*7C
$GPRMC,124724.00,A,3568.51751,N,13975.28000,E,0.063,,070720,,,A*7D
$GPRMC,124725.00,A,3568.51751,N,13975.28000,E,0.013,,070720,,,A*79
$GPRMC,124726.00,A,3568.51751,N,13975.28000,E,0.028,,070720,,,A*77
$GPRMC,124727.00,A,3568.51751,N,13975.28000,E,0.030,,070720,,,A*70
$GPRMC,124728.00,A,3568.51751,N,13975.28000,E,0.035,,070720,,,A*7A
$GPRMC,124729.00,A,3568.51751,N,13975.28000,E,0.015,,070720,,,A*70
こんな感じでRMC以外の余計なセンテンスの出力が抑制される。(座標は弄ってる)

出力頻度の変更

シリアル速度を十分に早めて出力するセンテンスの種類を絞ったなら出力頻度を変える必要はないかもしれないが、シリアル速度を変更できない場合には出力頻度を3秒に1回程度〜10秒に1回程度にに落とした方が良いかもしれない。

1Hz (1秒に1回): B5 62 06 08 06 00 E8 03 01 00 01 00 01 39
5Hz (1秒に5回): B5 62 06 08 06 00 C8 00 01 00 01 00 DE 6A B5 62 06 08 00 00 0E 30
10Hz (1秒に10回): B5 62 06 08 06 00 64 00 01 00 01 00 7A 12 B5 62 06 08 00 00 0E 30
0.33Hz (3秒に1回): B5 62 06 08 06 00 B8 0B 01 00 01 00 D9 41 B5 62 06 08 00 00 0E 30
0.2Hz (5秒に1回): B5 62 06 08 06 00 88 13 01 00 01 00 B1 49 B5 62 06 08 00 00 0E 30
0.1Hz (10秒に1回): B5 62 06 08 06 00 10 27 01 00 01 00 4D DD B5 62 06 08 00 00 0E 30
0.05Hz (20秒に1回): B5 62 06 08 06 00 20 4E 01 00 01 00 84 00 B5 62 06 08 00 00 0E 30

コマンドの送り方は前述。

GPSモジュールの再起動・初期化

任意のタイミングでGPSモジュールを再起動させたいときに、場合によってはコールドスタートまたはウォームスタートさせたいということもある筈。

コールドスタート: B5 62 06 04 04 00 FF B9 02 00 C8 8F
ウォームスタート: B5 62 06 04 04 00 01 00 02 00 11 6C
工場出荷状態(初期化): B5 62 06 09 0D 00 FF FF 00 00 00 00 00 00 FF FF 00 00 07 1F 9E

この記事のUBXコマンドはu-bloxまたはその互換チップでないと機能しません。また、u-bloxまたはその互換チップであるからといって全てで機能するとは限りませんし一部が機能したりしなかったりするかもしれません。送信しようとしているチップに合ったコマンドをメーカーの提供している資料等で調べることをオススメします。

一応、中華なATGM332Dというラベルの貼られたu-blox互換チップではこのページのUBXコマンドは機能しています。

次回はNTPサーバの時刻の調整をやるかやらないか。

関連記事:

新しい中華GPSモジュールとChronyで作るNTPサーバ (中編)

前編では怪しい中華GPSモジュールを買っちゃったこととArmbian最新ソースからビルドしたPPS対応イメージについて書いた。一応今回が本題の内容になる。

構成

NMEA → gpsd → Chrony
1PPS → Chrony

Armbian(Debian, Ubuntu)の新しいバージョンではChronyは最初からシステムに入っている。オプション等を指定して自分でビルドする必要もなしでそのまま使える。

Chronyはネットワーク上の時刻ソースからの同期はとても簡単だが、ntpdと違ってNMEAなどのリファレンスクロックドライバは揃っていないようで、gpsd等の補助を必要とするみたい。gpsd以外で小型で単体のNMEA用ドライバのようなものが無いかと思ってググったけど見つけられなかった。
1PPSはChronyだけでもいけるっぽい。ググったところ、他の人はNMEAと1PPSの両方をgpsdに読ませて、Chronyではその2つをgpsdから貰うような設定が多いようだが、「がとらぼ」ではNMEAだけをgpsdに読ませてChronyに渡し、1PPSは直接Chronyに読ませることにする。どちらが精度が高いのかは不明。
ntpdではNMEAも1PPSもntpdで直接読める(それでもgpsdでNMEAを読ませる設定にしてる人が多い)ので「がとらぼ」で1PPSを使ったNTPサーバではgpsdなしで両方ntpdに読ませる設定でやっていた。余計なものは極力使いたくないのでgpsdはなしにしたいところだが、現在のChronyではできないっぽい(知らないだけ?)ので気に入らないが諦めてgpsdを使うことにする。

gpsdの設定

gpsdはArmbianのシステムには入っていないが、パッケージは用意されているのでそれを使うことにする。
$ sudo apt update                       #パッケージ情報を最新に更新
$ sudo apt install gpsd gpsd-clients    #パッケージインストール

gpsd-clientsは衛星の捕捉状況を表示したい等gpsd-clientsに入っているツールをどうしても使いたいということでなければ特には不要。

この記事では接続したGPSモジュールのシリアルポートが/dev/ttyS1とする。
シリアルポート名は使っているPC, シングルボードコンピュータ, OSで違うので実際にNMEAを受信できているポートを指定する。/devにあるttyで始まるデバイスで sudo cat /dev/ttyS0 などでNMEAセンテンスがズラズラ表示され続けるポートを見つければ良い。(Linuxのシリアルポート名にはttyS*みたいに大文字のSが付くみたい)

設定ファイルはArmbianのパッケージでインストールすると /etc/default/gpsd になるよう。この設定ファイルのpathは/lib/systemd/system/gpsd.serviceで指定されているので気に入らなければ変更。(要サービスの再有効可)

/etc/default/gpsd
1
2
3
4
5
START_DAEMON="true"
USBAUTO="false"
DEVICES="/dev/ttyS1"
GPS_BAUD=115200
GPSD_OPTIONS="-n"

この内、4行目は要注意。次回の記事で予定のGPSモジュールの設定変更を実施しなければ多くの安価なGPSモジュールは初期値が4800/9600bps程度なので115200bpsを指定するとおそらく通信できなくなる(gpsd側が通信できないだけでGPSモジュールやPC/シングルボードコンピュータが壊れるわけではない)。GPSモジュールの通信速度の初期値を指定するか4行目自体を無しにする方が良い。

1PPSをgpsdで受けたいのであれば2行目は DEVICES="/dev/ttyS1 /dev/pps0" のような指定になる。

gpsdサービスを起動する。
$ sudo systemctl enable gpsd.socket  (有効化されていなければ実行,おそらく不要)
$ sudo systemctl enable gpsd.service  (次が実行できなければ実行,おそらく不要)
$ sudo systemctl start gpsd.service
gpsdサービスを動かすにはgpsd.serviceとgpsd.socketの2つが要る。メインのサービスはgpsd.serviceだが元から起動・停止したいならgpsd.socket。 すでにサービスが動いているなら「start」の代わりに「restart」。
gpsdの起動ステータスを確認する。
$ sudo systemctl status gpsd.socket
● gpsd.socket - GPS (Global Positioning System) Daemon Sockets
   Loaded: loaded (/lib/systemd/system/gpsd.socket; enabled; vendor preset: enabled)
   Active: active (running) since Thu 2020-07-09 19:29:38 JST; 15h ago
   Listen: /var/run/gpsd.sock (Stream)
           [::1]:2947 (Stream)
           127.0.0.1:2947 (Stream)
    Tasks: 0 (limit: 851)
   Memory: 44.0K
   CGroup: /system.slice/gpsd.socket

Warning: Journal has been rotated since unit was started.

これはgpsd.serviceではダメでgpsd.socketを指定する。問題が発生していればこの後にエラー等が表示される筈。

gpsdでのGPS衛星の補足情報を確認したいならgpsmoncgps -sを使う。(要gpsd-clientsパッケージ)。まぁ、見る必要は無いんだけど。

Chronyの設定

最新のArmbian (Debian, Ubuntu)ではChronyはシステムに入っているし逆にntpdは入っていないのでChronyを設定するだけ。他のディストリビューションや古いArmbian(Debian, Ubuntu)では標準がntpdが動いていてChronyが入っていないのでChronyをインストールしてntpdを停める(アンインストールする)必要があるかもしれない。Chronyとntpdはコンフリクトするので同時使用はできない。

Chronyサービスの制御ファイルは/lib/system/system/chrony.serviceだが、/etc/systemd/system/chronyd.serviceからシンボリックリンクになっているのでサービス名としてはchrony.serviceとchronyd.serviceの2つがあることになる。実体は1つ。ややこしいのでこういうのはやめて欲しい。

Chronyの設定ファイルはパッケージでインストールすると /etc/chrony/chrony.conf になる。

/etc/chrony/chrony.conf (設定例)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
server ntp1.v6.mfeed.ad.jp prefer
server ntp2.v6.mfeed.ad.jp
server ntp3.v6.mfeed.ad.jp

keyfile /etc/chrony/chrony.keys
driftfile /var/lib/chrony/chrony.drift
logdir /var/log/chrony
log measurements statistics tracking refclocks
local stratum 1

allow 192.168.0.0/24

initstepslew 15 ntp1.v6.mfeed.ad.jp ntp2.v6.mfeed.ad.jp
maxupdateskew 100.0
rtcsync
makestep 1 3

#NMEA
refclock SHM 0 refid NMEA

#PPS
refclock PPS /dev/pps0  refid PPS trust

こんな感じ。ntpdと似た感じな設定に見えるが、ntpd用そのままではダメなのでドキュメントを参照しながらの設定になる筈。
このNTPサーバへの参照許可は192.168.0.0/24にしている。NMEA/PPSのoffset, delayの設定は入れていない。個体差があるので普通は暫く動かして統計情報を録った上で必要に応じて変更することになる筈。

設定行の後にコメントをつけるとChronyがエラーで起動しない。この書き方はntpdではエラーにならないので最初chronyが起動しない理由が判らなかった。

#これは問題ない
#comment
blah blah

#こんな書き方はエラーになる
blah blah   #comment
chronyは設定ファイルで指定した入出力ファイルが存在しないとエラーになるっぽい。(停まりはしない)
/var/lib/chrony/chrony.drift.tmp
/var/log/chrony/measurements.log
/var/log/chrony/statistics.log
/var/log/chrony/tracking.log
この辺りのファイルは存在とパーミッションを確認。

何のファイルを入出力するかは利用者それぞれだと思うけどdriftファイル辺りは設定する人が多いと思うのでファイルを作成してchronyが読み書きできるパーミッションに設定する。
最初、driftファイルと統計用に出力設定したファイルを用意し忘れてchronyのサービスを再起動するとNMEA, PPSの値が入らないなど何か変な挙動を示して意味がわからなかったけど、これが原因だった。chronyは標準で入ってるのでdriftファイルはあるものだと思い込んでたし統計用ファイルは設定で指定すれば自動的に作成されるものだと思いこんでいた。

$ sudo systemctl status chrony
● chrony.service - chrony, an NTP client/server
   Loaded: loaded (/lib/systemd/system/chrony.service; enabled; vendor preset: enabled)
   Active: active (running) since Thu 2020-07-09 19:31:13 JST; 3h 41min ago
     Docs: man:chronyd(8)
           man:chronyc(1)
           man:chrony.conf(5)
  Process: 1307 ExecStartPre=/bin/mkdir /tmp/chrony (code=exited, status=0/SUCCESS)
  Process: 1308 ExecStartPre=/bin/chown _chrony:_chrony /tmp/chrony (code=exited, status=0/SUCCESS)
  Process: 1309 ExecStartPre=/bin/chmod 600 /tmp/chrony (code=exited, status=0/SUCCESS)
  Process: 1310 ExecStart=/usr/sbin/chronyd $DAEMON_OPTS (code=exited, status=0/SUCCESS)
  Process: 1319 ExecStartPost=/usr/lib/chrony/chrony-helper update-daemon (code=exited, status=0/SUCCESS)
 Main PID: 1312 (chronyd)
    Tasks: 2 (limit: 851)
   Memory: 1.2M
   CGroup: /system.slice/chrony.service
           ├─1312 /usr/sbin/chronyd -F -1
           └─1313 /usr/sbin/chronyd -F -1

Jul 09 19:31:07 hoge chronyd[1312]: Loaded seccomp filter
Jul 09 19:31:11 hoge chronyd[1312]: Could not open log file /var/log/chrony/statistics.log
Jul 09 19:31:11 hoge chronyd[1312]: System's initial offset : 0.001967 seconds fast of true (slew)
Jul 09 19:31:13 hoge systemd[1]: Started chrony, an NTP client/server.
Jul 09 19:32:00 hoge chronyd[1312]: Selected source PPS
Jul 09 20:32:04 hoge chronyd[1312]: Could not open temporary driftfile /var/lib/chrony/chrony.drift.tmp for writing

chronyのサービスを起動してステータスを確認し、ファイルが開けないというエラーが発生していないことを確認する。上の例では黄字が指定されたファイルが開けないことを示している。

1
2
3
4
5
6
7
8
9
/var/log.hdd/chrony/*.log {
    compress
    missingok
    nocreate
    sharedscripts
    postrotate
        /usr/bin/chronyc cyclelogs > /dev/null 2>&1 || true
    endscript
}

Chronyのログローテーションの設定は自動で入っているが、そのログ用ディレクトリの想定が /var/log.hdd/chrony になっている。この記事では /var/log/chrony にログを置くことを想定しているので1行目の黄色字の「.hdd」部分を削除する。

$ sudo logrotate -dv /etc/logrotate.conf
$ service logrotate restart

1行目を実行してエラーが発生しないことを確認。意外とディレクトリのパーミッション等でエラーが出るので必要に応じて修正。
エラーが無いか修正したら2行目でログローテートのサービスを再起動。

ChronyのNTPサーバとしての稼働状況の確認

chronyc sources 時刻ソース別の状態 -vを付けると簡易説明付きになる -nを付けるとIPアドレスで表示
chronyc sourcestats 時刻ソース別の状況 -vを付けると簡易説明付きになる
chronyc activity 時刻ソースの種類別の状態
sudo chronyc clients このNTPサーバを参照しているホストの参照状況
sudo chronyc serverstats パケットやコマンドの送受信状況
chronyc -a 対話式で状態表示や一時的な設定変更を行う

chronycはいろいろできるけどよく使いそうな確認用の5種と対話式の1つを例として挙げた。この5つの内、clientsとserverstatsを表示するには権限が必要。ntpq -pの代わりのようにchronyc sourcesを使うことが多いかな。(ちょっと違うんだけど)

次回はGPSモジュールの設定を行う。調整はその後かな。

関連記事:
Up