1 #+TITLE: Ninfacyzga-1 Time Tracking
2 #+AUTHOR: Steven Baltakatei Sandoval
3 #+EMAIL: baltakatei@gmail.com
6 This document was created by Steven Baltakatei Sandoval on
7 ~2020-07-23T22:27Z~ under a [[https://creativecommons.org/licenses/by-sa/4.0/][Creative Commons BY-SA 4.0 license]]. It
8 was updated by Steven Baltakatei Sandoval on ~2020-10-16T22:26Z~
11 The ~ninfacyzga-01~ device is equipped with an Ozzmaker BerryGPS-IMU
12 module which provides time and location data to ~gpsd~ and ~ntpsec~. The
13 time is provided by GPS satellites which themselves are
14 equipped [fn:nasa_20020408_atomicclock] with atomic clocks. This
15 extremely accurate set of clocks are needed since a GPS receiver
16 calculates its position in space using a General Relativity
17 calculation that uses the small variations in the time stamps received
18 from each satellite. This means that ~gpsd~ may be used to set the
19 system clock without a need for an internet connection to a default
20 Debian time server; ~ninfacyzga-01~ can be its own time server.
22 [fn:nasa_20020408_atomicclock] Title:[[https://science.nasa.gov/science-news/science-at-nasa/2002/08apr_atomicclock/][Tick-Tock Atomic Clock]];
23 Date:2002-04-08; Website:NASA.gov; [[https://web.archive.org/web/20100429141752/http://science.nasa.gov/science-news/science-at-nasa/2002/08apr_atomicclock/][Archive-link]]; Archive-date:
28 Ozzmaker BerryGPS-IMU, Version 3 (see [[https://ozzmaker.com/berrygps-berrygps-imu-quick-start-guide/][ref]]).
30 - [[https://tracker.debian.org/pkg/gpsd][~gpsd~]] : A background daemon app capable of interfacing with the
31 [[https://ozzmaker.com/berrygps-berrygps-imu-quick-start-guide/][Ozzmaker BerryGPS-IMU]]'s GPS submodule. Installed and initialized by
32 ~apt~. Should be installed along with the ~gpsd-clients~
33 package. This procedure was developed with ~gpsd~ version
35 - [[https://tracker.debian.org/pkg/ntpsec][~ntpsec~]] : A security-hardned version of [[https://tracker.debian.org/pkg/ntp][~ntp~]] which is a "[[https://en.wikipedia.org/wiki/Network_Time_Protocol][Network
36 Time Protocol]]" app that synchronizes the system clock with local or
37 remote time servers or devices. It is capable of extracting time
38 data from a GPS signal handled by ~gpsd~. It is also capable of
39 using the high precision PPS (pulse-per-second) signal handled by
40 ~gpsd~. Installed via ~apt~. This procedure was developed with
41 ~ntpsec~ version ~1.1.3~.
43 ** Operating Procedures
45 **** Perform initial setup.
46 See [[file:../setup/README.org][Main Setup]] procedure.
47 **** Install Hardware for time tracking
48 See [[https://ozzmaker.com/forums/topic/connecting-gps-pps-pin/][this]] Ozzmaker forum topic about connecting the BerryGPS-IMU
49 ~T_PULSE~ pin to GPIO 18.
51 #+CAPTION: An image showing how to connect the PPS signal from an Ozzmaker BerryGPS-IMU board to a Raspberry Pi Zero W.
52 #+NAME: fig:PPS_BERRYGPS_RASPIZW
53 [[../../img/Compact_Stratum_1_NTP_time_server_hardware,_October_2020.jpg]]
55 Connect the ~T_PULSE~ connection on the BerryGPS-IMU-3 to GPIO pin 18
56 (ex: with solder and wire) in order to provide the PPS data signal
57 generated by the BerryGPS-IMU to the Raspberry Pi. Processing of this
58 data signal is handled by adding a line to ~/boot/config.txt~ in the
59 next section ("Install Software").
61 Note: If it is desired to specify a custom GPIO pin besides the one
62 recommended, see this [[https://raspberryautomation.com/connect-multiple-ds18b20-temperature-sensors-to-a-raspberry-pi/][Raspberry Autom]] article.
64 **** Install Software for time tracking
65 The time tracking function can be performed by two programs: ~gpsd~
68 Basically, two things need to happen:
70 1. ~gpsd~ needs to be pointed towards the correct device files for
71 incoming GPS data (in NMEA format) and the PPS signal ("pulse per
72 second"; a high precision time signal).
74 2. ~ntpsec~ needs to be pointed towards the correct local IP addresses
75 where ~gpsd~ provides GPS data and the PPS signal.
77 ~gpsd~ then will provide GPS and PPS data to ~ntpsec~ via a "shared
80 ***** Install packages via ~apt~
81 Run the following command to install the required packages.
82 : $ sudo apt install gpsd gpsd-clients python-gps pps-tools ntpsec
84 ***** Enable PPS device
85 Modify the ~/boot/config.txt~ file in order to tell the Raspberry Pi
86 to expect PPS data on ~BCM 18~ (pin number 12; see [[https://pinout.xyz/][link]]). This is done
87 by adding the following line to ~/boot/config.txt~ as described on
88 [[https://ozzmaker.com/forums/topic/problems-with-pps-on-a-pi0w-running-raspian-and-attached-to-a-berrygps-imuv3/][this Ozzmaker page]]:
90 : dtoverlay=pps-gpio,gpiopin=18
92 The ~/boot/config.txt~ file can be modified via:
94 : $ sudo nano /boot/config.txt
96 PPS data can be confirmed by running:
101 trying PPS source "/dev/pps0"
102 found PPS source "/dev/pps0"
103 ok, found 1 source(s), now start fetching data...
104 source 0 - assert 1595708074.003644641, sequence: 219 - clear 0.000000000, sequence: 0
105 source 0 - assert 1595708075.003709620, sequence: 220 - clear 0.000000000, sequence: 0
106 source 0 - assert 1595708076.003779580, sequence: 221 - clear 0.000000000, sequence: 0
107 source 0 - assert 1595708077.003850580, sequence: 222 - clear 0.000000000, sequence: 0
110 Note: For older Raspberry Pi models, it may be necessary to enable
111 ~pps-gpio~ via modifications to ~/etc/modules~ (see [[https://www.raspberrypi.org/forums/viewtopic.php?p=757747#p757747][link]]).
113 ***** Enable GPS device
114 The Ozzmaker BerryGPS-IMU makes NMEA sentences available via the
115 serial "UART" device ~/dev/ttyAMA0~. If bluetooth has not been
116 disabled, the Raspberry Pi OS automatically creates a software "UART"
117 device at ~/dev/serial0~. See the "[[file:~/git-OC/ninfacyzga-01/doc/setup/README.org::*Disable%20Bluetooth][Disable Bluetooth]]" section in the
118 [[file:../setup/README.org][Main Setup]] Initial Startup procedure for instructions on how to
119 disable bluetooth to free up ~/dev/ttyAMA0~ for use by ~gpsd~.
121 Note: Older ~ntp~ documentation indicates that ~ntp~ (and presumably
122 ~ntpsec~ might be able to access GPS data (ex: NMEA sentences) without
123 the aid of ~gpsd~ itself if the data is available at a device named
124 ~/dev/ggp0~. Similarly, the same might apply to PPS data and the
125 ~/dev/gpspps0~ device. However, since the Raspberry Pi OS overlay
126 system automatically creates ~/dev/pps0~ using the modifications to
127 ~/boot/config.txt~ (described [[*Enable PPS device][elsewhere]] in this procedure).
130 See the "[[file:~/git-OC/ninfacyzga-01/doc/location/README.org::*Setup%20~gpsd~][Setup ~gpsd~]]" subsection within the "Initial Startup" section
131 of the Location Logging [[file:~/git-OC/ninfacyzga-01/doc/location/README.org][~README.org~]] file. There is one additional
132 change that must be made which is to add a ~/dev/pps0~ item to the
133 ~DEVICES=~ line in ~/etc/default/gpsd~ like so:
135 : DEVICES="/dev/ttyAMA0 /dev/pps0"
137 ~/dev/ttyAMA0~ is where ~gpsd~ can get NMEA data from the GPS unit.
139 ~/dev/pps0~ is where ~gpsd~ can get a PPS signal.
141 As an example, the following lines will be present in
142 ~/etc/default/gpsd~ if both location and time tracking are set up:
147 DEVICES="/dev/ttyAMA0 /dev/pps0"
152 The ~ntpsec~ configuration file at ~/etc/ntpsec/ntp.conf~ must be
153 modified to tell ~ntpsec~ how to retrieve and interpret the GPS and
154 PPS data provided by ~gpsd~.
156 In summary, lines need to be added telling ~ntpsec~ how often to poll
157 certain sources (local or remote) for time information as well as how
158 to prioritize and label information from each source.
160 ~ntpsec~ uses syntax simplified from that of ~ntp~. Specifically, it
161 recommends use of the ~refclock~ keyword for configuring local
162 hardware clocks such as GPS and PPS devices.
164 Below is an example of lines that may be added to
165 ~/etc/ntpsec/ntp.conf~ in order to ensure that the system clock will always have
170 # Kernel PPS (precision seconds; driver 22)
171 refclock pps unit 0 refid kPPS flag3 1 minpoll 4 maxpoll 4 stratum 1
173 # GPS PPS reference (precision seconds; driver 28; root) (NTP1)
174 refclock shm unit 1 refid PPS minpoll 4 maxpoll 4 iburst stratum 1
176 # GPS Serial data reference (coarse time; driver28; root) (NTP0)
177 refclock shm unit 0 refid GPS prefer time1 0.109 minpoll 4 maxpoll 4 iburst stratum 1
179 # GPS PPS reference (precision seconds; driver 28; user) (NTP2)
180 refclock shm unit 2 refid PPSuser minpoll 4 maxpoll 4 iburst stratum 1
182 # Tolerate outliers (useful for coarse clocks)
186 A complete working example of an ~ntp.conf~ file is found in Appendix
189 Commands useful for examining the shared memory driver used by ~gpsd~
192 - ~sudo ntpshmmon~ : Shows live output of data using the shared memory
193 driver. ([[https://gpsd.gitlab.io/gpsd/gpsd-time-service-howto.html][ref]])
195 - ~sudo ipcs -m~ : Show live segments of the shared memory. ([[https://gpsd.gitlab.io/gpsd/gpsd-time-service-howto.html][ref]])
197 General references for this configuration file are:
199 - "Raspberry Pi as a Stratum-1 NTP Server - Updating to the final NTP
200 configuration file" by David Taylor. [[http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html#ntp-conf][Link]]. Date: 2020-03-24. Note:
201 An example of kernel PPS transfer from ~gpsd~ to ~ntp~ via
204 - "GPSD Time Service HOWTO" by Garry E. Miller. [[https://gpsd.gitlab.io/gpsd/gpsd-time-service-howto.html][Link]]. Date:
205 2020-06-28. Note: Explains how shared memory segments available at
206 ~127.127.28.0~, ~127.127.28.1~, ~127.127.28.2~, etc. work in context
207 of an ~ntp~ configuration file.
209 - "Building a Stratum 1 NTP Server with a Raspberry Pi 4 and Adafruit
210 Ultimate GPS Hat". [[http://www.gregledet.net/computers/building-a-stratum-1-ntp-server-with-a-raspberry-pi-4-and-adafruit-ultimate-gps-hat/][Link]]. Date: 2020-02-23. Note: A concise example
211 between ~gpsd~ and ~ntp~ setup for a Raspberry Pi 4 using
212 ~127.127.28.0~ and ~127.127.28.1~. Recommends use of ~ntpsec~
215 Expalantions of some ~ntpsec~ [[https://docs.ntpsec.org/latest/comdex.html][commands and options]] used in the
216 configuration file include:
218 - ~refclock~ : An ~ntpsec~ keyword not present in ~ntp-4.2.8~ that is
219 meant to simplify configuration of reference clocks that use certain
220 [[https://docs.ntpsec.org/latest/refclock.html][drivers]] including ~pps~ ([[https://docs.ntpsec.org/latest/driver_pps.html][PPS Clock Discipline]]), ~shm~ ([[https://docs.ntpsec.org/latest/driver_shm.html][Shared Memory
221 Driver]]) . In ~ntp-4.2.8~ and earlier, in order to configure a clock,
222 instead of ~ntpsec~'s one keyword (~refclock~), two keywords would
223 be required (~server~ and ~fudge~).
225 - ~server [address]~ : Tells ~ntpsec~ the address to query for time
226 information. May be IP address or URL. Additional options such as
227 ~minpoll~, ~maxpoll~, ~prefer~, and ~true~ may be added.
229 - ~prefer~ : Indicates the source should be prioritized in some
230 way. How exactly the ~ntpsec~ mitigation rules (see [[https://docs.ntpsec.org/latest/prefer.html][ref]]) use the
231 ~prefer~ option is complicated but in the context of dealing with a
232 GPS source and a PPS source, the GPS source should have a ~prefer~
233 option. The PPS source may have a ~prefer~ option but it is not
234 necessary; adding ~prefer~ to a PPS source is useful in the corner
235 case that the GPS source is less reliable than another source (ex: a
236 remote clock specified by ~server~).
238 - ~... shm ... flag1 1~ : For an ~shm~ driver, tells ~ntpsec~ to
239 ignore the default sanity check that discards any time that is more
240 than 4-hours off from the system clock. Note that ~ntpsec~ treats
241 ~shm flag1 1~ in the opposite manner as ~ntp~ (see [[https://docs.ntpsec.org/latest/driver_shm.html][ref]]).
243 - ~... shm ... time1 [float]~ : Tells ~ntpsec~ that a latency
244 time of ~[float]~ seconds is required for data to travel from the
245 address to ~ntpsec~ (ex: a USB hub in the case of a GPS device that
246 connects via USB). (see [[https://gpsd.gitlab.io/gpsd/gpsd-time-service-howto.html#_feeding_ntpd_from_gpsd][ref]]) This number of seconds should be
247 adjusted to reduce the `offset` time of the address indicated in the
248 output of the ~ntpq -pn~ command to near ~0.000~. Note that the
249 units of ~offset~ displayed by ~ntpq -pn~ are in milliseconds.
251 - ~... refid [string]~ : Tells ~ntpsec~ a string used to label the source.
253 - ~fudge~ : An ~ntp~ keyword that ~ntpsec~ developers do not recommend
254 using; ~ntpsec~ documentation for ~fudge~ is widthdrawn. For local
255 hardware providing GPS and PPS time information, ~fudge~ can mostly
256 be replaced with use of the ~refclock~ keyword instead.
258 - ~fudge [address]~ : Tells ~ntpsec~ to consider additional options
259 when evaluating the accuracy of time from a given address.
261 - ~fudge [address] ... flag3 1~ : An option that tells ~ntpsec~ to
262 enable "kernel PPS discipline" when interpreting the PPS signal at
263 the address. (see [[http://doc.ntp.org/4.2.8p7/drivers/driver22.html][ref]]).
265 - ~stratum 1~ : Tells ~ntpsec~ to label the source as a "stratum 1"
266 time server. This means that it is a clock using NTP that is a
267 canonical (?) time source. For example, a stratum 0 NTP time server
268 would be an atomic clock. A stratum 1 NTP time server could be a
269 clock that uses a GPS receiver to synchronize to said atomic clock.
271 - ~iburst~ : Tells ~ntpsec~ how often to query a source.
273 - ~fudge [address] ... flag1 [float]~ : See description of ~... shm
276 - ~tos mindist [float]~ : Tells ~ntpsec~ to increase the tolerance for
277 outliers in the clock selection algorithm. Units of ~[float]~ are
278 seconds. The default value is ~0.001~ seconds. This [[http://doc.ntp.org/4.2.6/miscopt.html][reference]]
279 indicates that it is acceptable to raise this value for "clocks with
280 high jitter and a PPS signal". For the device being configured in
281 this guide, this is the case. ~ntpsec~ receives a kernel PPS signal
282 on ~127.127.22.0~ indicating when each second occurs but without
283 information about which second of the day is being ticked. ~ntpsec~
284 receives a coarse time from ~127.127.28.0~ supplied by ~gpsd~ that
285 is derived from the NMEA sentences generated by the GPS receiver;
286 this coarse time (high jitter) lacks the precision of the PPS signal
287 since NMEA sentence transmission times are not well-controlled.
289 ****** Disable DHCP services affecting ~ntpsec~
290 Some processes that use [[https://en.wikipedia.org/wiki/Dynamic_Host_Configuration_Protocol][DHCP]] (Dynamic Host Configuration Protocol) may
291 cause configuration changes to configuration files of ~ntp~. Since
292 ~ntpsec~ is similar to ~ntp~, it is reasonable to take action to
297 : $ sudo rm /etc/dhcp/dhclient-exit-hooks.d/ntp
298 : $ sudo rm /lib/dhcpcd/dhcpcd-hooks/50-ntp.conf
300 In the "request" block of ~dhclient.conf~, remove ~dhcp6.sntp-servers~
303 : $ sudo nano /etc/dhcp/dhclient.conf
305 For example, the following section of ~dhclient.conf~:
308 send host-name = gethostname();
309 request subnet-mask, broadcast-address, time-offset, routers,
310 domain-name, domain-name-servers, domain-search, host-name,
311 dhcp6.name-servers, dhcp6.domain-search, dhcp6.fqdn, dhcp6.sntp-servers,
312 netbios-name-servers, netbios-scope, interface-mtu,
313 rfc3442-classless-static-routes, ntp-servers;
316 should be changed to:
319 send host-name = gethostname();
320 request subnet-mask, broadcast-address, time-offset, routers,
321 domain-name, domain-name-servers, domain-search, host-name,
322 dhcp6.name-servers, dhcp6.domain-search, dhcp6.fqdn,
323 netbios-name-servers, netbios-scope, interface-mtu,
324 rfc3442-classless-static-routes;
327 ***** Disable CPU power saving
328 Power saving featurs of the Raspberry Pi Zero W may also be disabled
329 in order to improve accuracy.
331 ****** Configure CPU ~scaling_governor~
332 If additional precision is required, the PPS signal may be made more
333 reliable at the cost of increasing CPU power by configuring the CPU to
334 always run at maximum frequency.[fn:se_20180320_raspicpugov] This
335 change can be performed by modifying the following file as root:
337 : /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
339 The file should consist of one line. Change
349 This change can be performed via the ~nano~ text editor by running the
353 : # nano /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
355 Additionally, in order to prevent the ~raspi-config~ init script from
356 reverting this text file back to ~ondemand~ after a reboot, this
357 script must be disabled via:
359 : $ sudo systemctl disable raspi-config
361 ****** Configure ~/boot/config.txt~
362 Modify ~/boot/config.txt~ so that it contains these lines in order to
363 disable power saving functions:
366 # Disable power saving
370 [fn:se_20180320_raspicpugov] Title:[[https://raspberrypi.stackexchange.com/questions/9034/how-to-change-the-default-governor]["How to change the default governor?"]]; Author:[[https://raspberrypi.stackexchange.com/users/5538/goldilocks][goldilocks]]; Date: 2018-03-20; Website:stackexchange.com;
375 *** Unscheduled Shutdown
377 *** Example ~ntp.conf~ for ~ntpsec~
378 Below is an example ~ntp.conf~ file for use with ~ntpsec~.
381 # /etc/ntpsec/ntp.conf, configuration for ntpd; see ntp.conf(5) for help
384 driftfile /var/lib/ntpsec/ntp.drift
386 # Leap seconds definition provided by tzdata
387 leapfile /usr/share/zoneinfo/leap-seconds.list
390 #logfile /var/log/ntp.log
393 # You must create /var/log/ntpsec (owned by ntpsec:ntpsec) to enable logging.
394 #statsdir /var/log/ntpsec/
395 #statistics loopstats peerstats clockstats
396 #filegen loopstats file loopstats type day enable
397 #filegen peerstats file peerstats type day enable
398 #filegen clockstats file clockstats type day enable
401 # Comment this out if you have a refclock and want it to be able to discipline
402 # the clock by itself (e.g. if the system is not connected to the network).
403 #tos minclock 4 minsane 3
408 # Kernel PPS (precision seconds; driver 22)
409 refclock pps unit 0 refid kPPS flag3 1 minpoll 4 maxpoll 4 stratum 1
411 # GPS PPS reference (precision seconds; driver 28; root) (NTP1)
412 refclock shm unit 1 refid PPS minpoll 4 maxpoll 4 iburst stratum 1
414 # GPS Serial data reference (coarse time; driver28; root) (NTP0)
415 refclock shm unit 0 refid GPS prefer time1 0.109 minpoll 4 maxpoll 4 iburst stratum 1
417 # GPS PPS reference (precision seconds; driver 28; user) (NTP2)
418 refclock shm unit 2 refid PPSuser minpoll 4 maxpoll 4 iburst stratum 1
420 # Tolerate outliers (useful for coarse clocks)
424 # Specify one or more NTP servers.
426 # pool.ntp.org maps to about 1000 low-stratum NTP servers. Your server will
427 # pick a different set every time it starts up. Please consider joining the
428 # pool: <https://www.pool.ntp.org/join.html>
429 server time.nist.gov iburst
430 server tick.usno.navy.mil iburst
431 server 0.us.pool.ntp.org iburst
432 #server 0.us.pool.ntp.org iburst
433 #server 0.us.pool.ntp.org iburst
434 #server 0.us.pool.ntp.org iburst
435 pool 0.debian.pool.ntp.org iburst
436 #pool 1.debian.pool.ntp.org iburst
437 #pool 2.debian.pool.ntp.org iburst
438 #pool 3.debian.pool.ntp.org iburst
441 # Access control configuration; see /usr/share/doc/ntpsec-doc/html/accopt.html
444 # Note that "restrict" applies to both servers and clients, so a configuration
445 # that might be intended to block requests from certain clients could also end
446 # up blocking replies from your own upstream servers.
448 # By default, exchange time with everybody, but don't allow configuration.
449 restrict default kod nomodify nopeer noquery limited
451 # Local users may interrogate the ntp server more closely.
458 ** Transitional ntp to ntpsec config file snippet
459 # Kernel PPS (precision seconds; driver 22)
460 #server 127.127.22.0 minpoll 4 maxpoll 4 true
461 #fudge 127.127.22.0 flag3 1 refid kPPS stratum 1
462 refclock pps unit 0 refid kPPS flag3 1 minpoll 4 maxpoll 4 stratum 1
464 # GPS PPS reference (precision seconds; driver 28; root) (NTP1)
465 #server 127.127.28.1 minpoll 4 maxpoll 4 iburst
466 #fudge 127.127.28.1 flag1 1 refid PPS
467 refclock shm unit 1 refid PPS minpoll 4 maxpoll 4 iburst stratum 1
469 # GPS Serial data reference (coarse time; driver28; root) (NTP0)
470 #server 127.127.28.0 minpoll 4 maxpoll 4 iburst prefer
471 #fudge 127.127.28.0 flag1 1 time1 0.109 refid GPS stratum 1
472 refclock shm unit 0 refid GPS prefer time1 0.109 minpoll 4 maxpoll 4 iburst stratum 1
474 # GPS PPS reference (precision seconds; driver 28; user) (NTP2)
475 #server 127.127.28.2 minpoll 4 maxpoll 4 iburst
476 #fudge 127.127.28.2 flag1 1 refid PPSuser stratum 1
477 refclock shm unit 2 refid PPSuser minpoll 4 maxpoll 4 iburst stratum 1
479 # Tolerate outliers (useful for coarse clocks)