关于GPS的1PPS时间同步功能探索与测试
最近在研究GPSD相關(guān)信息,查閱到GPSD可以與NTPD相配合實(shí)現(xiàn)高精度時(shí)間同步功能,因此才涉及到此主題。
目前手頭用的是Ublox F9P模塊,UART輸出NEMA數(shù)據(jù),另外一個(gè)GPIO輸出1PPS脈沖
首先看一張時(shí)序圖:
1. NEMA中包含有時(shí)間信息,一般是秒級(jí)別,也有部分帶有毫秒
2. 1PPS即每秒輸出一個(gè)脈沖,圖中以高電平觸發(fā)為例(沒(méi)畫(huà)下降沿),接收及處理1PPS脈沖的時(shí)間也在ns級(jí)別
3. 因?yàn)镹EMA是通過(guò)串口發(fā)送和接收,而且一次NEMA數(shù)據(jù)量也有KB級(jí)別大小,處理時(shí)間遠(yuǎn)比1PPS時(shí)間長(zhǎng)
4. 通過(guò)NEMA中的秒級(jí)時(shí)間和1PPS脈沖相配合,即可實(shí)現(xiàn)高精度時(shí)間同步(ns級(jí):依據(jù)1PPS的響應(yīng)時(shí)間)
具體時(shí)間同步實(shí)現(xiàn),以Linux為例,常用組合方式為:kenel pps.ko,GPSD,chronyd或者NTPD
首先Kernel pps.ko:
當(dāng)前kernel是支持pps處理的,因?yàn)槲矣玫膗blox的pps是接到gpio的,所以選擇gpio方式
1. kernel timer client 是內(nèi)核軟件模擬的pps信號(hào),用于測(cè)試
2. pps client using gpio 是以gpio作為pps信號(hào)源
pps-gpio.c源碼實(shí)現(xiàn)也比較簡(jiǎn)單,主要通過(guò)注冊(cè)gpio中斷,當(dāng)gpio電平變化時(shí),記錄當(dāng)前系統(tǒng)運(yùn)行時(shí)刻,然后post event到用戶空間。
因?yàn)槭褂昧送獠縂PIO,因此在使用該模塊之前,需要在dts中指定相關(guān)的gpio引腳,compatible 為 "pps-gpio"
static const struct of_device_id pps_gpio_dt_ids[] = {{ .compatible = "pps-gpio", },{ /* sentinel */ }};配置后編譯啟動(dòng),查閱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為內(nèi)核模擬的pps信號(hào),pps1? ublox模塊的pps 信號(hào)
在應(yīng)用層,使用ppstest工具可查看pps信號(hào)時(shí)間值(pps信號(hào)發(fā)生時(shí)刻的系統(tǒng)時(shí)間點(diǎn))
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通過(guò)date時(shí)間打印,可以看到1s產(chǎn)生一次中斷。
至此,pps配置完畢,接下來(lái)處理NEMA數(shù)據(jù),使用gpsd
gpsd是一個(gè)支持多設(shè)備,多協(xié)議以及提供豐富工具集的專用gps信號(hào)處理服務(wù)。此處主要介紹起使用,不做編譯以及功能詳細(xì)說(shuō)明。
通過(guò)gpsd -l可以查閱支持的gps協(xié)議或者說(shuō)模塊,我裁剪過(guò),只保留NEMA和ublox,所以只顯示兩個(gè)
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 和共享內(nèi)存方式通訊,比如后續(xù)要用到的chronyd即是采用共享內(nèi)存方式,同時(shí)也開(kāi)啟了時(shí)間服務(wù),當(dāng)然此處沒(méi)有用,而是用chrony單獨(dú)實(shí)現(xiàn)。
啟動(dòng)gpsd服務(wù)后,可以通過(guò)其提供的各種工具集獲取gps狀態(tài),比如gpsmon:
接下來(lái)配置chrony,chrony為一個(gè)專用的時(shí)間服務(wù)程序,與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 - 根據(jù)實(shí)際時(shí)間計(jì)算出計(jì)算機(jī)增減時(shí)間的比率,將它記錄到一個(gè)文件中是最合理的,它會(huì)在重啟后為系統(tǒng)時(shí)鐘作出補(bǔ)償,甚至可能的話,會(huì)從時(shí)鐘服務(wù)器獲得較好的估值。
rtcsync -指令將啟用一個(gè)內(nèi)核模式,在該模式中,系統(tǒng)時(shí)間每11分鐘會(huì)拷貝到實(shí)時(shí)時(shí)鐘(RTC)。
allow / deny - 這里你可以指定一臺(tái)主機(jī)、子網(wǎng),或者網(wǎng)絡(luò)以允許或拒絕NTP連接到扮演時(shí)鐘服務(wù)器的機(jī)器。
makestep - 通常,chronyd將根據(jù)需求通過(guò)減慢或加速時(shí)鐘,使得系統(tǒng)逐步糾正所有時(shí)間偏差。在某些特定情況下,系統(tǒng)時(shí)鐘可能會(huì)漂移過(guò)快,導(dǎo)致該調(diào)整過(guò)程消耗很長(zhǎng)的時(shí)間來(lái)糾正系統(tǒng)時(shí)鐘。該指令強(qiáng)制chronyd在調(diào)整期大于某個(gè)閥值時(shí)步進(jìn)調(diào)整系統(tǒng)時(shí)鐘,但只有在因?yàn)閏hronyd啟動(dòng)時(shí)間超過(guò)指定限制(可使用負(fù)值來(lái)禁用限制),沒(méi)有更多時(shí)鐘更新時(shí)才生效
詳細(xì)的各項(xiàng)配置可以參閱官方文檔:https://chrony.tuxfamily.org/documentation.html
運(yùn)行chronyd之后,可以看到時(shí)間同步過(guò)程:
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測(cè)試如下:
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平臺(tái)搭建的時(shí)間服務(wù)器完畢。
總結(jié)
以上是生活随笔為你收集整理的关于GPS的1PPS时间同步功能探索与测试的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 项目中用到的语音识别方案 硬件/软件相关
- 下一篇: GPSD架构介绍及交叉编译和使用