Lo scopo di questo progetto è ottenere un server ntp stratum 1 utilizzando un Raspberry Pi 4.

cosa ci server:

  • Raspberry Pi 4
  • Memory card con Raspian installato
  • Modulo GPS Adafruit ultimate GPS hat
  • Antenna GPS attiva esterna e convertitore da uFL a SMA
  • Batteria CR1220

adafruit products GPS Board top demo 01 ORIG

 

Questo modulo GPS per funzionare utilizza la porta seriale per trasmettere i dati NMEA e il Pin 4 per il PPS e afinchè funzioni correttamente è necessario procedere come segue:

 

Disabilitiamo tutto ciò che può interferire con la porta seriale, ciò comprende la console e il bluetooth, e configuriamo il PPS. Per fare questo modifichiamo il file /boot/config.txt e aggiungiamo alla fine queste impostazioni:

 

dtoverlay=pi3-disable-bt #disabilita bluetooth
force_turbo=1
dtoverlay=pps-gpio,gpiopin=4 #imposta il pin del PPS

 

modifichiamo in seguito il file /boot/cmdline.txt e cancelliamo "console=serial0,115200" e/o "console=ttyAMA0,115200", e aggiungiamo alla fine nohz=off. nel mio caso il file finale risulta come segue:

dwc_otg.lpm_enable=0 console=tty1 root=PARTUUID=b55c365b-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait quiet splash plymouth.ignore-serial-consoles nohz=off

Modifichiamo il file /etc/modules a ggiungiamo alla fine pps-gpio. il risultato finale sarà il seguente:

# /etc/modules: kernel modules to load at boot time.
#
# This file contains the names of kernel modules that should be loaded
# at boot time, one per line. Lines beginning with "#" are ignored.
i2c-dev
pps-gpio

Creiamo il file /etc/udev/rules.d/99-gps.rules e all'interno inseriamo:

KERNEL=="pps0",SYMLINK+="gpspps0"
KERNEL=="ttyAMA0",SUBSYSTEM=="tty",MODE=="0777", SYMLINK+="gps0"

 

Aggiorniamo il sistema, installiamo i pacchetti necessari e disabilitiamo i servizi che potrebbero influire sul corretto funzionamento:

 

sudo apt update && sudo apt dist-upgrade
sudo systemctl disable hciuart
sudo systemctl disable Questo indirizzo email è protetto dagli spambots. È necessario abilitare JavaScript per vederlo.
sudo dpkg -P bluez pi-bluetooth bluealsa bluez-firmware
sudo apt install pps-tools ntp dnsutils setserial ntpdate

Rimuovere da /etc/dhcp/dhclient.conf ogni riferimento a ntp server (ntp-servers e dhcp6.sntp-servers)

Eliminare /etc/dhcp/dhclient-exit-hooks.d/ntp

sudo rm /etc/dhcp/dhclient-exit-hooks.d/ntp
sudo rm /var/lib/ntp/ntp.conf.dhcp
sudo rm /lib/dhcpcd/dhcpcd-hooks/50-ntp.conf

Affinche tutte le modifiche abbiano effetto è necessario riavviare

una volta riavviato il sistema nella directory /dev troveremo gps0 e pps0, nel primo con un semplice cat /dev/gps0 dovremmo essere in grado di vedere i dati NMEA trasmessi dal modulo gps mentre con sudo ppstest /dev/pps0 troveremo i dati del PPS ad esempio:

pi@raspberrypi:~ $ sudo 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 1562313996.000001112, sequence: 39098 - clear  0.000000000, sequence: 0
source 0 - assert 1562313997.000000798, sequence: 39099 - clear  0.000000000, sequence: 0
source 0 - assert 1562313998.000000736, sequence: 39100 - clear  0.000000000, sequence: 0
source 0 - assert 1562313999.000000859, sequence: 39101 - clear  0.000000000, sequence: 0

 

Se durante il test esce la scritta "Time out" significa che non avete ancora agganciato i satelliti quindi attendete o spostate l'antenna in modo che veda meglio il celo

 

Configuriamo ntp, la versione attuale è già compilata con tutto quello che ci serve quindi non è necessario ricompilare da sorgente.

quindi nel mio /etc/ntp.conf ho i seguenti parametri:

# /etc/ntp.conf, configuration for ntpd; see ntp.conf(5) for help
driftfile /var/lib/ntp/ntp.drift
# Leap seconds definition provided by tzdata
leapfile /usr/share/zoneinfo/leap-seconds.list
# Enable this if you want statistics to be logged.
#statsdir /var/log/ntpstats/
statistics loopstats peerstats clockstats
filegen loopstats file loopstats type day enable
filegen peerstats file peerstats type day enable
filegen clockstats file clockstats type day enable
# Access control configuration; see /usr/share/doc/ntp-doc/html/accopt.html for
# details. The web page
# might also be helpful.
#
# Note that "restrict" applies to both servers and clients, so a configuration
# that might be intended to block requests from certain clients could also end
# up blocking replies from your own upstream servers.
# By default, exchange time with everybody, but don't allow configuration.
restrict default kod notrap nomodify nopeer noquery limited
restrict -6 default kod notrap nomodify nopeer noquery limited
# Local users may interrogate the ntp server more closely.
restrict 127.0.0.1
restrict -6 ::1
# Needed for adding pool entries
restrict source notrap nomodify noquery
restrict 192.168.1.0 mask 255.255.255.0
# If you want to provide time to your local subnet, change the next line.
# (Again, the address is an example only.)
#broadcast 192.168.123.255
# If you want to listen to time broadcasts on your local subnet, de-comment the
# next lines. Please do this only if you trust everybody on the network!
#disable auth
#broadcastclient
server 127.127.22.0 minpoll 4 maxpoll 4
fudge 127.127.22.0 refid PPS
server ntp1.inrim.it iburst prefer
server ntp2.inrim.it iburst
server ntplamezia.ddns.me iburst
server ntp0.as34288.net iburst
server ntp.freestone.net iburst
server ntp1.as34288.net iburst

una volta effettuate le modifiche alla configurazione e riavviato il servizio ntp ( sudo systemctl restart ntp ) il risultato dovrebbe essere simile al seguente,

pi@raspberrypi:~ $ ntpq -crv -pn
associd=0 status=0115 leap_none, sync_pps, 1 event, clock_sync,
version="ntpd Questo indirizzo email è protetto dagli spambots. È necessario abilitare JavaScript per vederlo. (1)", processor="armv7l",
system="Linux/4.19.50-v7l+", leap=00, stratum=1, precision=-20,
rootdelay=0.000, rootdisp=1.075, refid=PPS,
reftime=e0c98afc.6b9758d4  Fri, Jul  5 2019 10:38:20.420,
clock=e0c98b02.3f1e548b  Fri, Jul  5 2019 10:38:26.246, peer=60776, tc=4,
mintc=3, offset=0.001131, frequency=-20.169, sys_jitter=0.000954,
clk_jitter=0.001, clk_wander=0.000, tai=37, leapsec=201701010000,
expire=201912280000
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
o127.127.22.0    .PPS.            0 l    6   16  377    0.000    0.001   0.001
*193.204.114.232 .CTD.            1 u    6   64  377   31.329    0.349   0.190
-193.204.114.233 .CTD.            1 u   32   64  377   30.829    0.912   0.266
-79.36.117.15    .GPS.            1 u   29   64  377   36.767   -1.822  11.026
+2001:4b20::beef 85.158.25.74     2 u   64   64  377   18.049   -0.034   0.914
+2001:67c:8:abcd .PPS.            1 u   25   64  377   31.660    0.244   0.275
-81.94.123.17    85.158.25.74     2 u   52   64  377   21.261   -2.667  17.290

 

Abbiamo così ottenuto un server ntp stratum 1 ma NON è indipendente in quanto necessita di connessione internet per ottenere l'ora di riferimento da un altro server, noi non ci accontentiamo.

Non sono riuscito a interfacciare gpsd in nessun modo con ntp in quanto creava non pochi problemi tra offset e jitter, affinche funzioni tutto correttamente ho proceduto in maniera diversa.

 

sudo systemctl stop gpsd
sudo systemctl disable gpsd
sudo systemctl stop gpsd.socket
sudo systemctl disable gpsd.socket

 

affinchè tutto parta automaticamente e correttamente in caso di riavvio ho modificato il file /etc/rc.local

per il momento il risultato migliore l'ho ottenuto settando i seguenti parametri:

#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.
# Print the IP address
_IP=$(hostname -I) || true
if [ "$_IP" ]; then
  printf "My IP address is %s\n" "$_IP"
fi
systemctl stop ntp
setserial /dev/ttyAMA0 low_latency
/bin/echo -e '$PMTK314,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*29\r\n' > /dev/ttyAMA0 # diable all except GPMRC and GPGGA
/bin/echo -e '$PMTK320,0*26\r\n' > /dev/ttyAMA0 # power saving mode off
/bin/echo -e '$PMTK301,0*2C\r\n' > /dev/ttyAMA0 # No DGPS source
/bin/echo -e '$PMTK313,0*2F\r\n' > /dev/ttyAMA0 # disable SBAS satellite
/bin/echo -e '$PMTK251,115200*1F\r\n' > /dev/ttyAMA0 #set baud to 115200
stty -F /dev/ttyAMA0 raw 115200 cs8 clocal -cstopb -echo # set serial baud to 115200
systemctl start ntp
exit 0

Riavviate il sistema affinchè le modifiche abbiano effetto altrimenti effettuate le operazioni indicate nel file rc.local manualmente

Dobbiamo ora configurare il servizio ntp affinchè utilizzi i dati forniti dal gps per l'ora, modifichiamo il file /etc/ntp.conf nel modo seguente:


server 127.127.20.0 mode 83 minpoll 4 maxpoll 4 prefer
fudge 127.127.20.0 flag1 1 time2 0.350 refid GPPS
tos mindist 0.002
pool 0.it.pool.ntp.org
pool 1.it.pool.ntp.org
pool 2.it.pool.ntp.org
pool 3.it.pool.ntp.org

 

per intenderci il risultato del file sarà il seguente

# /etc/ntp.conf, configuration for ntpd; see ntp.conf(5) for help
driftfile /var/lib/ntp/ntp.drift
# Leap seconds definition provided by tzdata
leapfile /usr/share/zoneinfo/leap-seconds.list
# Enable this if you want statistics to be logged.
#statsdir /var/log/ntpstats/
statistics loopstats peerstats clockstats
filegen loopstats file loopstats type day enable
filegen peerstats file peerstats type day enable
filegen clockstats file clockstats type day enable
# Access control configuration; see /usr/share/doc/ntp-doc/html/accopt.html for
# details.  The web page <http://support.ntp.org/bin/view/Support/AccessRestrictions>
# might also be helpful.
#
# Note that "restrict" applies to both servers and clients, so a configuration
# that might be intended to block requests from certain clients could also end
# up blocking replies from your own upstream servers.
# By default, exchange time with everybody, but don't allow configuration.
restrict default kod notrap nomodify nopeer noquery limited
restrict -6 default kod notrap nomodify nopeer noquery limited
# Local users may interrogate the ntp server more closely.
restrict 127.0.0.1
restrict -6 ::1
# Needed for adding pool entries
restrict source notrap nomodify noquery
# Clients from this (example!) subnet have unlimited access, but only if
# cryptographically authenticated.
restrict 192.168.1.0 mask 255.255.255.0
# If you want to provide time to your local subnet, change the next line.
# (Again, the address is an example only.)
#broadcast 192.168.123.255
# If you want to listen to time broadcasts on your local subnet, de-comment the
# next lines.  Please do this only if you trust everybody on the network!
#disable auth
#broadcastclient
server 127.127.20.0 mode 83 minpoll 4 maxpoll 4 iburst prefer
fudge 127.127.20.0 flag1 1 time2 0.350 refid GPS
# Minimum distance used by the selection algorithm, default is .001 s.

tos mindist 0.002
pool 0.it.pool.ntp.org
pool 1.it.pool.ntp.org
pool 2.it.pool.ntp.org
pool 3.it.pool.ntp.org

 

Riavviamo il servizio

 

sudo systemctl stop ntp
sudo systemctl start ntp

 

Fatto questo dovremmo ottenere quando segue:

pi@raspberrypi:~ $ ntpq -crv -pn
associd=0 status=0415 leap_none, sync_uhf_radio, 1 event, clock_sync,
version="ntpd Questo indirizzo email è protetto dagli spambots. È necessario abilitare JavaScript per vederlo. (1)", processor="armv7l",
system="Linux/4.19.50-v7l+", leap=00, stratum=1, precision=-19,
rootdelay=0.000, rootdisp=1.000, refid=GPS,
reftime=e0ca4824.662daa2f  Sat, Jul  6 2019  0:05:24.399,
clock=e0ca4824.b4ded91c  Sat, Jul  6 2019  0:05:24.706, peer=44792, tc=4,
mintc=3, offset=-0.006248, frequency=-18.960, sys_jitter=0.001907,
clk_jitter=0.002, clk_wander=0.002, tai=37, leapsec=201701010000,
expire=201912280000
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
o127.127.20.0    .GPS.            0 l    -   16  377    0.000   -0.006   0.002
 0.it.pool.ntp.o .POOL.          16 p    -   64    0    0.000    0.000   0.002
 1.it.pool.ntp.o .POOL.          16 p    -   64    0    0.000    0.000   0.002
 2.it.pool.ntp.o .POOL.          16 p    -   64    0    0.000    0.000   0.002
 3.it.pool.ntp.o .POOL.          16 p    -   64    0    0.000    0.000   0.002
+212.45.144.3    193.204.114.232  2 u    7   64  377   12.093    0.450   0.766
-212.45.144.88   193.204.114.233  2 u    8   64  377   14.580   -0.698  14.404
#80.211.178.99   216.239.35.4     2 u   15   64  377   19.291   -7.537   6.057
#185.19.184.35   193.204.114.233  2 u    7   64  377   22.121    3.802  57.602
-2a00:6d40:40:45 81.2.248.189     3 u    2   64  377   29.596    2.064   0.830
+94.177.187.22   193.204.114.233  2 u    -   64  377   17.269    0.168   0.564
-2a00:6d40:72:73 85.199.214.99    2 u    3   64  377   32.497   -0.594  53.941
#2a00:6d40:60:74 193.204.114.233  2 u    8   64  377   32.245   -0.466  54.263
-2a00:dcc0:dead: 193.204.114.232  2 u    6   64  377   20.967    0.600  14.194
+80.211.82.90    185.19.184.35    3 u   11   64  377   18.123   -1.208   4.013
-151.3.106.211   172.16.0.100     3 u   59   64  377    0.125    0.198   0.035
-80.211.155.206  193.204.114.233  2 u   63   64  377   19.422    1.295   0.153
-188.213.165.209 193.204.114.233  2 u   66   64  377   18.214    0.632   3.939

 

Come potete notare a questo punto ntpd ha rilevato e sta utilizzando i dati dal GPS e integrando il PPS (o). lo si può notare anche verificando l'uso dei device con

pi@raspberrypi:~ $ sudo lsof /dev/pps0 /dev/gps0
COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
ntpd    11340  ntp    4u   CHR 204,64      0t0 1165 /dev/ttyAMA0
ntpd    11340  ntp    5u   CHR  242,0      0t0 1495 /dev/pps0

 

precisazioni:

127.127.22.0 non è un indirizzo ip bensì il driver che utilizzerà ntp per comunicare con il PPS

127.127.20.0 non è un indirizzo ip bensì il driver che utilizzerà ntp per comunicare con il GPS

fudge 127.127.20.0 flag1 1 <- questo flag dice a ntp di usare il PPS 

 mode 83 = GPMRC + GPGGA + 115200

rif.:https://www.eecis.udel.edu/~mills/ntp/html/refclock.html

rif.:https://www.eecis.udel.edu/~mills/ntp/html/drivers/driver22.html

rif.:https://www.eecis.udel.edu/~mills/ntp/html/drivers/driver28.html

rif.https://learn.adafruit.com/adafruit-ultimate-gps-hat-for-raspberry-pi/overview