弹霄博科

小谈谈一亩三分地



用 RaspberryPi 与 GPS 构建 NTP 服务器


发布日期: 2018/04/07
更新日期: 2021/02/13
作者: 小谈谈
分类: 笔记
标签: ntpserver, raspberrypi
阅读时间: 7 分钟
字数: 1702 字


NTP 服务器 Network Time Protocol(NTP)是用来使计算机时间同步化的一种协议,它可以使计算机对其服务器或时钟源(如石英钟,GPS 等等)做同步化,它可以提供高精准度的时间校正(LAN 上与标准间差小于 1 毫秒,WAN 上几十毫秒),且可介由加密确认的方式来防止恶毒的协议攻击。时间按 NTP 服务器的等级传播。按照离外部 UTC 源的远近把所有服务器归入不同的 Stratum(层)中。

本文将介绍如何使用 RaspberryPi 和 GPS 模块构建一个 NTP 服务器,精度在 100 毫秒以内,基本满足一般业务对时需求和一些无法使用公网环境的授时需要。

GPS 模块的准备

硬件选择

我购买的是正点原子的 GPS+ 北斗双定位模块 S1216,其内核为 SkyTra 的 S1216F8-BD 芯片。支持串口和 PPS,宽供电 3.3V-5V,20Hz 更新速度,支持 IPX 天线,板载电池热启动速度极快。

选择 GPS 模块的几点要求,必须支持串口和 PPS,这是授时所必须的。另外也十分建议板载电池,这有助于在热启动时有更快的定位和获取时间的速度。板载天线接口,可扩展天线。

[图片: BD-GPS]
https://static.txisfine.cn/upload/20180407202848.png/pkwatermark

软件调整

正点原子 GPS+ 北斗双定位模块 S1216 开发工具包

推荐使用 GNSS 将模块的通信速度调整为 9600,关闭北斗频点(因为软件无法识别 BDNMEA 语句)

Raspberry Pi 的准备

特别鸣谢 BH8TWO 送的 RaspberryPi

连接线

| Raspberry Pi | GPS | | ------------ | --- | | GND | GND | | 5V | VCC | | TXD | RXD | | RXD | TXD | | GPIO 18 | PPS |

关于树莓派的 GPIO 定义,请参见 RaspberryPi 英文 WiKi

刷写系统

最小需要一个 8G 的 SD 卡,使用 NOOBS 安装系统,并做一些基础性的配置,例如 Root 密码、启用 SSH 远程登录、启用 GPIO 接口。

配置国内软件源

修改后的 /etc/apt/sources.list

#deb http://mirrordirector.raspbian.org/raspbian/ jessie main contrib non-free rpi # Uncomment line below then 'apt-get update' to enable 'apt-get source' #deb-src http://archive.raspbian.org/raspbian/ jessie main contrib non-free rpi

# use ustc mirror: deb http://mirrors.ustc.edu.cn/raspbian/raspbian/ jessie main contrib non-free rpi

修改后的 /etc/apt/sources.d/raspi.list

#deb http://archive.raspberrypi.org/debian/ jessie main ui # Uncomment line below then 'apt-get update' to enable 'apt-get source' #deb-src http://archive.raspberrypi.org/debian/ jessie main ui

# use ustc mirror: deb http://mirrors.ustc.edu.cn/archive.raspberrypi.org/debian/ jessie main ui

启用串口并禁用串口登录

sudo raspi-config

找到 Serial 选项,enable Serial,disable Serial Login。(博主记:因为当时没用保存截图,这里可能与实际情况又出入,你可以仔细找找类似的选项)

更新 RaspberryPi

sudo apt-get update sudo apt-get dist-upgrade sudo rpi-update sudo reboot

检查串口

连接好 GPS 模块和 RaspberryPi 之后,使用 cat /dev/ttyAMA0 检查串口

串口输入如下数据系正常

$GPGSA,A,3,02,04,12,25,24,05,10,,,,,,02.4,01.1,02.107 $GPGLL,2834.2631,N,07720.5426,E,102954.00,A,A6E $GPGSV,3,1,07,02,71,345,50,04,40,038,48,12,62,315,47,25,20,321,457F $GPGSV,3,2,07,05,41,167,23,10,48,086,23,24,24,236,30,,,,48 $GPGSV,3,3,07,,,,,,,,,,,,,,,,*7E

安装 PPS-tools

sudo apt-get install pps-tools sudo apt-get install libcap-dev

配置 PPS-tools

使用 sudo nano /boot/config.txt 修改文件,在文件的最后加入如下内容保存退出

dtoverlay=pps-gpio,gpiopin=18

使用 sudo vim /etc/modules 修改文件,在文件的最后加入如下内容保存并退出

pps-gpio

配置完毕重启生效

验证 PPS 是否工作

使用 lsmod | grep pps 验证模块是否正常加载

若输出如下信息系正常

ppsgpio 2555 0 ppscore 7092 1 ppsgpio

使用 dmesg | grep pps 命令检查 PPS GPIO 是否被配置

若输出如下信息系正常

[图片: 图片]
https://static.txisfine.cn/upload/20180407202850.png/pkwatermark

使用 sudo ppstest /dev/pps0 将会看到类似下面的输出

trying PPS source "/dev/pps0" found PPS source "/dev/pps0" ok, found 1 source(s), now start fetching data... source 0 - assert 1421066632.974111422, sequence: 1698 - clear 0.000000000, sequence: 0 source 0 - assert 1421066633.974045488, sequence: 1699 - clear 0.000000000, sequence: 0

正常情况下每一秒输出一条,如果发现输出间隔不是一秒,可能是连线错误或者 GPS 模块未设置导致的

配置 NTP 服务

有两个方案可以实现 NTP 服务,ntpd 和 chrony。但是 RaspberryPi 源中的 ntpd 是一个阉割的版本,里面不含 PPS 支持,所以如果你执意想使用 ntpd 的话,需要从源码编译,很不幸的是,博主编译了 n 次(n∈【1,6】)都没用成功,故我使用了 chrony。

chrony 的优点有: 同步更快,只需要几分钟收敛到最小误差,而 ntpd 可能需要几个小时。 对变频环境有优化。 对于断线和延迟有更好的优化。 chrony 的缺点(可以弥补): 仅支持 PPS,对于 GPS 的串口连接的 NMEA 语句没有支持,但可以通过 gpsd 的共享内存的方式来获取。

另外说一句 ntpd 和 chrony 冲突,请二者选其一。

安装 GPSD

sudo apt install gpsd gpsd-clients python-gps

修改 /etc/default/gpsd 文件如下

DEVICES="/dev/ttyAMA0" GPSDOPTIONS="-n -G"

配置 GPSD 开机启动

太简单了,不再赘述

检查 GPSD

使用 gpsd -s 来查看 GPSD 的数据,如果你在开阔的地方,你将会看到类似下面的输出

[图片: 图片]
https://static.txisfine.cn/upload/20180407202852.png/pk
watermark

安装 chrony

chrony 官网 了解一下?

直接 apt 安装就好了,没这么麻烦

sudo apt install chrony

修改配置文件 /etc/chrony/chrony.conf 确保有以下内容(如果没有则添加)

leapsectz right/UTC makestep 1.0 -1 rtcsync

refclock PPS /dev/pps0 lock GPSD prefer refid PPS refclock SHM 0 offset 0.0 delay 0.2 refid GPSD

allow

解释一下 chrony.conf 配置文档,其中 :

makestep 1.0 -1表示超过1秒立刻修正,不回归 rtcsync每11分钟自动矫正系统rtc时钟 注意这里的 delay 的大小,delay 代表信号源往返信号的时间预估,其值的一半会作为信号的误差,且不同的信号源的范围需要 overlay。 如 pps 的 delay 和 offset 都很小,接近0,而 gpsd 的 offset 如果在100ms左右,这个时候就需要设置 delay 大于0.2(两倍100ms,我会设置0.3)。 否则的话,通过 chronyc sources -v 会看到型号元前面是 time may be error 的标志。 allow 允许局域网所有设备使用本服务器时间

配置完成后通过 sudo service chrony restart 重启服务

可以通过下面两个命令来查看连接状态

watch -n1 chronyc sources -v watch -n1 chronyc sourcestats -v

尽情使用吧

精度说明

经过测试,基本精度在 60ms 左右,最好能到 10ms,基本够非精密业务授时使用,例如,我是给我们广播服务器授时用的。

特别鸣谢与参考资料

感谢 BH8TWO 送的 RaspberryPi

[图片: 图片]
https://static.txisfine.cn/upload/20180407224941.jpg/pkwatermark

感谢 汽车工程学院 3D 打印社团 设计的 树莓派外壳

[图片: 图片]
https://static.txisfine.cn/upload/20180407224927.jpg/pkwatermark

参考资料:

https://blog.csdn.net/xiaohu50/article/details/78731534

https://blog.csdn.net/qishi_blog/article/details/52843696

https://area-51.blog/2012/06/18/getting-gps-to-work-on-a-raspberry-pi/

等等在 Google 上搜到的资料……