折腾完InfluxDB,咱接着折腾 NTP,因为时序数据库对时间要求比较高,就想到了搭建个一级的NTP服务器,硬件自然还是接着蹂躏我的那块树莓派3B(活着真不容易2333~
参考了网上的很多文章,多是东拼西凑得来的,坑很多,最终还是决定再写一篇!
硬件准备
一张树莓派3B、一个GPS模块一个(带PPS输出),GPS天线、杜邦线、电源、TTL串口线。
测试GPS模块
在折腾之前,先测试你的GPS模块都一切正常,接上GPS天线,把模块放置到开阔空旷的空间方便GPS模块搜星定位,把模块TXD,RXD线接到USB转串口TTL模块上,先在Window系统中测试模块能够正常定位,别折腾到最后是GPS模块的问题,保证模块正常工作后再在树莓派上折腾。
树莓派安装系统
建议到树莓派官网上下载full版本的系统镜像安装,我起初安装了lite版本的镜像,在添加PPS的时候死活是注册不了PPS源到Linux内核,更换了系统之后正常了。
经反复验证,跟lite还是full版本的镜像无关,详见关于PPS的坑。树莓派官方的系统就OK了
线路连接
参考树莓派官网手册得到了树莓派的IO引脚定义
https://www.raspberrypi.org/documentation/usage/gpio/README.md
具体详细引脚定义可以在树莓派系统中执行pinout命令查看
[root@raspberrypi:~]# pinout
我的模块是5V的供电,按照下表连接线路
GPS模块 | 树莓派 |
VCC | (2)5V |
GND | (6)GND |
TXD |
(10)GPIO15 |
PPS | (12)GPIO18 |
GPIO15是树莓派串口的RXD接口,GPIO18则是树莓派pps-gpio默认的IO接口,后面会详细介绍。
设置树莓派串口
使用raspi-config工具启用串口并禁用通过串口登陆系统
[root@raspberrypi:~]# raspi-config
需要注意的是Raspberry-Pi 3相比于1和2在使用串口的时候会有问题,原因是树莓派CPU内部有两个串口,一个是硬件串口(官方称为PL011 UART),一个是迷你串口(官方成为mini-uart)。在树莓派2B/B+这些老版树莓派上,官方设计时都是将“硬件串口”分配给GPIO中的UART(GPIO14&GPIO15),因此可以独立调整串口的速率和模式。而树莓派3的设计上,官方在设计时将硬件串口分配给了新增的蓝牙模块上,而将一个没有时钟源,必须由内核提供时钟参考源的“迷你串口”分配给了GPIO的串口,这样以来由于内核的频率本身是变化的,就会导致“迷你串口”的速率不稳定,这样就出现了无法正常使用的情况。
需要在/boot/config.txt修改
enable_uart=0
至
enable_uart=1
然后添加
dtoverlay=pi3-miniuart-bt force_turbo=1
修改/boot/cmdline.txt
删除所有的console=xxx的语句,例如将
dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p7 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait
修改为
dwc_otg.lpm_enable=0 root=/dev/mmcblk0p7 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait
修改蓝牙服务,编辑/lib/systemd/system/hciuart.service
修改[Unit]中的After字段,由
After=dev-serial1.device
改成
After=dev-ttyS0.device
修改[Service]中的ExecStart字段,由
ExecStart=xxx(根据具体表示)
改成
ExecStart=/usr/lib/hciattach /dev/ttyS0 bcm43xx 460800 noflow -
注:其中的bcm43xx真的是xx哦
重启Raspberry Pi, 串口接下来可以用作通信
测试串口
在终端中用cat命令输出/dev/ttyAMA0的信息,可以看到GPS的相关信息
[root@raspberrypi:~]# cat /dev/ttyAMA0 $GPRMC,073811.00,A,2923.85607,N,10553.02783,E,0.352,,300419,,,A*7D $GPVTG,,T,,M,0.352,N,0.653,K,A*27 $GPGGA,073811.00,2923.85607,N,10553.02783,E,1,09,1.05,300.5,M,-27.0,M,,*79 $GPGSA,A,3,19,07,13,01,22,11,28,17,30,,,,1.68,1.05,1.32*0A $GPGSV,4,1,13,01,65,073,23,03,15,129,,04,04,206,09,07,46,181,38*7F $GPGSV,4,2,13,08,18,054,,11,56,041,17,13,07,294,31,17,35,269,39*72 $GPGSV,4,3,13,18,41,048,,19,14,254,22,22,20,107,16,28,46,329,19*79 $GPGSV,4,4,13,30,66,241,36*4A
安装gpsd后可以用gpsd查看GPS信息
root@raspberrypi:~# apt install gpsd gpsd-clients -y
用gpsmon查看GPS定位信息
root@raspberrypi:~# gpsmon /dev/ttyAMA0
可以看到
如果数据不正常,可以用minicom或者stty设置端口的波特率为9600 8n1之后再试。
设置PPS
在/boot/config.txt文件中添加
dtoverlay=pps-gpio,gpiopin=18
在/etc/modules文件中添加
pps-gpio
重启树莓派后可以在/dev下面应该能看到pps0这个设备
[root@raspberrypi:~]# ls /dev/pps0 /dev/pps0
lsmod | grep pps能看到pps_gpio和pps_core两个模块
[root@raspberrypi:~]# lsmod | grep pps pps_gpio 16384 0 pps_core 16384 2 pps_gpio
dmesg | grep pps应该能看到注册了PPS源相关字样
[root@raspberrypi:~]# dmesg | grep pps [ 1.966648] pps_core: LinuxPPS API ver. 1 registered [ 1.966657] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it> [ 1.981050] pps pps0: new PPS source pps@12.-1 [ 1.981139] pps pps0: Registered IRQ 169 as PPS source
至此,PPS驱动设置完成,安装pps-tools以对PPS源测试
[root@raspberrypi:~]# apt install pps-tools -y
使用ppstest对pps0进行测试
[root@raspberrypi:~]# 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 1556611258.100036986, sequence: 13093 - clear 0.000000000, sequence: 0 source 0 - assert 1556611259.100037438, sequence: 13094 - clear 0.000000000, sequence: 0 source 0 - assert 1556611260.100037681, sequence: 13095 - clear 0.000000000, sequence: 0
每一秒输出一条,如果发现输出间隔不是1s,可能是连线错误或者gps模块未设置导致。
关于PPS的坑
树莓派因为没有BIOS,所以Raspbian对设备的加载都是依赖在/boot/config.txt中的配置来加载。当Linux内核加载时,会读取/boot/config.txt中的设备配置和设备参数配置来把设备动态加载到Device Tree(DT)中。所以是在/boot/config.txt文件中添加dtoverlay=pps-gpio,gpiopin=18而不是在/boot/cmdline.txt中添加,我所搜索到的文章 https://blog.csdn.net/xiaohu50/article/details/78731534 中有错误,致使我在/boot/cmdline.txt中添加了dtoverlay=pps-gpio,gpiopin=18,导致系统能够正常加载mod但是无法注册pps源,也就是dmesg中只能看到
[root@raspberrypi:~]# dmesg | grep pps [ 1.966648] pps_core: LinuxPPS API ver. 1 registered [ 1.966657] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
而没有显示
[ 1.981050] pps pps0: new PPS source pps@12.-1 [ 1.981139] pps pps0: Registered IRQ 169 as PPS source
最终查阅了树莓派设备树的相关资料才发现https://blog.csdn.net/xiaohu50/article/details/78731534 这篇文章有错误,应该将dtoverlay=pps-gpio,gpiopin=18添加到/boot/config.txt而不是添加到/boot/cmdline.txt中。非常感谢https://www.jianshu.com/p/80e713f91285 这篇文章。
安装NTP
系统自带的ntpd是阉割版的ntpd,不支持PPS,甚至有的系统都没有安装ntpd,所以需要到ntp官网下载ntp源码自行编译安装。
先卸载
[root@raspberrypi:~]# service ntp stop [root@raspberrypi:~]# apt remove ntp
先安装编译所依赖的libcap-dev库:
[root@raspberrypi:~]# apt install libcap-dev -y
到 http://archive.ntp.org 下载最新的ntp源码到树莓派上
[root@raspberrypi:~]# wget http://archive.ntp.org/ntp4/ntp-4.2.8p13.tar.gz
解压配置编译安装
[root@raspberrypi:~]# tar xzf ntp-4.2.8p13.tar.gz [root@raspberrypi:~]# cd ntp-4.2.8p13/ [root@raspberrypi:~/ntp-4.2.8p13]# ./configure --enable-linuxcaps [root@raspberrypi:~/ntp-4.2.8p13]# make [root@raspberrypi:~/ntp-4.2.8p13]# make install [root@raspberrypi:~/ntp-4.2.8p13]# cp /usr/local/bin/ntp* /usr/bin/ [root@raspberrypi:~/ntp-4.2.8p13]# cp /usr/local/sbin/ntp* /usr/sbin/ [root@raspberrypi:~/ntp-4.2.8p13]# service ntp start
配置NTPd从GPS获取时间
编辑/etc/ntp.conf添加NMEA
# NMEA refclock driver directly from serial port server 127.127.20.1 mode 16 minpoll 4 iburst prefer true fudge 127.127.20.1 flag1 1 flag2 0 flag3 0 flag4 0 time1 0.1 refid GPS
server, fudge的配置说明请参看man ntp.conf。这里的127.127.t.u并不是真实的ip地址,而是Reference clock,根据t来指定实际类型,根据u来指定设备。t对应的实际设备需要看文档,在源代码目录ntp/html/drivers/driverxx.html中也有。参考 driver20.html可知,若要从GPS设备中获取时间,需要将t写为20,也就是127.127.20.u,u为设备号,也就是/dev/gps0,/dev/gps1等类似于/dev/gpsu设备,通过创建GPS的串口的软连接可以得到/dev/gpsu,
我将我的串口/dev/ttyAMA0软连接到/dev/gps1,所以server的地址就应当是127.127.20.1
[root@raspberrypi:~]# ln -s /dev/ttyAMA0 /dev/gps1
driver20.html中提到:
Address: 127.127.20.u
Reference ID: GPS
Driver ID: GPS_NMEA
Serial Port: /dev/gpsu; 4800 - 115200 bps, 8-bits, no parity
Serial Port: /dev/gpsppsu; for just the PPS signal (this is tried first for PPS, before /dev/gpsu)
也就是不仅有/dev/gpsu,还要有/dev/gpsppsu,也就是GPS中的PPS,同样,通过创建软连接得到
[root@raspberrypi:~]# ln -s /dev/pps0 /dev/gpspps1
有的文章中有提到再添加一个单独的PPS设备的,其实没有必要的,因为GPS中的PPS信号已经通过driver20中的/dev/gpsppsu传入NTPd了,不需要再添加PPS Driver(driver22)(172.172.22.u)
配置完成后重启ntp
[root@raspberrypi:~]# service ntp restart
测试NTP
NTP重启后稍等几分钟后执行ntpq -crv -p应该可以看到以下信息:
[root@raspberrypi:~]# ntpq -crv -p associd=0 status=0415 leap_none, sync_uhf_radio, 1 event, clock_sync, version="ntpd 4.2.8p13@1.3847 Tue Apr 30 03:35:42 UTC 2019 (1)", processor="armv7l", system="Linux/4.14.79-v7+", leap=00, stratum=1, precision=-20, rootdelay=0.000, rootdisp=1.060, refid=GPS, reftime=e0726e8f.ba9ef0c1 Tue, Apr 30 2019 14:49:51.728, clock=e0726e94.81d1fa5b Tue, Apr 30 2019 14:49:56.507, peer=6494, tc=4, mintc=3, offset=-0.000261, frequency=2.297, sys_jitter=0.000954, clk_jitter=0.001, clk_wander=0.000 remote refid st t when poll reach delay offset jitter ============================================================================== 0.pool.ntp.org .POOL. 16 p - 64 0 0.000 0.000 0.001 oGPS_NMEA(1) .GPS. 0 l 5 16 377 0.000 0.000 0.001 *203.107.6.88 10.137.38.86 2 u 33 64 377 44.138 -94.476 0.093 -45.43.30.59 (st 216.218.254.202 2 u 175 64 304 219.931 -98.853 1.722 -sv1.ggsrv.de 205.46.178.169 2 u 32 64 277 239.642 -98.971 2.007 +167.99.110.109 64.62.153.210 3 u 36 64 137 194.662 -98.467 0.349 -ntp.wdc1.us.lea 130.133.1.10 2 u 40 64 123 248.103 -94.458 0.758 -ntp6.flashdance 192.36.143.150 2 u 29 64 377 353.068 -91.349 12.499 -electrode.felix 56.1.129.236 3 u 35 64 375 236.587 -90.245 1.789 +119.28.183.184 100.122.36.4 2 u 24 64 377 50.639 -87.102 6.290
表中第一个字符(统计代码)是状态标识(参见 Peer Status Word),包含 " ","x","-","#","+","*","o":
" " – 无状态,表示:
没有远程通信的主机
"LOCAL" 即本机
(未被使用的)高层级服务器
远程主机使用的这台机器作为同步服务器
"x" – 已不再使用
"-" – 已不再使用
"#" – 良好的远程节点或服务器但是未被使用 (不在按同步距离排序的前六个节点中,作为备用节点使用)
"+" – 良好的且优先使用的远程节点或服务器(包含在组合算法中)
"*" – 当前作为优先主同步对象的远程节点或服务器
"o" – PPS 节点 (当优先节点是有效时)。实际的系统同步是源于秒脉冲信号(pulse-per-second,PPS),可能通过PPS 时钟驱动或者通过内核接口。
在同网段的Linux机器中使用ntpdate -d ip来测试NTP服务器是否正常授时
[root@linux ~]# ntpdate -d 10.60.60.100 30 Apr 14:48:21 ntpdate[24028]: ntpdate 4.2.6p5@1.2349-o Fri Apr 13 12:52:28 UTC 2018 (1) Looking for host 10.60.60.100 and service ntp host found : 10.60.60.100 transmit(10.60.60.100) receive(10.60.60.100) transmit(10.60.60.100) receive(10.60.60.100) transmit(10.60.60.100) receive(10.60.60.100) transmit(10.60.60.100) receive(10.60.60.100) server 10.60.60.100, port 123 stratum 1, precision -20, leap 00, trust 000 refid [GPS], delay 0.02611, dispersion 0.00003 transmitted 4, in filter 4 reference time: e0726e3f.ba9ed2b5 Tue, Apr 30 2019 14:48:31.728 originate timestamp: e0726e3f.cfb24bac Tue, Apr 30 2019 14:48:31.811 transmit timestamp: e0726e3c.1aa8c4c5 Tue, Apr 30 2019 14:48:28.104 filter delay: 0.02612 0.02611 0.02629 0.02615 0.00000 0.00000 0.00000 0.00000 filter offset: 3.706743 3.706803 3.706777 3.706823 0.000000 0.000000 0.000000 0.000000 delay 0.02611, dispersion 0.00003 offset 3.706803 30 Apr 14:48:28 ntpdate[24028]: step time server 10.60.60.100 offset 3.706803 sec [root@linux ~]#
可以看到NTP服务器已经使用了GPS作为时间源给Client授时。
参考博文
https://blog.csdn.net/xiaohu50/article/details/78731534
https://blog.csdn.net/qishi_blog/article/details/52843696
https://www.jianshu.com/p/80e713f91285
-
« 上一篇:
Linux下的N种作死方法【2】ls也能原地爆炸
-
Linux下的N种作死方法【3】mv ==rm ??
:下一篇 »