当前位置: 首页 > 工具软件 > ATOM-Gitee > 使用案例 >

linux gpsd 授时原理,app/ntp/gps/README.md · 王者归来/ITTS - Gitee.com

向弘懿
2023-12-01

## [原创] 用GPS模块建立高精度ntp服务器

本文原创:**中国科学技术大学 张焕杰**

修改时间:2019.02.26

# 零、高精度时间的定义

简单的说,衡量时间主要有2个参数,分别是offset和jitter。offset可以理解为与标准时间的偏差,jitter可以理解为时间均匀度。

比如一个石英钟,每天对比与CCTV新闻联播时间一致,可以认为jitter为0,但offset并不一定为0,因为电视信号传播需要时间。

理想的ntp服务器,offset和jitter都为0。

对于现实的计算机,我们希望:

* 时间单向增加,也就是不会发生往回调表的情况。

* 时间均匀增加,也就是不会忽快忽慢,即上面描述的jitter尽量接近0。

* 与标准时间偏差尽量少,即上面描述的offset尽量接近0。

使用GPS模块授时的ntp服务器,据称offset可以到10µs(即0.01ms,大约相当于光或电波传播3km的时间)左右,jitter与服务器晶振和环境温度有关,一般可以到10µs以下(即0.01ms)。

# 一、GPS授时简单原理

GPS卫星有精密时钟源,GPS模块依靠接收到信号时间差来计算位置,同时可以通过以下两种方式对外输出时间信息:

一是通过串口输出NMEA语句,如下的北斗格式(GPS格式,前面是$GPRMC)输出:

```

$GNRMC,015022.00,A,3150.59184,N,11716.04078,E,0.242,,260219,,,D,V*12

```

其中的015022是时间01:50:22(UTC时间,对应的北京时间是09:50:22),260219是2019年2月26日。

这种输出,由于串口工作在9600BPS速率,误差比较大。

二是通过引脚 1PPS,信号的上升沿表示每秒钟的开始。1PPS信号的精度比较高,在10-30ns。

结合以上两种方式,可以从GPS模块得到高精度的时钟信号。

# 二、GPS模块/接收器的选择

如果是连接PC机使用,建议选择RS232信号电平的模块,如果连接树莓派机器使用,可以使用TTL信号电平的模块。

绝大部分GPS模块,引出了电源、地、RX、TX四根线,而并未将1PPS信号引出。用作ntp时,购买时让商家断开RX信号,引出1PPS信号。

我从taobao 深圳北天通讯 购买的 GPS/北斗双模BS-70DU接收器,其中USB口用来给模块供电,RS232口用来通信。

特别注意:购买时与店主沟通,让店主断开RX信号,将1PPS信号连接到DB9的1口,即DCD信号。

模块外形如下:

![BS-70DU](bs-70du.png)

后来,我又从taobao 北京GPS北斗专业店 购买了 M8N 双频10HZ输出 RS232接口 USB供电MH16-N1 北斗GPS,购买时与店主沟通,要求

1PPS信号接rs 232的1脚(dcd)。

模块外形如下:

![M8N](m8n.jpg)

# 三、服务器的安装

本来计划使用atom处理的小盒子做ntp服务器,测试时发现无法成功,可能与atom处理的CPU自动降频有关。后来找了一台比较老的服务器,顺利完成。

## 3.1 安装OS和软件

使用的是CentOS 7,安装系统后,运行以下命令安装需要的软件:

```

yum install -y epel-release

yum install -y ntp pps-tools gpsd gpsd-clients

```

## 3.2 gpsd设置

gpsd是用来读取GPS模块信息,并将信息放到一段共享内存,供ntpd之类的其他应用使用。

编辑 `/etc/sysconfig/gpsd`,修改为(GPS模块232口接在COM1,也就是ttysS0)

```

# Options for gpsd, including serial devices

OPTIONS="-n /dev/ttyS0"

# Set to 'true' to add USB devices automatically via udev

USBAUTO="true"

```

设置gpsd启动:

```

systemctl start gpsd

systemctl enable gpsd

```

这时执行`cgps`或`gpsmon`可以看到信息,分别如下图所示,其中有位置信息、PPS信息,说明GPS模块工作正常:

![CGPS](cgps.png)

![gpsmon](gpsmon.png)

## 3.3 ntpd设置

CentOS 7默认的是chronyd,我还是使用相对熟悉的ntpd。

编辑文件`/etc/ntp.conf`,增加如下内容:

```

server 127.127.28.0 minpoll 4 maxpoll 4

fudge 127.127.28.0 refid GPS

server 127.127.28.1 minpoll 4 max poll 4 prefer

fudge 127.127.28.1 refid PPS

```

这里的127.127.28.0和127.127.28.1是虚拟设备,含义是获取gpsd放到共享内存中的信息来对时。

设置ntpd启动,并放开防火墙:

```

systemctl stop chronyd

systemctl disable chronyd

systemctl start ntpd

systemctl enable ntpd

firewall-cmd --add-service=ntp --permanent

firewall-cmd --reload

```

如果执行这些命令时,系统的时间大致正确,过10来分钟,执行`ntpstat`看到如下输出,说明工作正常:

```

synchronised to UHF radio at stratum 1

time correct to within 1 ms

polling server every 64 s

```

执行命令`ntpq -p`可以看到ntpd的工作状态:

```

# ntpq -p

remote refid st t when poll reach delay offset jitter

==============================================================================

+static-5-103-13 .GPS. 1 u 43 64 377 425.213 -51.480 1.376

-biisoni.miuku.n 207.224.49.219 2 u 58 64 377 247.198 -16.032 11.992

x2001:1af8:4700: 130.133.1.10 2 u 43 64 377 318.917 5.976 1.928

+SHM(0) .GPS. 0 l 9 16 377 0.000 -109.06 7.257

*SHM(1) .PPS. 0 l 9 16 377 0.000 0.002 0.001

```

这里显示服务器时钟与 PPS 信号的offset是0.002ms(即2us),jitter是0.001ms(即1us)。

而GPS NMEA信号,因为RS232串口传输慢,要慢109.06ms(大约0.1s)。GNRMC消息大约70个字节长,每个字节前有开始bit,后有结束bit,

传输70字节的消息需要 70*(2+8)/9600=0.073 秒。

此时,从其他计算机执行`ntpdate ntp服务器IP地址`,可以完成对时操作。

使用ntpdate对时,可能会引起时钟往前跳变。因此,重要的服务器建议直接用ntp同步对时。

如果允许其他服务器想使用带有gps模块的ntp服务器进行同步,则需要在ntp.conf中增加(其中c.c.c.c是其他ntp服务器的IP地址)

```

restrict c.c.c.c nomodify notrap

```

在其他服务器的 ntp.conf 中增加(其中s.s.s.s是其他带有GPS模块的ntp服务器IP地址)

```

server s.s.s.s minpoll 3 maxpoll 3 prefer

```

注意:有些版本的服务器minpoll和maxpoll最小允许为4,即16秒查询一次。ntpq -p 可以看到。如果设置为3或4,ntp对时后,offset可以到20us以下。

# 四、服务器运行状态监控

如果想监视ntp服务器的运行状况,可以参考 https://www.satsignal.eu/ntp/NTPandMRTG.html

下面是我参考网页的做法:

```

yum install mrtg httpd

```

vi `/etc/mrtg/ntp.cfg`,输入以下内容:

```

HtmlDir: /var/www/mrtg

ImageDir: /var/www/mrtg

LogDir: /var/lib/mrtg

Target[ntp]: `perl /etc/mrtg/GetNTPoffset.pl 127.0.0.1`

MaxBytes[ntp]: 100000

Title[ntp]: NTP statistics - offset from UTC

Options[ntp]: integer, gauge, nopercent, growright

Colours[ntp]: BLUE#0033FF, RED#FF0000, BLUE#0033FF, RED#FF0000,

YLegend[ntp]: offset +/- us

ShortLegend[ntp]: µs

LegendI[ntp]: offset µs (-): 

LegendO[ntp]: offset µs (+): 

Legend1[ntp]: Time offset in µs (-)

Legend2[ntp]: Time offset in µs (+)

PageTop[ntp]:

NTP server

```

vi `/etc/mrtg/GetNTPoffset.pl`,输入以下内容:

```

# Expects node name as a parameter

# Returns 1st value for positive offsets, second value for negative

# Returns microseconds of offset

$ntp_str = `/usr/sbin/ntpq -c rv $ARGV[0]`; # execute "ntpq -c rv "

$val = (split(/\,/,$ntp_str))[20]; # get the offset string

$val =~ s/offset=//i; # remove the "offset="

$val = int (1000 * $val); # convert to microseconds

$nval = $val; # prepare the negative value

if ($val < 0){

$nval = -$nval; # make the value positive

$val = 0; # ensure zero return for the positive

} else {

$nval = 0; # ensure zero return for the negative

}

print "$nval\n"; # return four numbers, incoming

print "$val\n"; # outgoing

print "0\n";

print "$ARGV[0]\n";

```

执行`crontab -e`,增加一行

```

*/5 * * * * env LANG=C /usr/bin/mrtg /etc/mrtg/ntp.conf

```

`vi /etc/httpd/conf.d/mrtg.conf`,放开访问权限。

执行以下命令,启动httpd:

```

systemctl start httpd

systemctl enable httpd

firewall-cmd --add-service=http --permanent

firewall-cmd --reload

```

然后访问 http://x.x.x.x/mrtg/ntp.html 就能看到 offset 的变化情况了。

参考资料:

* http://www.catb.org/gpsd/gpsd-time-service-howto.html

* https://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html

* https://pthree.org/2013/11/05/real-life-ntp/

***

欢迎 [加入我们整理资料](https://github.com/bg6cq/ITTS)

一键复制

编辑

Web IDE

原始数据

按行查看

历史

 类似资料: