嵌入式设备时间同步(gpsd pps chrony 校时)

二、时间同步方案

时间同步包含哪些内容?

时间同步可分为几部分的内容:统一时钟源硬件同步软件同步

1. 统一时钟源

1.1 PPS + NMEA

GPS能够从卫星获得高精度的时钟信号,因此通常作为整个系统的时钟源。常规的GPS单元都支持输出精确到毫秒的秒脉冲信号PPS和包含年月日时分秒信息的NMEA指令,通过PPS和NMEA的组合就能够实现对激光雷达或主机的毫秒级时钟同步。
PPS+NMEA的优点是协议简单,容易实现;缺点是必须基于RS232。多个设备之间实现同步比较困难。

1.2 PTP(IEEE 1588或IEEE 802.1AS)

PTP(Precision Time Protocol,1588 V2)是基于以太网的高精度时钟同步协议,能够实现以太网中多个从节点(各种传感器)与主节点(主机)之间的亚微秒级时钟同步,前提是所有节点之间都通过以太网互联,交换机支持PTP协议,并且每个节点都支持PTP协议。

与PTP同时出现的还有一种NTP,即网络时间协议,不同的是PTP是在硬件级实现的,NTP是在应用层级别实现的 。

2. 硬件同步

3. 软件同步

在这里插入图片描述

三、chrony 介绍和使用

3.1 chrony 介绍

chrony是网络时间协议(NTP)的通用实现。它可以将系统时钟与NTP服务器、参考时钟(如GPS接收器)以及使用手表和键盘的手动输入同步。它还可以作为NTPv4(RFC 5905)服务器和对等端操作,为网络中的其他计算机提供时间服务。

通过互联网同步的两台机器之间的典型精度在几毫秒内;在局域网上,精度通常为几十微秒。通过硬件时间戳或硬件参考时钟,亚微秒精度可能是可能的。

chrony中包含两个程序,chronyd是一个可以在启动时启动的守护进程,chronyc是一个命令行界面程序,可以用来监视chronyd的性能,并在其运行时更改各种操作参数。

chrony支持的功能

  • NTP校时:作为ntp client向ntp server进行校时。
  • PPS(脉冲秒信号)校时:通过连接GPS接收器或其他高精度时钟设备来获取脉冲秒信号。
  • RTC(实时时钟)校时:Chrony可以通过与计算机上的实时时钟设备进行通信,将计算机的时钟与实时时钟进行同步。
  • NMEA 校时:通过与NMEA设备(如GPS接收器)通信,获取到NMEA数据,并将其用于校正计算机时钟。
  • 作为校时服务器:给其他设备校时。

注意:实际使用时根据chrony版本查阅帮助文档,这里使用的版本是chrony 2.4。

3.2 chrony 使用示例

使用步骤:

  1. 配置好chrony.conf文件
  2. 启动chronyd
  3. 选择性设置添加自启动
  4. chronyc查看状态信息

示例1:ntp 客户端

server ntp1.aliyun.com trust minpoll 2 maxpoll 4 polltarget 30
server 10.234.111.138 trust minpoll 2 maxpoll 4 polltarget 30
makestep 0.1 -1
driftfile /var/lib/chrony/drift
rtcsync

示例1:gps校时,同时作为ntp服务器端给其他设备校时

# gpsd and pps
refclock SHM 0 poll -2 refid GPS precision 1e-1 offset 0.9999 delay 0.2
refclock PPS /dev/pps1 lock NMEA refid PPS

makestep 0.1 -1
driftfile /var/lib/chrony/drift
rtcsync

# 作为校时服务器
allow all
local stratum 10

3.3 chrony.conf

示例1-faq

server ntp.local minpoll 2 maxpoll 4 polltarget 30

在NTP服务器配置中,minpollmaxpoll参数用于限制NTP客户端发送时间同步请求的频率。这两个参数控制了NTP客户端在连续的时间同步请求之间等待的最小和最大时间间隔。

minpoll参数指定了NTP客户端发送时间同步请求的最小时间间隔,单位为2的幂次方的秒。在你的配置中,minpoll的值为2,表示最小时间间隔为2的2次方,即4秒。

maxpoll参数指定了NTP客户端发送时间同步请求的最大时间间隔,单位同样为2的幂次方的秒。在你的配置中,maxpoll的值为4,表示最大时间间隔为2的4次方,即16秒。

polltarget参数表示NTP客户端向服务器发送请求的时间间隔的目标值,单位为秒。在你的配置中,polltarget的值为30,表示NTP客户端希望每30秒发送一次时间同步请求。

需要注意的是,polltarget参数是以秒为单位的,而不是2的幂次方。因此,polltarget的值并不会超过maxpoll参数的限制。在你的配置中,即使maxpoll的值为4(即16秒),polltarget的值也仍然是30秒。这样设置的目的是为了在时间同步的准确性和服务器负载之间取得一个平衡。

综上所述,NTP客户端的实际时间同步间隔取决于服务器响应和网络延迟等因素,但会受到minpollmaxpoll参数的限制。在你的配置中,NTP客户端将以30秒为目标值发送时间同步请求,但实际的时间间隔可能会在4秒到16秒之间变化。

示例2-faq

server ntp.local minpoll 0 maxpoll 0 xleave
hwtimestamp eth0

3.4 chronyd

3.5 chronyc

chronyc是一个命令行界面程序,可用于监视chronyd的性能,并在运行时更改各种操作参数。

  • chronyc tracking:跟踪命令显示有关系统时钟性能的参数。
  • chronyc sources
    root@imx6qdlsabresd:/app/log#  chronyc tracking
    Reference ID    : 127.127.1.1 ()
    Stratum         : 10
    Ref time (UTC)  : Thu Sep 07 23:14:28 2023
    System time     : 14539.303710938 seconds fast of NTP time
    Last offset     : -0.271399736 seconds
    RMS offset      : 105085.718750000 seconds
    Frequency       : 499789.469 ppm fast
    Residual freq   : +0.000 ppm
    Skew            : 0.000 ppm
    Root delay      : 0.000000 seconds
    Root dispersion : 0.000001 seconds
    Update interval : 0.1 seconds
    Leap status     : Normal
    

chrony如何查看校时精度?

在上面的输出中,您可以看到Last offset和RMS offset字段,它们表示最近一次同步时钟的偏移量和持续的偏移量的均方根。这些值越小,校时精度越高。另外,您还可以关注Frequency字段,它表示系统时钟相对于NTP服务器时钟的频率偏移。

请注意,校时精度的度量单位是秒,小数点后的数字表示精度的小数部分。

四、gpsd + chrony + pps 介绍和使用

  • gpsd + chrony : 实现时间同步。
  • gpsd + chrony + pps : 实现更高精度的时间同步。

4.1 gpsd 介绍

gpsd是一个服务守护进程,它通过串行或USB端口监视连接到主机的一个或多个GPSE或AIS接收器,使有关传感器的位置/路线/速度的所有数据都可以在主机的TCP端口2947上查询。

4.1.1 gpsd 交叉编译

1. gpsd 源码下载

# 方式一(当前版本是 v3.25.1)
git clone https://gitlab.com/gpsd/gpsd

# 方式二:浏览器下载源码压缩包

2. ubuntu 下安装交叉编译工具链以及编译工具scons
1) 确保ubuntu系统已经安装python
2) 已安装交叉编译工具链 arm-fslc-linux-gnueabi-gcc
3)安装编译工具 scons

scons是linux下的自动构建工具,类似cmake.

sudo apt-get install scons

3.1 交叉编译依赖库libusb

交叉编译gpsd,需要安装依赖库 libusb 、libncurses、libtinfo。

1)下载libusb:http://sourceforge.net/projects/libusb/files/ (这里下载的 libusb-1.0.22.tar.bz2)
2)交叉编译源码

# 解压
tar xjvf libusb-1.0.22.tar.bz2
cd libusb-1.0.22

# 配置交叉编译
./configure CC="arm-fslc-linux-gnueabi-gcc  -march=armv7-a -mthumb -mfpu=neon -mfloat-abi=hard --sysroot=/opt/fslc-framebuffer/2.4.4/sysroots/armv7at2hf-neon-fslc-linux-gnueabi" --host=arm-fslc-linux-gnueabi --prefix=$PWD/install_arm --disable-udev

# 编译和安装
make && make install

# 查看成果物(头文件、库、pkgconfig文件),一会要将库文件统一拷贝到gpsd目录下
ls -R install_arm
cp -rf install_arm/lib/* ../lib

3.2 交叉编译依赖库libncurses
1)下载ncurses库源码包:http://ftp.gnu.org/pub/gnu/ncurses/ (这里下载的是ncurses-6.1.tar.gz)
2)交叉编译源码

# 解压
tar -xzvf ncurses-6.1.tar.gz
cd ncurses-6.1/
# 配置交叉编译
./configure CC="arm-fslc-linux-gnueabi-gcc  -march=armv7-a -mthumb -mfpu=neon -mfloat-abi=hard --sysroot=/opt/fslc-framebuffer/2.4.4/sysroots/armv7at2hf-neon-fslc-linux-gnueabi" --host=arm-fslc-linux-gnueabi --prefix=$PWD/install_arm
# 编译和安装
make && make install
# 拷贝库成果物
cp -rf install_arm/lib/* ../lib

3.3 交叉编译pps-tools(可选)

计划使用gpsd + pps + chrony来使用,这里交叉编译pps-tools,一方面使用工具,另外一方面gpsd若支持pps需要 timepps.h 头文件(需要放到指定位置,以便编译时能找到)

1)下载源码包:github下载压缩包(这里下载版本1.0.2)
2)交叉编译源码

cd pps-tools-1.0.2/
# 配置环境变量
export CC="arm-fslc-linux-gnueabi-gcc  -march=armv7-a -mthumb -mfpu=neon -mfloat-abi=hard --sysroot=/opt/fslc-framebuffer/2.4.4/sysroots/armv7at2hf-neon-fslc-linux-gnueabi"

# 成果物(可执行程序)有:ppstest、ppsctl、ppswatch

# 拷贝gpsd pps依赖头文件(已根据sysroot,所以拷贝到对应路径下)
cp timepps.h /opt/fslc-framebuffer/2.4.4/sysroots/armv7at2hf-neon-fslc-linux-gnueabi/usr/include/sys/

4. gpsd 交叉编译

1)配置交叉编译

在这里插入图片描述

cd gpsd

# 拷贝依赖库
cp -fr ../lib/* .

# 新增交叉编译配置
vi .scons-option-cache

配置如下内容:

libgpsmm = False
python = False
prefix = '/mnt/d/hik/debug/opensource/gpsd-depend/20231114/gpsd/install_arm'
sysroot = '/opt/fslc-framebuffer/2.4.4/sysroots/armv7at2hf-neon-fslc-linux-gnueabi'
target = 'arm-fslc-linux-gnueabi'

修改 SConscript 文件

将 dbus_export 改成 false 或 交叉编译 dbus-1.14.0

2)操作交叉编译(参考Quick start章节)

# 配置环境变量
export CC="arm-fslc-linux-gnueabi-gcc  -march=armv7-a -mthumb -mfpu=neon -mfloat-abi=hard --sysroot=/opt/fslc-framebuffer/2.4.4/sysroots/armv7at2hf-neon-fslc-linux-gnueabi"

# 清理、编译、安装
scons -c
scons pps=yes ntpshm=yes prefix=$PWD/install_arm
scons check						# 忽略报错
sudo scons install				# 要带sudo、不然只安装gpsd,没其他组件

# 参考留底
# scons pps=yes ntpshm=yes prefix=$PWD/install_arm -n
# scons pps=yes ntpshm=yes timeservice=yes nmea0183=yes -n
# source /opt/fslc-framebuffer/2.4.4/environment-setup-armv7at2hf-neon-fslc-linux-gnueabi

# 查看安装结果,如下图(若没成功再检查修复)

在这里插入图片描述

注意,若没有python,操作安装或软连接

sudo ln -s /usr/bin/python3 /usr/bin/python
# 或
sudo ln -s /opt/fslc-x11/2.4.4/sysroots/x86_64-fslcsdk-linux/usr/bin/python3  /usr/bin/python

4.1.2 gpsd 使用

将gpsd、gpsmon、cgps、ppstest等拷贝到arm设备中,比如拷贝到/app/gpsd-test目录下,添加可执行权限 chmod +x /app/gpsd-test/*

cd /app/gpsd-test

# gpsd 查看支持项
./gpsd -l

# gpsd 使用pps 
./gpsd -n -G /dev/ttyUSB5 /dev/pps1 
./gpsd -n -G -s 115200 /dev/ttymxc3 /dev/pps1

# gpsd 不使用pps 
./gpsd -n -G /dev/ttymxc3

# 带调试
./gpsd -D 5 -N -n /dev/ttymxc3 /dev/pps1

# 数据验证
./gpsmon

# 查看和修改串口波特率(由于gpsd没有设置,所以系统必须设置好 或 -s 指定波特率)
stty -F /dev/ttymxc3
stty -F /dev/ttymxc3 speed 115200

./gpsd -l 查看是否开启PPS
在这里插入图片描述

gpsd 带pps时,执行 ./gpsmon 效果
在这里插入图片描述
gpsd 不带pps时,执行 ./gpsmon 效果
在这里插入图片描述

4.1.2 gpsd + chrony

  1. 要先启动 gpsd
  2. 再启动 chronyd (先修改设置好配置文件 /etc/chrony.conf)
mv /etc/chrony.conf /etc/chrony.conf.bk # 备份下原来文件

vi /etc/chrony.conf

填写如下内容:

# gpsd and pps 注意pps节点名称
refclock SHM 0 poll -2 refid GPS precision 1e-1 offset 0.9999 delay 0.2
refclock PPS /dev/pps1 lock NMEA refid PPS

makestep 0.1 -1
driftfile /var/lib/chrony/drift
rtcsync

# 作为校时服务器(用来给其他设备校时 或 比较时间差)
allow all
local stratum 10

启动gpsd和chronyd

killall -15 gpsd chronyd  	# 执行两遍
./gpsd -n -G -s 115200 /dev/ttymxc3 /dev/pps1
chronyd -d &
./ppstest /dev/pps1			# 要稍微等一会才会校准

# 比较时间



./gpsd -D 5 -N -n /dev/ttyUSB5 /dev/pps1
chronyc sources
date +%Y-%m-%d' '%H:%M:%S.%N | cut -b 1-23		
./ntpdate -q 10.234.111.138

4.2 pps 和 pps-tools 介绍和使用

  • PPS 支持需要:GPS接收器 + 硬件设计连接 + 内核配置开启 + 驱动。
  • 查看当前系统是否已支持 pps
  • ppstest查看pps信号时间值
  • 查看pps中断
  • pps配合gpsd使用(配合)

PPS是指脉冲秒信号(Pulse Per Second),它是一个精确的时间标记信号,用于精确同步计时设备。PPS通常由GPS接收器提供,以确保设备与全球卫星导航系统(GPS)的时间同步。

PPS-Tools是一个用于处理和分析PPS信号的软件工具包。它包含了一系列用于接收、分析和校准PPS信号的工具和库。使用PPS-Tools,用户可以通过计算和比较PPS信号与其他参考时间源的差异来实现高精度的时间同步。

PPS-Tools的功能包括:

  1. PPS接收器:用于接收和解码PPS信号的硬件设备。
  2. PPS校准:通过与参考时间源比较PPS信号,进行时间校准和同步。
  3. 数据记录和分析:记录和分析PPS信号的时间戳数据。
  4. 精度测量:测量PPS信号与参考时间源之间的精确度和稳定性。

PPS-Tools是一个强大的工具包,广泛用于科学研究、计时设备校准和精确时间同步等领域。它可以帮助用户实现微秒级甚至更高精度的时间同步,对于需要高精度时间标记的应用非常有用。

查看当前系统是否已支持 pps

dmesg | grep pps

./ppstest /dev/pps*

在这里插入图片描述

在应用层,使用ppstest工具可查看pps信号时间值(pps信号发生时刻的系统时间点)

ppstest若没有需通过源码交叉编译得到。
在这里插入图片描述
注意,若pps已校准,时间精度会变高:
在这里插入图片描述

查看pps中断:

root@imx6qdlsabresd:/app/test/debug_gpsd# cat /proc/interrupts |grep pps
 37:     258897          0          0          0  gpio-mxc   5 Edge      pps.-1
root@imx6qdlsabresd:/app/test/debug_gpsd# cat /proc/interrupts |grep pps
 37:     258899          0          0          0  gpio-mxc   5 Edge      pps.-1
root@imx6qdlsabresd:/app/test/debug_gpsd# cat /proc/interrupts |grep pps
 37:     258903          0          0          0  gpio-mxc   5 Edge      pps.-1

参考资料

五、比较两个设备时间差

5.1 date 命令

两台设备分别通过xshll工具进行SSH连接,然后工具—发送输入到—所有会话:

# 获取系统时间纳秒
date +%Y-%m-%d' '%H:%M:%S.%N

# 获取系统时间毫秒
date +%Y-%m-%d' '%H:%M:%S.%N | cut -b 1-23

# 自动循环获取时间(有休眠、不如手动敲)
while true; do date +%Y-%m-%d' '%H:%M:%S.%N; sleep 0.1;done
  • 若性能要求高:务必确保两台设备、PC在同一个交换机下。
  • 时间误差:PC到两台设备的网络时延、IO时延。

5.2 ntpdate命令

5.2.1 使用示例

只比较和ntp 服务器的时间差,不校时:(务必在同一个交换机下)

./ntpdate -q ntp1.aliyun.com

响应:
server 120.25.115.20, stratum 2, offset 32.851291, delay 0.04848 8
Sep 14:43:24 ntpdate[15053]: step time server 120.25.115.20 offset 32.851291 sec

5.2.2 ntpdate 交叉编译

版权声明:本文为CSDN博主「钱德勒宾」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_38184741/article/details/100011091

前言
板子上需要在开机时同步网络时间。

之前板子上有ntpdate工具,可以直接使用。最近突然不能用了。需要手动移植一个。

开发板:Hi3559A

编译工具链:aarch64-himix100-linux-gcc

ntp版本:ntp-4.2.8p13.tar.gz

openssl 版本:openssl-1.0.1f.tar.gz (注意,使用其他版本会报版本错误)

# 交叉编译

# 配置环境变量
source /opt/fslc-framebuffer/2.4.4/environment-setup-armv7at2hf-neon-fslc-linux-gnueabi

./configure --prefix=$PWD/install_arm --exec-prefix=$PWD/install_arm CC="arm-fslc-linux-gnueabi-gcc  -march=armv7-a -mthumb -mfpu=neon -mfloat-abi=hard --sysroot=/opt/fslc-framebuffer/2.4.4/sysroots/armv7at2hf-neon-fslc-linux-gnueabi" --host=arm-fslc-linux-gnueabi --with-yielding-select=yes

make -j
make install

编译成果物
在这里插入图片描述
以下是一些常见的 NTP 可执行文件以及它们的功能和用途:

  1. ntpd:NTP 守护进程,负责运行 NTP 服务器,提供时间同步服务。
  2. ntpdate:手动更新系统时间的工具,通过与指定的 NTP 服务器通信,将服务器的时间应用到本地系统上。
  3. ntpq:NTP 查询工具,用于监控和调试 NTP 服务器。通过 ntpq,你可以查看服务器状态、查询时间同步信息等。
  4. ntpdc:NTP 控制台工具,用于与 NTP 服务器进行交互,进行配置、查询状态和执行其他管理操作。
  5. ntptrace:追踪 NTP 服务器的路径,显示从本地系统到指定服务器的网络路径。
  6. ntp-keygen:用于生成和管理 NTP 安全密钥的工具,用于加密和验证 NTP 服务器之间的通信。

5.2.3 chronyd 命令

在这里插入图片描述

# 校时一次退出
chronyd -q 'pool pool.ntp.org iburst'

# 不校时,只比较时间差
chronyd -Q 'pool pool.ntp.org iburst'

在这里插入图片描述

六、核心参考

遗留问题:

  • 不同设备 gpsd + chronyd + pps 校时后时间相差较大,什么原因?
  • gpsd + chronyd + pps 原理