在我的电脑上,我想从GPS馈送chrony。为此,我安装了gpsd
和pps-tools
。我有一个GPS连接到串行端口/dev/ttyS0
,PPS连接到DCD输入。显然,PPS脉冲接收正确:
$ sudo ppscheck /dev/ttyS0
# Seconds nanoSecs Signals
1646915383.000347816 TIOCM_CD
1646915383.100323649
1646915384.000213974 TIOCM_CD
1646915384.100172453
...
到目前为止还不错。此外,来自GPS模块的数据似乎接收正确。我使用sudo gpsmon /dev/ttyS0
对此进行了验证。它显示为$GPRMC
语句已成功接收并且数据有效。可以提取时间并检测PPS:
┌──────────────────────────────────────────────────────────────────────────────┐
│Time: 2022-03-10T12:31:10.000Z Lat: 46 xx.xxxxxx' N Lon: 7 xx.xxxxxx' E │
└───────────────────────────────── Cooked TPV ─────────────────────────────────┘
┌──────────────────────────────────────────────────────────────────────────────┐
│ GPRMC │
└───────────────────────────────── Sentences ──────────────────────────────────┘
┌───────────────────────┌─────────────────────────┌────────────────────────────┐
│ SVID PRN Az El SN HU│Time: 123110 │Time: │
│ │Latitude: 46xx.xxxxx N │Latitude: │
│ │Longitude: 7xx.xxxxx E │Longitude: │
│ │Speed: 000.0 │Altitude: │
│ │Course: 000.0 │Quality: Sats: │
│ │Status: A FAA: │HDOP: │
│ │MagVar: 000.0E │Geoid: │
│ └───────── RMC ───────────└─────────── GGA ────────────┘
│ ┌─────────────────────────┌────────────────────────────┐
│ │Mode: Sats: │UTC: RMS: │
│ │DOP H= V= P= │MAJ: MIN: │
│ │TOFF: 0.132531938 │ORI: LAT: │
│ │PPS: 0.000246686 │LON: ALT: │
└──────── GSV ──────────└────── GSA + PPS ────────└─────────── GST ────────────┘
到目前为止,一切都很好。我现在想运行gpsd
,这样chrony
就可以从中获得时间。问题开始了。我测试gpsd
如下`
gpsd:INFO: launching (Version 3.23.1, revision 3.23.1)
gpsd:IO: opening IPv4 socket
gpsd:SPIN: passivesock_af() -> 3
gpsd:IO: opening IPv6 socket
gpsd:SPIN: passivesock_af() -> 4
gpsd:INFO: listening on port gpsd
gpsd:PROG: NTP: shmat(0,0,0) succeeded, segment 0
gpsd:PROG: NTP: shmat(1,0,0) succeeded, segment 1
gpsd:PROG: NTP: shmat(2,0,0) succeeded, segment 2
gpsd:PROG: NTP: shmat(3,0,0) succeeded, segment 3
gpsd:PROG: NTP: shmat(4,0,0) succeeded, segment 4
gpsd:PROG: NTP: shmat(5,0,0) succeeded, segment 5
gpsd:PROG: NTP: shmat(6,0,0) succeeded, segment 6
gpsd:PROG: NTP: shmat(7,0,0) succeeded, segment 7
gpsd:PROG: successfully connected to the DBUS system bus
gpsd:PROG: shmget(0x47505344, 26712, 0666) for SHM export succeeded
gpsd:PROG: shmat() for SHM export succeeded, segment 8
gpsd:INFO: stashing device /dev/ttyS0 at slot 0
gpsd:PROG: no /etc/gpsd/device-hook present, skipped running ACTIVATE hook. No such file or directory
gpsd:INFO: SER: opening read-only GPS data source type 2 at '/dev/ttyS0'
gpsd:IO: SER: fusercount: path /dev/ttyS0 fullpath /dev/ttyS0 cnt 1
gpsd:IO: SER: fd 6 set speed 115200(4098)
gpsd:INFO: SER: fd 6 current speed 115200, 8N1
gpsd:IO: SER: open(/dev/ttyS0) -> 6 in gpsd_serial_open()
gpsd:PROG: Probing "Garmin USB binary" driver...
gpsd:PROG: Probe not found "Garmin USB binary" driver...
gpsd:PROG: Probing "GeoStar" driver...
gpsd:PROG: Sent GeoStar packet id 0xc1
gpsd:PROG: Probe not found "GeoStar" driver...
gpsd:PROG: Probing "Trimble TSIP" driver...
gpsd:IO: SER: fd 6 set speed 9600(13)
gpsd:INFO: SER: fd 6 current speed 9600, 8O1
gpsd:IO: SER: fd 6 set speed 115200(4098)
gpsd:INFO: SER: fd 6 current speed 115200, 8N1
gpsd:PROG: Probe not found "Trimble TSIP" driver...
gpsd:PROG: Probing "iSync" driver...
gpsd:IO: SER: fd 6 set speed 9600(13)
gpsd:INFO: SER: fd 6 current speed 9600, 8N1
gpsd:IO: SER: fd 6 set speed 115200(4098)
gpsd:INFO: SER: fd 6 current speed 115200, 8N1
gpsd:PROG: Probe not found "iSync" driver...
gpsd:PROG: no probe matched...
gpsd:INFO: gpsd_activate(2): activated GPS (fd 6)
gpsd:PROG: NTP:PPS: using SHM(0)
gpsd:PROG: NTP:PPS: using SHM(1)
gpsd:PROG: PPS:/dev/ttyS0 connect chrony socket failed: /run/chrony.ttyS0.sock, error: -2, errno: 111/Connection refused
gpsd:PROG: KPPS:/dev/ttyS0 checking /sys/devices/virtual/pps/pps1/path, /dev/ttyS0
gpsd:INFO: KPPS:/dev/ttyS0 RFC2783 path:/dev/pps1, fd is 7
gpsd:INFO: KPPS:/dev/ttyS0 pps_caps 0x1133
gpsd:INFO: KPPS:/dev/ttyS0 have PPS_CANWAIT
gpsd:INFO: KPPS:/dev/ttyS0 kernel PPS will be used
gpsd:PROG: PPS:/dev/ttyS0 thread launched
gpsd:INFO: PPS: activated /dev/ttyS0 ntpshm_link_activate(): Clock
gpsd:INFO: stashing device /dev/pps0 at slot 1
gpsd:PROG: no /etc/gpsd/device-hook present, skipped running ACTIVATE hook. No such file or directory
gpsd:ERROR: SER: stat(/dev/pps0) failed: No such file or directory(2)
gpsd:ERROR: initial GPS device /dev/pps0 open failed
gpsd:INFO: KPPS:/dev/ttyS0 kernel PPS timeout 4:unknown error
gpsd:INFO: KPPS:/dev/ttyS0 kernel PPS timeout 4:unknown error
gpsd:INFO: KPPS:/dev/ttyS0 kernel PPS timeout 4:unknown error
gpsd:INFO: running with effective group ID 18
gpsd:INFO: running with effective user ID 65534
gpsd:INFO: startup at 2022-03-10T12:35:52.000Z (1646915752)
gpsd:PROG: KPPS:/dev/ttyS0 assert 1646915753.000208807, sequence: 1, clear 0.000000000, sequence: 0 - using: assert
gpsd:PROG: KPPS:/dev/ttyS0 Assert cycle: 1646915753000208, duration: 0 @ 1646915753.000208807
gpsd:RAW: PPS:/dev/ttyS0 Assert pps-detect changed to 1
gpsd:PROG: PPS:/dev/ttyS0 Assert cycle: 1646915753000208, duration: 0 @ 1646915753.000208807
gpsd:PROG: PPS:/dev/ttyS0 Assert ignored missing last_fixtime
gpsd:PROG: KPPS:/dev/ttyS0 assert 1646915753.000208807, sequence: 1, clear 1646915753.100149920, sequence: 1 - using: clear
gpsd:PROG: KPPS:/dev/ttyS0 Clear cycle: 99941, duration: 99941 @ 1646915753.100149920
gpsd:RAW: PPS:/dev/ttyS0 Clear pps-detect changed to 0
gpsd:PROG: PPS:/dev/ttyS0 Clear cycle: 99941, duration: 99941 @ 1646915753.100149920
gpsd:PROG: PPS:/dev/ttyS0 Clear ignored missing last_fixtime
gpsd:SPIN: pselect() {3 4 6} -> { 6 } at 1646915753.130428717 (Success)
gpsd:SPIN: packet_get() fd 6 -> 9 (0)
gpsd:RAW: packet sniff on /dev/ttyS0 finds type -1
gpsd:INFO: reconnection attempt on device 1
gpsd:PROG: no /etc/gpsd/device-hook present, skipped running ACTIVATE hook. No such file or directory
gpsd:ERROR: SER: stat(/dev/pps0) failed: No such file or directory(2)
gpsd:ERROR: /dev/pps0: device activation failed, freeing device.
gpsd:SPIN: pselect() {3 4 6} -> { 6 } at 1646915753.131202895 (Success)
gpsd:SPIN: packet_get() fd 6 -> 9 (0)
gpsd:RAW: packet sniff on /dev/ttyS0 finds type -1
gpsd:SPIN: pselect() {3 4 6} -> { 6 } at 1646915753.132038783 (Success)
gpsd:SPIN: packet_get() fd 6 -> 9 (0)
gpsd:RAW: packet sniff on /dev/ttyS0 finds type -1
gpsd:IO: SER: gpsd_next_hunt_setting(6) retries 0 diff 0
gpsd:SPIN: pselect() {3 4 6} -> { 6 } at 1646915753.132776939 (Success)
gpsd:SPIN: packet_get() fd 6 -> 9 (0)
gpsd:RAW: packet sniff on /dev/ttyS0 finds type -1
gpsd:IO: SER: gpsd_next_hunt_setting(6) retries 1 diff 0
gpsd:SPIN: pselect() {3 4 6} -> { 6 } at 1646915753.133566515 (Success)
gpsd:SPIN: packet_get() fd 6 -> 9 (0)
gpsd:RAW: packet sniff on /dev/ttyS0 finds type -1
gpsd:IO: SER: gpsd_next_hunt_setting(6) retries 2 diff 0
gpsd:SPIN: pselect() {3 4 6} -> { 6 } at 1646915753.134296808 (Success)
gpsd:SPIN: packet_get() fd 6 -> 9 (0)
gpsd:RAW: packet sniff on /dev/ttyS0 finds type -1
gpsd:IO: SER: gpsd_next_hunt_setting(6) retries 3 diff 0
gpsd:SPIN: pselect() {3 4 6} -> { 6 } at 1646915753.135119824 (Success)
gpsd:SPIN: packet_get() fd 6 -> 9 (0)
gpsd:RAW: packet sniff on /dev/ttyS0 finds type -1
gpsd:IO: SER: gpsd_next_hunt_setting(6) retries 4 diff 0
gpsd:SPIN: pselect() {3 4 6} -> { 6 } at 1646915753.135905236 (Success)
gpsd:SPIN: packet_get() fd 6 -> 9 (0)
gpsd:RAW: packet sniff on /dev/ttyS0 finds type 1
gpsd:PROG: switching to match packet type 1: $GPRMC,123553,A,46xx.xxxxx,N,7xx.xxxxx,E,000.0,000.0,100322,000.0,E*70x0dx0a
gpsd:PROG: switch_driver(NMEA0183) called...
gpsd:PROG: selecting NMEA0183 driver...
gpsd:INFO: /dev/ttyS0 identified as type NMEA0183, 1 sec @ 115200bps
gpsd:RAW: raw packet of type 1, 72:$GPRMC,123553,A,46xx.xxxxx,N,7xx.xxxxx,E,000.0,000.0,100322,000.0,E*70x0dx0a
gpsd:IO: <= GPS: $GPRMC,123553,A,46xx.xxxxx,N,7xx.xxxxx,E,000.0,000.0,100322,000.0,E*70
gpsd:DATA: NMEA0183: merge_ddmmyy(100322) sets year 2022
gpsd:RAW: NMEA0183: merge_ddmmyy(100322) 2 10 122
gpsd:DATA: NMEA0183: GPRMC: registers fractional time 123553.000000000
gpsd:DATA: NMEA0183: RMC: ddmmyy=100322 hhmmss=123553 lat=46.95 lon=7.44 speed=0.00 track=0.00 mode=2 var=nan status=0
gpsd:DATA: NMEA0183: GPRMC newtime is 1646915753.000000000 = 2022-03-10T12:35:53.000Z
gpsd:DATA: NMEA0183: GPRMC time 123553.000000000 last 0.000000000 latch 1 cont 0
gpsd:PROG: NMEA0183: GPRMC starts a reporting cycle. lasttag 0
gpsd:SPIN: parse_packet() = {ONLINE|TIME|LATLON|SPEED|TRACK|STATUS|MODE|PACKET|DRIVER|CLEAR|NTPTIME}
gpsd:DATA: packet type 1 from /dev/ttyS0 with {ONLINE|TIME|LATLON|SPEED|TRACK|STATUS|MODE|PACKET|DRIVER|CLEAR|NTPTIME}
gpsd:DATA: all_reports(): changed {ONLINE|TIME|LATLON|SPEED|TRACK|STATUS|MODE|PACKET|DRIVER|CLEAR|NTPTIME}
gpsd:SPIN: packet_get() fd 6 -> 0 (0)
gpsd:RAW: /dev/ttyS0 is known to be NMEA0183
gpsd:PROG: KPPS:/dev/ttyS0 assert 1646915754.000142962, sequence: 2, clear 1646915753.100149920, sequence: 1 - using: assert
gpsd:PROG: KPPS:/dev/ttyS0 Assert cycle: 999934, duration: 899993 @ 1646915754.000142962
gpsd:RAW: PPS:/dev/ttyS0 Assert pps-detect changed to 1
gpsd:PROG: PPS:/dev/ttyS0 Assert cycle: 999934, duration: 899993 @ 1646915754.000142962
gpsd:PROG: PPS:/dev/ttyS0 Assert ignored missing last_fixtime
gpsd:PROG: KPPS:/dev/ttyS0 assert 1646915754.000142962, sequence: 2, clear 1646915754.100056948, sequence: 2 - using: clear
gpsd:PROG: KPPS:/dev/ttyS0 Clear cycle: 999907, duration: 99913 @ 1646915754.100056948
gpsd:RAW: PPS:/dev/ttyS0 Clear pps-detect changed to 0
gpsd:PROG: PPS:/dev/ttyS0 Clear cycle: 999907, duration: 99913 @ 1646915754.100056948
gpsd:PROG: PPS:/dev/ttyS0 Clear ignored missing last_fixtime
gpsd:SPIN: pselect() {3 4 6} -> { 6 } at 1646915754.139262196 (Success)
gpsd:SPIN: packet_get() fd 6 -> 12 (0)
gpsd:RAW: /dev/ttyS0 is known to be NMEA0183
gpsd:RAW: packet sniff on /dev/ttyS0 finds type 1
gpsd:SPIN: pselect() {3 4 6} -> { 6 } at 1646915754.140017104 (Success)
gpsd:PROG: transmission pause. gap 1.004081 quiet_time 0.250000
gpsd:SPIN: packet_get() fd 6 -> 9 (0)
gpsd:RAW: /dev/ttyS0 is known to be NMEA0183
gpsd:RAW: packet sniff on /dev/ttyS0 finds type 1
gpsd:SPIN: pselect() {3 4 6} -> { 6 } at 1646915754.140906731 (Success)
gpsd:SPIN: packet_get() fd 6 -> 10 (0)
gpsd:RAW: /dev/ttyS0 is known to be NMEA0183
gpsd:RAW: packet sniff on /dev/ttyS0 finds type 1
gpsd:SPIN: pselect() {3 4 6} -> { 6 } at 1646915754.141784777 (Success)
gpsd:SPIN: packet_get() fd 6 -> 10 (0)
gpsd:RAW: /dev/ttyS0 is known to be NMEA0183
gpsd:RAW: packet sniff on /dev/ttyS0 finds type 1
gpsd:SPIN: pselect() {3 4 6} -> { 6 } at 1646915754.142634744 (Success)
gpsd:SPIN: packet_get() fd 6 -> 10 (0)
gpsd:RAW: /dev/ttyS0 is known to be NMEA0183
gpsd:RAW: packet sniff on /dev/ttyS0 finds type 1
gpsd:SPIN: pselect() {3 4 6} -> { 6 } at 1646915754.143412923 (Success)
gpsd:SPIN: packet_get() fd 6 -> 9 (0)
gpsd:RAW: /dev/ttyS0 is known to be NMEA0183
gpsd:RAW: packet sniff on /dev/ttyS0 finds type 1
gpsd:SPIN: pselect() {3 4 6} -> { 6 } at 1646915754.144186955 (Success)
gpsd:SPIN: packet_get() fd 6 -> 9 (0)
gpsd:RAW: /dev/ttyS0 is known to be NMEA0183
gpsd:RAW: packet sniff on /dev/ttyS0 finds type 1
gpsd:SPIN: pselect() {3 4 6} -> { 6 } at 1646915754.144838131 (Success)
gpsd:SPIN: packet_get() fd 6 -> 3 (0)
gpsd:RAW: /dev/ttyS0 is known to be NMEA0183
gpsd:RAW: packet sniff on /dev/ttyS0 finds type 1
gpsd:RAW: raw packet of type 1, 72:$GPRMC,123554,A,46xx.xxxxx,N,7xx.xxxxx,E,000.0,000.0,100322,000.0,E*7Bx0dx0a
gpsd:IO: <= GPS: $GPRMC,123554,A,46xx.xxxxx,N,7xx.xxxxx,E,000.0,000.0,100322,000.0,E*7B
gpsd:DATA: NMEA0183: merge_ddmmyy(100322) sets year 2022
gpsd:RAW: NMEA0183: merge_ddmmyy(100322) 2 10 122
gpsd:DATA: NMEA0183: GPRMC: registers fractional time 123554.000000000
gpsd:DATA: NMEA0183: RMC: ddmmyy=100322 hhmmss=123554 lat=46.95 lon=7.44 speed=0.00 track=0.00 mode=2 var=nan status=0
gpsd:DATA: NMEA0183: GPRMC newtime is 1646915754.000000000 = 2022-03-10T12:35:54.000Z
gpsd:DATA: NMEA0183: GPRMC time 123554.000000000 last 123553.000000000 latch 1 cont 0
gpsd:PROG: NMEA0183: GPRMC starts a reporting cycle. lasttag 61
gpsd:PROG: NMEA0183: tagged RMC as a cycle ender. 61
gpsd:PROG: NMEA0183: GPRMC ends a reporting cycle.
gpsd:SPIN: parse_packet() = {ONLINE|TIME|LATLON|SPEED|TRACK|STATUS|MODE|PACKET|CLEAR|REPORT|NTPTIME}
gpsd:DATA: packet type 1 from /dev/ttyS0 with {ONLINE|TIME|LATLON|SPEED|TRACK|STATUS|MODE|PACKET|CLEAR|REPORT|NTPTIME}
gpsd:DATA: all_reports(): changed {ONLINE|TIME|LATLON|SPEED|TRACK|STATUS|MODE|PACKET|CLEAR|REPORT|NTPTIME}
gpsd:SPIN: packet_get() fd 6 -> 0 (0)
gpsd:RAW: /dev/ttyS0 is known to be NMEA0183
...
显然,它成功地建立了共享内存。它还可以读取NMEA数据,提取日期和时间,还可以检测PPS脉冲!当它运行时,它创建了一个设备/dev/pps0
,并且使用sudo ppstest /dev/pps0
,我可以确认PPS脉冲仍然存在。现在,在我的chrony.conf
中,我有这两行
refclock SHM 0 offset 0.5 delay 0.2 refid NMEA noselect
refclock SHM 1 offset 0.0 delay 0.1 refid PPS
所以chrony应该能够读取时间。然而,即使几分钟后,也什么都没有:
$ chronyc sources
MS Name/IP address Stratum Poll Reach LastRx Last sample
===============================================================================
#? NMEA 0 4 0 - +0ns[ +0ns] +/- 0ns
#? PPS 0 4 0 - +0ns[ +0ns] +/- 0ns
然而,我可以确认共享内存段在那里:
$ ipcs -m
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x4e545030 0 root 600 96 2
0x4e545031 1 root 600 96 2
0x4e545032 2 root 666 96 1
0x4e545033 3 root 666 96 1
0x4e545034 4 root 666 96 1
...
那这是怎么回事?我注意到gpsd
将自己的用户更改为nobody
$ ps aux | grep gpsd
root 12667 0.0 0.0 235424 8736 pts/0 S+ 13:41 0:00 sudo gpsd -D 8 -N -b -n /dev/ttyS0 /dev/pps0
nobody 12668 0.3 0.0 17172 4816 pts/0 S<l+ 13:41 0:01 gpsd -D 8 -N -b -n /dev/ttyS0 /dev/pps0
而chronyd
作为用户chrony
:运行
$ ps aux | grep chrony
chrony 12917 0.0 0.0 10600 2972 ? S 13:45 0:00 /usr/sbin/chronyd -F 2
我相信这可能是罪魁祸首,因为共享的记忆属于root
。但我不确定。为什么不能从gpsd获取chrony时间?我还尝试了其他变体,即套接字,但结果相同。
由于/dev/pps0提供了合理的输出,chrony.conf中的这些refclock行可能正是您所需要的:
refclock PPS /dev/pps0 lock NMEA refid GPS
refclock SHM 0 offset 0.5 delay 0.2 refid NMEA noselect
我的系统(Raspberry pi3B+与Adafruit Ultimate GPS HAT版本2(除了默认内容外,在chrony.conf中还有这些非注释行:
pool 0.europe.pool.ntp.org iburst
refclock PPS /dev/pps0 lock NMEA refid GPS
refclock SHM 0 offset 0.5 delay 0.2 refid NMEA noselect
据我所知,PPS系统非常准确地知道第二个边界在哪里,但它不知道边界属于哪个秒。NMEA条目足够准确,可以知道哪一秒正在计时,并将其传递给PPS。"魔法"是意识到"noselect"条目可以帮助引用它的行,而无需直接使用它本身。
Chronyc来源显示
MS Name/IP address Stratum Poll Reach LastRx Last sample
===============================================================================
#* GPS 0 4 17 11 +18ns[ +127ns] +/- 113ns
#? NMEA 0 4 17 13 -120ms[ -120ms] +/- 106ms
^- 169.80-203-110.customer.> 2 6 17 59 +428us[ +575us] +/- 24ms
^- 84.2.46.19 2 6 17 59 -901us[-1185us] +/- 23ms
^- time.erickochen.nl 2 6 17 59 -141us[ -425us] +/- 12ms
^- phouchg.0x2a.io 2 6 17 59 -962us[-1245us] +/- 58ms
^- mail.rettensteiner.com 2 6 17 59 +509us[ +226us] +/- 42ms
^- ip98.mikrocom.sk 2 6 17 58 -1150us[-1433us] +/- 52ms
^- pauseq4vntp2.datamossa.io 2 6 17 58 +1777us[+1494us] +/- 177ms
^- time2.isu.net.sa 2 6 17 60 -23ms[ -23ms] +/- 413ms