關於GPS的1PPS時間同步功能探索與測試

最近在研究GPSD相關信息,查閱到GPSD可以與NTPD相配合實現高精度時間同步功能,因此才涉及到此主題。

目前手頭用的是Ublox F9P模塊,UART輸出NEMA數據,另外一個GPIO輸出1PPS脈衝

首先看一張時序圖:

1. NEMA中包含有時間信息,一般是秒級別,也有部分帶有毫秒

2. 1PPS即每秒輸出一個脈衝,圖中以高電平觸發爲例(沒畫下降沿),接收及處理1PPS脈衝的時間也在ns級別

3. 因爲NEMA是通過串口發送和接收,而且一次NEMA數據量也有KB級別大小,處理時間遠比1PPS時間長

4. 通過NEMA中的秒級時間和1PPS脈衝相配合,即可實現高精度時間同步(ns級:依據1PPS的響應時間)

具體時間同步實現,以Linux爲例,常用組合方式爲:kenel pps.ko,GPSD,chronyd或者NTPD

首先Kernel pps.ko:

當前kernel是支持pps處理的,因爲我用的ublox的pps是接到gpio的,所以選擇gpio方式

1. kernel timer client 是內核軟件模擬的pps信號,用於測試

2. pps client using gpio 是以gpio作爲pps信號源

pps-gpio.c源碼實現也比較簡單,主要通過註冊gpio中斷,當gpio電平變化時,記錄當前系統運行時刻,然後post event到用戶空間。

因爲使用了外部GPIO,因此在使用該模塊之前,需要在dts中指定相關的gpio引腳,compatible 爲 "pps-gpio"

static const struct of_device_id pps_gpio_dt_ids[] = {

{ .compatible = "pps-gpio", },

{ /* sentinel */ }

};

配置後編譯啓動,查閱dmesg

root@imx8qxpmek:~# dmesg |grep pps
[    0.708441] pps_core: LinuxPPS API ver. 1 registered
[    0.713357] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <[email protected]>
[    1.737515] pps pps0: new PPS source ktimer
[    1.741727] pps pps0: ktimer PPS source registered
[    1.747556] pps pps1: new PPS source pps.-1
[    1.751804] pps pps1: Registered IRQ 115 as PPS source
[  236.866057] pps pps1: unsupported capabilities (2)

此處, PPS0爲內核模擬的pps信號,pps1  ublox模塊的pps 信號

在應用層,使用ppstest工具可查看pps信號時間值(pps信號發生時刻的系統時間點)

root@imx8qxpmek:~# 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 1591828917.828448156, sequence: 85791 - clear  0.000000000, sequence: 0
source 0 - assert 1591828918.852533634, sequence: 85792 - clear  0.000000000, sequence: 0
source 0 - assert 1591828919.876534727, sequence: 85793 - clear  0.000000000, sequence: 0
^C
root@imx8qxpmek:~# 
root@imx8qxpmek:~# ppstest /dev/pps1 
trying PPS source "/dev/pps1"
found PPS source "/dev/pps1"
ok, found 1 source(s), now start fetching data...
source 0 - assert 1591828923.065352191, sequence: 87742 - clear  0.000000000, sequence: 0
source 0 - assert 1591828924.065348846, sequence: 87743 - clear  0.000000000, sequence: 0
source 0 - assert 1591828925.065347127, sequence: 87744 - clear  0.000000000, sequence: 0
source 0 - assert 1591828926.065348783, sequence: 87745 - clear  0.000000000, sequence: 0
^C

查看pps中斷:

root@imx8qxpmek:~# date
Thu Jun 11 06:43:49 CST 2020
root@imx8qxpmek:~# cat /proc/interrupts |grep pps
115:      87851          0          0          0  gpio-mxc  16 Edge      pps.-1
root@imx8qxpmek:~# date
Thu Jun 11 06:43:53 CST 2020
root@imx8qxpmek:~# cat /proc/interrupts |grep pps
115:      87855          0          0          0  gpio-mxc  16 Edge      pps.-1

通過date時間打印,可以看到1s產生一次中斷。

至此,pps配置完畢,接下來處理NEMA數據,使用gpsd

gpsd是一個支持多設備,多協議以及提供豐富工具集的專用gps信號處理服務。此處主要介紹起使用,不做編譯以及功能詳細說明。

通過gpsd -l可以查閱支持的gps協議或者說模塊,我裁剪過,只保留NEMA和ublox,所以只顯示兩個

root@imx8qxpmek:~# ./gpsd -l
                                NMEA0183
n       b       c       *       u-blox
# n: mode switch, b: speed switch, c: rate switch, *: non-NMEA packet type.
# Socket export enabled.
# Shared memory export enabled.
# Time service features enabled.

另外也可以看到,支持socket 和共享內存方式通訊,比如後續要用到的chronyd即是採用共享內存方式,同時也開啓了時間服務,當然此處沒有用,而是用chrony單獨實現。

啓動gpsd服務後,可以通過其提供的各種工具集獲取gps狀態,比如gpsmon:

接下來配置chrony,chrony爲一個專用的時間服務程序,與NTPD類似

其配置爲/etc/chrony.conf


leapsectz right/UTC
makestep 1.0 -1
rtcsync

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

allow

driftfile - 根據實際時間計算出計算機增減時間的比率,將它記錄到一個文件中是最合理的,它會在重啓後爲系統時鐘作出補償,甚至可能的話,會從時鐘服務器獲得較好的估值。

rtcsync -指令將啓用一個內核模式,在該模式中,系統時間每11分鐘會拷貝到實時時鐘(RTC)。

allow / deny - 這裏你可以指定一臺主機、子網,或者網絡以允許或拒絕NTP連接到扮演時鐘服務器的機器。
makestep - 通常,chronyd將根據需求通過減慢或加速時鐘,使得系統逐步糾正所有時間偏差。在某些特定情況下,系統時鐘可能會漂移過快,導致該調整過程消耗很長的時間來糾正系統時鐘。該指令強制chronyd在調整期大於某個閥值時步進調整系統時鐘,但只有在因爲chronyd啓動時間超過指定限制(可使用負值來禁用限制),沒有更多時鐘更新時才生效

refclock driver parameter[:option]…​ [option]…​

    The refclock directive specifies a hardware reference clock to be used as a time source. It has two mandatory parameters, a driver name and a driver-specific parameter. The two parameters are followed by zero or more refclock options. Some drivers have special options, which can be appended to the driver-specific parameter using the : character.

    There are four drivers included in chronyd:

    PPS

        Driver for the kernel PPS (pulse per second) API. The parameter is the path to the PPS device (typically /dev/pps?). As PPS refclocks do not supply full time, another time source (e.g. NTP server or non-PPS refclock) is needed to complete samples from the PPS refclock. An alternative is to enable the local directive to allow synchronisation with some unknown but constant offset. The driver supports the following option:

        clear

            By default, the PPS refclock uses assert events (rising edge) for synchronisation. With this option, it will use clear events (falling edge) instead.

        Examples:

        refclock PPS /dev/pps0 lock NMEA refid GPS
        refclock SHM 0 offset 0.5 delay 0.2 refid NMEA noselect
        refclock PPS /dev/pps1:clear refid GPS2

詳細的各項配置可以參閱官方文檔:https://chrony.tuxfamily.org/documentation.html

運行chronyd之後,可以看到時間同步過程:

root@imx8qxpmek:~# chronyd  -d -f /etc/chrony.conf  
2020-06-10T17:00:41Z chronyd version 3.2 starting (+CMDMON +NTP +REFCLOCK +RTC -PRIVDROP -SCFILTER -SECHASH -SIGND +ASYNCDNS +IPV6 -DEBUG)
2020-06-10T17:00:41Z Initial frequency -116.709 ppm
2020-06-10T17:00:41Z Timezone right/UTC failed leap second check, ignoring

2020-06-10T17:01:28Z Selected source PPS
2020-06-10T17:01:28Z System clock wrong by 34565.191649 seconds, adjustment started
2020-06-11T02:37:33Z System clock was stepped by 34565.191649 seconds

在客戶端方面,使用ntpd測試如下:

root@OpenWrt:~# ntpd -d -n -p 192.168.3.1
ntpd: sending query to 192.168.3.1
ntpd: reply from 192.168.3.1: offset:+6152.992411 delay:0.008204 status:0x24 strat:1 refid:0x00535050 rootdelay:0.000015 reach:0x01
ntpd: sending query to 192.168.3.1
ntpd: reply from 192.168.3.1: offset:+6152.990378 delay:0.004154 status:0x24 strat:1 refid:0x00535050 rootdelay:0.000015 reach:0x03
ntpd: setting time to 2020-06-11 10:42:38.090639 (offset +6152.990378s)

至此以NEMA,1PPS,GPSD,chronyd 等在linux平臺搭建的時間服務器完畢。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章