关于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 <giometti@linux.it> [ 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 -lNMEA0183 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 rtcsyncrefclock PPS /dev/pps1 lock GPSD prefer refid PPS refclock SHM 0 offset 0.0 delay 0.2 refid GPSDallowdriftfile - 根據實際時間計算出計算機增減時間的比率,將它記錄到一個文件中是最合理的,它會在重啟后為系統時鐘作出補償,甚至可能的話,會從時鐘服務器獲得較好的估值。
rtcsync -指令將啟用一個內核模式,在該模式中,系統時間每11分鐘會拷貝到實時時鐘(RTC)。
allow / deny - 這里你可以指定一臺主機、子網,或者網絡以允許或拒絕NTP連接到扮演時鐘服務器的機器。
makestep - 通常,chronyd將根據需求通過減慢或加速時鐘,使得系統逐步糾正所有時間偏差。在某些特定情況下,系統時鐘可能會漂移過快,導致該調整過程消耗很長的時間來糾正系統時鐘。該指令強制chronyd在調整期大于某個閥值時步進調整系統時鐘,但只有在因為chronyd啟動時間超過指定限制(可使用負值來禁用限制),沒有更多時鐘更新時才生效
詳細的各項配置可以參閱官方文檔: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, ignoring2020-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平臺搭建的時間服務器完畢。
總結
以上是生活随笔為你收集整理的关于GPS的1PPS时间同步功能探索与测试的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 项目中用到的语音识别方案 硬件/软件相关
- 下一篇: GPSD架构介绍及交叉编译和使用