HCL:Raspberry Pi3 GPS
This is a guide for setting up a Raspberry Pi3 as a local time server with a GPS module with pps output and configuring the gpsd and chrony services. It also disables the onboard bluetooth to use /dev/ttyAMA0 for the gps feed.
NOTE: There is no reason you can't use a USB gps, all that is needed is a pps output from the device to the selected gpio pin and modification of the dt overlay.
GPS Module
As long as the gps module has pps out it should work fine. For example a NEO-6M (Arduino GPS, Drone Microcontroller GPS Receiver) Compatible with 51 Microcontroller STM32 Arduino UNO R3 with IPEX Antenna High Sensitivity for Navigation Satellite Positioning for creating this HCL entry.
Device Tree (DT) overlay
The GPS module PPS output needs to be activated with a Device Tree (DT) overlay.
The configuration for this is located at /boot/efi/extraconfig.txt
. GPIO pin 18 was chosen for its location next to the tx and rx pins for the gps.
dtparam=spi=on dtoverlay=disable-bt dtoverlay=pps-gpio,gpiopin=18 core_freq=250 force_turbo=1
YaST Bootloader changes
Start YaST Bootloader and modify default from;
GRUB_CMDLINE_LINUX_DEFAULT="loglevel=3 splash=silent plymouth.enable=0 console=ttyS0,115200n8"
To;
GRUB_CMDLINE_LINUX_DEFAULT="loglevel=3 splash=silent plymouth.enable=0 console=tty1"
Now reboot the system and check for the pps and AMA0 devices are present, for example;
dmesg |egrep "ttyAMA0|pps0" [ 4.939465] 3f201000.serial: ttyAMA0 at MMIO 0x3f201000 (irq = 66, base_baud = 0) is a PL011 rev2 [ 20.034296] pps pps0: new PPS source pps@12.-1 [ 20.034388] pps pps0: Registered IRQ 79 as PPS source
If devices are present you can proceed to install the additional gpsd and pps-tools packages, check pps output and configure gpsd and chrony. You can install the gpsd-clients package if desired, but it pulls in considerable packages for the X clients.
zypper in gpsd pps-tools
Test the pps output is functioning;
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 1616795192.000002666, sequence: 19800 - clear 0.000000000, sequence: 0 source 0 - assert 1616795193.000001291, sequence: 19801 - clear 0.000000000, sequence: 0 source 0 - assert 1616795194.000000385, sequence: 19802 - clear 0.000000000, sequence: 0 source 0 - assert 1616795195.000001398, sequence: 19803 - clear 0.000000000, sequence: 0
If data is being seen, then all ok to proceed with further configuration.
GPSD Configuration
In the case of only using ipv4, then you will need to copy the gpsd.service and gpsd.socket to /etc/systemd/system and edit out the ipv6 ListenStream line;
[Unit] Description=GPS (Global Positioning System) Daemon Sockets [Socket] ListenStream=/var/run/gpsd.sock #ListenStream=[::1]:2947 ListenStream=127.0.0.1:2947 SocketMode=0600 [Install] WantedBy=sockets.target
Don't forget to systemctl daemon-reload
after editing!
Edit /etc/sysconfig/gpsd and add the following options;
GPSD_OPTIONS="-G -n -b /dev/ttyAMA0 /dev/pps0"
Now test the gpsd service is starting and no errors seen;
systemctl start gpsd systemctl status gpsd ● gpsd.service - GPS (Global Positioning System) Daemon Loaded: loaded (/etc/systemd/system/gpsd.service; disabled; vendor preset: disabled) Active: active (running) since ... TriggeredBy: ● gpsd.socket Main PID: 697 (gpsd) Tasks: 3 CGroup: /system.slice/gpsd.service └─697 /usr/sbin/gpsd -G -n -b /dev/ttyAMA0 /dev/pps0 Feb 08 06:00:19 host systemd[1]: Starting GPS (Global Positioning System) Daemon... Feb 08 06:00:19 host systemd[1]: Started GPS (Global Positioning System) Daemon.
If no errors reported, enable the service to start on boot.
systemctl enable gpsd
Chronyd Configuration
Create a new file in /etc/chrony.d/
called for example gps_time.conf
at a minimum you need the two gps refclock sources, allow local access and allow local sync.
# Add gps and pps as reference clock refclock SHM 0 delay 0.5 refid NMEA refclock PPS /dev/pps0 refid PPS # Allow NTP client access from local network. allow xxx.xxx.xxx.xxx/xx # Serve time even if not synchronized to a time source. local stratum 10
Testing
Now restart chronyd and as long as no errors can proceed to test.
Check that the NMEA (a -) and PPS (a *) sources are synced via the following command;
chronyc sources -v 210 Number of sources = 6 .-- Source mode '^' = server, '=' = peer, '#' = local clock. / .- Source state '*' = current synced, '+' = combined , '-' = not combined, | / '?' = unreachable, 'x' = time may be in error, '~' = time too variable. || .- xxxx [ yyyy ] +/- zzzz || Reachability register (octal) -. | xxxx = adjusted offset, || Log2(Polling interval) --. | | yyyy = measured offset, || \ | | zzzz = estimated error. || | | \ MS Name/IP address Stratum Poll Reach LastRx Last sample =============================================================================== #- NMEA 0 4 3 13 +142ms[ +149ms] +/- 250ms #* PPS 0 4 203 12 +502ns[+7004us] +/- 155us ^- 097-091-222-080.res.spec> 1 6 37 60 -4234us[+2769us] +/- 34ms ^- autoforward.com 3 6 37 60 -10ms[-3351us] +/- 91ms ^- ntp3.junkemailfilter.com 2 6 37 60 -11ms[-4557us] +/- 85ms ^- clock.trit.net 2 6 37 60 -3607us[+3321us] +/- 64ms
Now as a final check use the tracking and serverstats options;
chronyc tracking Reference ID : NNNNNNNN (PPS) Stratum : 1 Ref time (UTC) : Tue Mar 30 22:16:28 2021 System time : 0.000000199 seconds slow of NTP time Last offset : -0.000000152 seconds RMS offset : 0.000510382 seconds Frequency : 4.773 ppm fast Residual freq : -0.000 ppm Skew : 0.012 ppm Root delay : 0.000000001 seconds Root dispersion : 0.000011117 seconds Update interval : 16.0 seconds Leap status : Normal chronyc serverstats NTP packets received : 37 NTP packets dropped : 0 Command packets received : 38 Command packets dropped : 0 Client log records dropped : 0
Now for another reboot and check the services start and chronyc outputs are correct. Depending on the module used it can take some minutes.
Client Configuration
To add the new time server to local machines this can be done on openSUSE systems via YaST ntp-client or add to /etc/chrony.d/pool.conf;
pool <server fqdn or ip address> iburst
The same chronyc tests can be performed on the client to verify it's syncing with the Raspberry Pi3 time server;
chronyc tracking Reference ID : NNNNNNNN (<hostname>) .... chronyc sources 210 Number of sources = 3 MS Name/IP address Stratum Poll Reach LastRx Last sample =============================================================================== ^* hostname 1 9 377 377 +31us[ +24us] +/- 198us ^- time-a-g.nist.gov 1 9 377 53 -5135us[-5135us] +/- 34ms ^- time-b-g.nist.gov 1 9 377 241 -4242us[-4242us] +/- 33ms