summaryrefslogtreecommitdiff
path: root/www/gpsd-time-service-howto.txt
blob: d5caf6197a534a39a16415ecc594911c63e759db (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
= GPSD Time Service HOWTO =
Gary E. Miller <gem@rellim.com>, Eric S. Raymond <esr@thyrsus.com>
v1.0, October 2013

This document is mastered in asciidoc format.  If you are reading it in HTML,
you can find the original at the GPSD project website.

== Introduction ==

GPSD, NTP and a GPS supplying 1PPS (one pulse-per-second) output can be
used to set up a high-quality NTP time server. This HOWTO explains the
method and various options you have in setting it up.

This document is intended to be a comprehensive guide suitable for
people who know little about time service. We encourage others to
contribute additions and corrections.

This document does not attempt to explain all the intricacies of
time service; it is focused on practical advice for one specific
deployment case.  An overview of the protocols can be found at
<<WIKI-NTP>>, and the official NTP FAQ <<NTP-FAQ>> is probably
as gentle an introduction as presently exists.

.Units table
|====================================================
| nSec    | nanoSecond  | 1/1,000,000,000 of a second
| uSec    | microSecond | 1/1,000,000 of a second
| mSec    | milliSecond | 1/1,000 of a second
|====================================================

There are a few important terms we need to define up front.  *Latency*
is delay from a time measurement until a report on it arrives where it
is needed. *Jitter* is short-term variation in latency. *Wobble* is a
jitter-like variation that is long compared to typical measurement
periods.  *Accuracy* is the traceable offset from 'true' time as
defined by a national standard institute.

A good analogy to jitter vs wobble is changes in sea level on a beach.
Jitter is caused by wave action, wobble is the daily effect of tides.
For a time server, the most common cause of wobble is the effect of
daily temperature variations on the oscillators in your equipment.

== How NTP Works ==

NTP (Network Time Protocol) is a set of protocols that attempts to
synchronize computer clocks across the Internet - ultimately,
Universal Coordinated Time (UTC) as defined by several scale-related atomic
clocks run by national standards institutes.  NTP Version 4 is defined
in <<RFC-5905>>.

NTP service daemons running on each host do clock synchronization in
the presence of variable network latency by monitoring those delays in
real time and passing around messages that say, essentially, "I
received your request at time X, I'm sending the reply at time Y and
the propagation delay to my source of time is Z".  Each daemon then
uses rather complex algorithms that we won't attempt to describe here
to digest incoming messages into a composite "NTP time".

NTP conditions your system clock by noticing how your system clock time
differs from deduced NTP time, then speeding up or slowing down your
clock's tick rate until it is synchronized.  These tick-rate changes
are usually extremely small, much too small for a human or even most
software timing loops to ever notice. But large changes are possible.

Most computers are just NTP clients.  They send NTP requests to a set
of servers and use it to adjust the local clock.  It is generally
expected that NTP clients will have an accuracy (that is, maximum
divergence from the master atomic clock) of at most &plusmn;100 mSec,
possibly less depending upon the quality of your network connection.

Some NTP hosts are time *servers*.  These are known as "chimers".
They respond to NTP clients with time read from high-precision
reference clocks (often abbreviated "refclocks") synchronized to
national time standards.  GPSes, because they distribute a single
atomic-clock time basis in a way that is generally accessible, are
widely used as refclocks.

You will hear time service people speak of "Stratum 0" (the reference
clocks) "Stratum 1" (NTP servers directly connected to reference
clocks) and "Stratum 2" (servers that get time from Stratum
1). Stratum 3 chimers redistribute time from Stratum 2, and so
forth. There are defined higher strata up to 15, but you will probably
never see a public chimer higher than Stratum 3 or 4.

Ordinary client computers are normally configured to get time from one
or more Stratum 2 (or less commonly Stratum 3) servers. However, with GPSD and
a suitable GPS device, you can easily condition your clock to higher accuracy
than what you get from typical Stratum 2; with a little effort you can
do better than you can get from most public Stratum 1 servers.

You can then make your high-quality time available to other systems on
your network, or even run a public NTP server.  Anyone can do this;
there is no official authority, and any NTP client may choose to use
your host as a chimer by requesting time from it. The time-service
network is self-regulating, with NTP daemons constantly pruning
statistical outliers so the timebase cannot be accidentally or
deliberately compromised.

In fact many public and widely-trusted Stratum 1 chimers use GPSes as
their Stratum 0, and a significant fraction of those use GPSD in the
way we will describe here.

== 1PPS quality issues ==

GPSD is useful for precision time service because it can use the 1PPS
pulse delivered by some GPSes to discipline (correct) a local NTP
instance.

It's tempting to think one could use a GPS for time service just by 
timestamping the arrival of the first character in the report on each fix
and correcting for a relatively small fixed latency composed of
fix-processing and RS232 transmission time.

Unfortunately, fix reports are often delayed in the receiver and on
the link by as much as several hundred mSec, and this delay is not
constant. This latency varies (jitters) throughout the day.  It may be
stable to 10 mSec for hours and then jump by 200mSec.  Under these
circumstances you can't expect accuracy to UTC much better than 1
second from this method.

For example: SiRF receivers, the make currently most popular in
consumer-grade GPSes, exhibit a wobble of about 170mSec in the offset
between actual top-of-second and the transmission of the first
sentence in each reporting cycle. You can see this graphed at
<<SIRF-WOBBLE>>.

To get accurate time, then, the in-band fix report from the GPS needs
to be supplemented with an out-of-band signal that has a low and
constant latency with respect to the time of of the fix.  GPS
satellites deliver a top-of-GPS-second notification that is nominally
accurate to 50nSec; in capable GPses that becomes the 1PPS signal.

1PPS-capable GPSes use an RS-232 control line to ship the 1PPS
edge of second to the host system (usually Carrier Detect or Ring
Indicator; GPSD will quietly accept either).  Satellite top-of-second
loses some accuracy on the way down due mainly to variable delays in
the ionosphere; processing overhead in the GPS itself adds a bit more
latency, and your local host detecting that pulse adds still more
latency and jitter.  But it's still often accurate to on the order of
1 uSec.

Under most Unixes there are two ways to watch 1PPS; Kernel PPS (KPPS)
and plain PPS latching.  KPPS is an implementation of RFC 2783 <<RFC-2783>>.  
Plain PPS just references the pulse to the system clock as 
measured in user space.  These have different error budgets.  

Kernel PPS uses a kernel function to accurately timestamp the status
change on the PPS line.  Plain PPS has the kernel wake up the PPS
thread and then the PPS thread reads the current system clock.  As
noted in the GPSD code, having the kernel do the time stamp yields
lower latency and less jitter. Both methods have accuracy degraded by
interrupt-processing latency in the kernel serial layer, but plain
PPS incurs additional context-switching overhead that KPPS does not.

With KPPS it is very doable to get the system clock stable to &plusmn;1
uSec.  Otherwise you are lucky to get &plusmn;5 uSec, and there will be
about 20uSec of jitter. All these figures were observed on
plain-vanilla x86 PCS with clock speeds in the 2GHz range.

All the previous figures assume you're using PPS delivered over
RS232.  USB GPSes that deliver 1PPS are rare, but do exist. Notably,
there's the Navsys GR601-W. In case this device goes out of
production it's worth noting that it's a trivial modification of the
stock two-chip-on-a-miniboard commodity-GPS design of engine plus
USB-to-serial adapter; the GR601-W wires a uBlox 6 to a Prolific Logic
PL23203.  To get 1PPS out, just wire the 1PPS pin from the GPS engine to
the Carrier Detect pin on the USB adapter. (This is known as the "Macx-1
mod".)

With this design, 1PPS from the engine will turn into a USB event that
becomes visible to the host system (and GPSD) the next time the USB
device is polled. USB 1.1 polls 1024 slots ever second.  Each slot is
polled in the same order every second.  When a device is added it is
assigned to one of those 1024 polling slots.  It should then be clear
that the accuracy of a USB 1.1 connected GPS would be about 1 mSec.

As of late 2013 no USB GPS we know of implements the higher polling-rate
options in USB 2 and 3.  When one does, and if it has the Macx-1 mod,
higher USB accuracy will ensue.

.Summary of typical accuracy
|=======================================
| GPS atomic clock    |  &plusmn;50nSec 
| KPPS                |  &plusmn;1uSec  
| PPS                 |  &plusmn;5uSec  
| USB poll interval   |  &plusmn;1mSec  
| Network NTP time    |  &plusmn;10mSec 
|=======================================

Observed variations from the typical figure increase towards the
bottom of the table.  Notably, a heavily loaded host system can reduce PPS
accuracy, though not KPPS accuracy except in the most extreme cases.
The USB poll interval tends to be very stable.

Network NTP time accuracy can be degraded below 10mSec by a number of
factors. Almost all have more to do with the quality of your Internet
connection to your chimers than with the acuracy of the chimers
themselves.  Some negatives:

* Having a cable modem.  That is, as opposed to DSL or optical fiber, which
  tend to have less variable latencies.

* Path delay asymmetries due to peering policy.  These can confuse
  NTP's reconciliation algorithms.

With these factors in play, worst-case error can reach up to
&plusmn;100mSec.  Fortunately, errors of over &plusmn;100mSec are very
unusual and should occur only if all your network routes to chimers
have serious problems.

== Choice of Hardware ==

To get 1PPS to your NTP daemon, you first need to get it from a
PPS-capable GPS. As of late 2013 this means either the previously
mentioned GR601-W or a serial GPS with 1PPS.

You can find 1PPS-capable devices supported by GPSD at <<HARDWARE>>.
Note that the most popular consumer-grade GPS engine - SiRF - does not
deliver 1PPS through USB or even RS232.  Thus the usual run of cheap
GPS mice won't do.  In general, you can't use a USB device for time
service unless you know it has the Macx-1 mod.

In the past, the RS232 variant of the Garmin GPS-18 has been very
commonly used for time service.  While it is still a respectable
choice, newer devices have better sensitivity and signal
discrimination. This makes them superior for indoor use as time
sources.

In general, use a GPS with an RS232 interface for time service if you
can.  The GR601-W was designed (by one of the authors, as it happens)
for deployment with commodity TCP/IP routers that only have USB ports.
RS232 is more fiddly to set up (with older devices like the GPS-18 you
may even have to make your own cables) but it can deliver three orders
of magnitude better accuracy and repeatability - enough to meet
prevailing standards for a public Stratum 1 chimer.

Among newer receiver designs we've found the the uBlox 6 receiver used
in the GR601-W to be particularly good.  Very detailed information on
its timing performance can be found at <<UBLOX-TIMING>>. One of us
(Raymond) has recent experience with an eval kit, the EVK 6H-0-001,
that would make an excellent Stratum 0 device. 

Both the EVK 6H and GR601-W are built around the LEA-6H module, which
is a relatively inexpensive but high-quality navigation GPS. We make a
note of this because u-blox also has a specialized timing variant, the
LEA 6T, which would be expensive overkill for an NTP server.

Unfortunately as of late 2013 the LEA-6H is still hard to find in a
packaged RS232 version, as opposed to a bare OEM module exporting TTL
levels or an eval kit like the EVK 6H-0-001 costing upwards of
US$300. Search the web; you may find a here-today-gone-tomorrow offer
on alibaba.com or somewhere similar.

The LEA-6T, and some other higher-end GPS receivers (but not the
LEA-6H) have a stationary mode which, after you initialize it with the
device's location, can deliver time service with only one good
satellite lock (as opposed to the three required for a fix in its
normal mode). For most reliable service we recommend using stationary
mode if your device has it. GPSD tools don't yet directly support
this, but that capability may be added in a future release.

The design of your host system can also affect time quality.  The
&plusmn;5uSec error bound quoted above is for a dual-core or better
system with clock in the 2GHz range on which the OS can schedule the
long-running PPS thread in GPSD on an otherwise mostly unused
processor (the Linux scheduler, in particular, will do this). On a
single-core system, contention with other processes can pile
on several additional microseconds of error.

If you are super-serious about your time-nuttery, you may want to look
into the newest generation of dedicated Stratum 1 microservers being
built out of open-source SBCs like the Raspberry Pi and Beaglebone, or
sometimes with fully custom designs. A representative build is well
described at <<RPI>>.

These microserver designs avoid load-induced jitter by being fully
dedicated to NTP service.  They are small, low-powered devices and
often surprisingly inexpensive, as in costing less than US$100.  They
tend to favor the LEA-6H, and many of them use preinstalled GPSD on
board.

== Enabling PPS ==

gpsd includes support for interpreting the 1PPS pulses; this can be
used to update your time at much higher accuracy than message time provides.
You can determine whether your GPS emits this pulse, and gpsd is
detecting it, by running at -D 5 and watching for carrier-detect state
change messages in the logfile.  In addition, if your kernel provides
the RFC 2783 KPPS (kernel PPS) API gpsd will use that for extra
accuracy.

Note that gpsd assumes that after each fix the GPS will assert
1PPS first and ship sentences reporting time of fix second. Every
GPS we know of does things in this order.  If you ever encounter 
an exception, it should manifest as reported times that look like
they're from the future and require a negative fudge. If this
ever happens, please report the device make and model to the GPSD
maintainers so we can flag it in our GPS hardware database.

Many Linux distributions have a package called "pps-tools" that will
install KPPS support and the time_pps.h header file.  We recommend you
do that.  If your kernel is built in the normal modular way, this
package installation will suffice.

If you are scratch-building your Linux kernel, the configuration 
must include either these two lines, or the same with "y" replaced
by "m" to enable the drivers as modules:

-----------------------------------------------------------------------------
CONFIG_PPS=y
CONFIG_PPS_CLIENT_LDISC=y
-----------------------------------------------------------------------------

Your Linux distribution may ship a file "config-xxxx" in the /boot
directory, which will have a list of the configuration options
that were used to build the kernel.  You can check if the above
options are set. Usually they will be set to "m", which is
sufficient.

Other OSes have different ways to enable KPPS in their kernels.
When we learn what those are, we'll document them or point
at references.

If you're going to use gpsd for time service, you must run in -n mode
so the clock will be updated even when no JSON clients are active.

In order to present the smallest possible attack surface to
privilege-escalation attempts, gpsd, if run as root, drops its root
privileges very soon after startup - just after it has opened any
serial device paths passed on the command line.

Thus, KPPS can only be used with devices passed that way, not with
GPSes that are later presented to gpsd by the hotplug system.  Those
hotplug devices may, however, be able to use plain, non-kernel
PPS. gpsd tries to automatically fall back to this when absence of
root permissions makes KPPS unavailable.

In general, if you start gpsd as other than root, the following things
will happen that degrade the accuracy of reported time:

1. Devices passed on the command line will be unable to use KPPS and
will fall back to the same plain PPS that all hotplug devices must
use, increasing the associated error from ~1 uSec to about ~5 uSec.

2. gpsd will be unable to renice itself to a higher priority.  This
action helps protect it against jitter induced by variable system
load. It's particularly important if your NTP server is a general-use 
computer that's also handling mail or web service or development.

3. The way you have to configure ntpd and chrony will change away
from what we show you here; ntpd will need to be told different
shared-memory segment numbers, and chronyd will need a different
socket location.

You may also find gpsd can't open serial devices at all if your
OS distribution has done "secure" things with the permissions.
 
== Feeding NTPD from GPSD ==

Most Unix systems get their time service through ntpd, a very old and
stable open-source software suite which is the reference
implementation of NTP.  The project home page is <<NTP.ORG>>.

When gpsd receives a sentence with a timestamp, it packages the
received timestamp with current local time and sends it to a
shared-memory segment with an ID known to ntpd, the network time
synchronization daemon.  If ntpd has been properly configured to
receive this message, it will be used to correct the system clock.

When in doubt, the preferred method to start your timekeeping is:

-----------------------------------------------------------------------------
$ su - (or sudo -s )
# killall -9 gpsd ntpd
# ntpd -gN
# sleep 2
# gpsd -n /dev/ttyXX
# sleep 2
# cgps
-----------------------------------------------------------------------------

where /dev/ttyXX is whatever 1PPS-capable device you have.  In a
binary-package-based Linux distribution it is probable that ntpd
will already have brrn launched at boot time.

The rest of these setup instructions will assume that you are starting
gpsd as root, with occasional glances at the non-root case.

Now check to see if gpsd has correctly attached the shared-memory
segments in needs to communicate with ntpd.  ntpd's rules for the
creation of these segments are:

Segments 0 and 1:: 
	 Permissions are 0600 - other programs can only read and
	 write this segment when running as root.

Segments 2 and 3:: 
	 Permissions are 0666 - other programs can read
 	 and write as any user. If ntpd has been
 	 configured to use these segments, any
 	 unprivileged user is allowed to provide data
 	 for synchronisation.

Because gpsd can be started either as root or non-root, it checks and
attaches the more privileged segment pair it can - either 0 and 1 or 2
and 3.

For each GPS receiver that gpsd controls, it will use the attached ntpshm
segments in pairs (for coarse clock and pps source, respectively)
starting from the first found segments.

To debug, try looking at the live segments this way

-----------------------------------------------------------------------------
ipcs -m
-----------------------------------------------------------------------------

If gpsd was started as root, the results  should look like this:

-----------------------------------------------------------------------------
------ Shared Memory Segments --------
 key        shmid      owner      perms      bytes      nattch     status
 0x4e545030 0          root       700        96         2
 0x4e545031 32769      root       700        96         2
 0x4e545032 163842     root       666        96         1
 0x4e545033 196611     root       666        96         1
-----------------------------------------------------------------------------

For a bit more data try this:

-----------------------------------------------------------------------------
cat /proc/sysvipc/shm
-----------------------------------------------------------------------------

If gpsd cannot open the segments, check that you are not running SELinux
or apparmor. Either may require you to configure a security exception.

If you see the shared segments (keys 1314148400 -- 1314148403), and
no gpsd or ntpd is running then try removing them like this:

-----------------------------------------------------------------------------
ipcrm -M 0x4e545030
ipcrm -M 0x4e545031
ipcrm -M 0x4e545032
ipcrm -M 0x4e545033
-----------------------------------------------------------------------------

Here is a minimal sample ntp.conf configuration telling ntpd how to
read the GPS notifications, when gpsd is started as root:

-----------------------------------------------------------------------------
pool us.pool.ntp.org iburst

driftfile /var/lib/ntp/ntp.drift
logfile /var/log/ntp.log

# GPS Serial data reference
server 127.127.28.0 
fudge 127.127.28.0 time1 0.420 refid GPS

# GPS PPS reference
server 127.127.28.1 prefer
fudge 127.127.28.1 refid PPS
-----------------------------------------------------------------------------

The pool statement adds 4 chimers as additional time references needed
by ntpd for redundancy and to give you a reference to see how well your
local GPS is performing.

If you are outside of the USA replace the pool servers with one in your
local area. See <<USE-POOL>> for further information.

Users of ntpd versions older than revision ntp-4.2.5p138 should instead use
this ntp.conf, when gpsd is started as root:

-----------------------------------------------------------------------------
pool us.pool.ntp.org iburst

driftfile /var/lib/ntp/ntp.drift
logfile /var/log/ntp.log

# GPS Serial data reference
server 127.127.28.0 minpoll 4 maxpoll 4
fudge 127.127.28.0 time1 0.420 refid GPS

# GPS PPS reference
server 127.127.28.1 minpoll 4 maxpoll 4 prefer
fudge 127.127.28.1 refid PPS
-----------------------------------------------------------------------------

Users of ntpd versions prior to ntp-4.2.5 do not have the "pool" option.
Alternative configurations exist, but it is recommended that you upgrade
ntpd, if feasible.

The magic pseudo-IP address 127.127.28.0 identifies unit 0 of the ntpd
shared-memory driver; 127.127.28.1 identifies unit 1.  Unit 0 is used
for message-decoded time and unit 1 for the (more accurate, when
available) time derived from combining message-decoded time with the
PPS synchronization pulse.  Splitting these notifications allows ntpd
to use its normal heuristics to weight them. 

(Different units - 2 and 3, respectively - must be used when gpsd is not
started as root.)

With this configuration, ntpd will read the timestamp posted by gpsd
every 64 seconds (16 if non-root) and send it to unit 0.  The number after
the parameter time1 (0.420 in the example above) is a "fudge", offset in seconds.  It's an estimate
of the latency between the time source and the 'real' time. You can use
it to adjust out some of the fixed delays in the system.

To keep ntpd from preferring NMEA time over PPS time, you can add an 
overlarge fudge to the NMEA time.  Or add the suffix 'noselect' so it
is never used, just monitored.

When you start gpsd, it will wait for a few good fixes before
attempting to process PPS.

You may run 'cgps' to verify your GPS has a 3D lock before worrying about
timekeeping.

After starting (as root) ntpd, then gpsd, a listing similar to the one below
should appear as the output of the command "ntpq -p" (after allowing the
GPS to acquire a 3D fix).  This may take up to 30 minutes if your GPS
has to cold start or has a poor skyview.

-----------------------------------------------------------------------------
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
xtime-a.timefreq .ACTS.           1 u   40   64  377   59.228   -8.503   0.516
-bonehed.lcs.mit 18.26.4.106      2 u   44   64  377   84.259    4.194   0.503
+clock.sjc.he.ne .CDMA.           1 u   41   64  377   23.634   -0.518   0.465
+SHM(0)          .GPS.            0 l   50   64  377    0.000    6.631   5.331
-----------------------------------------------------------------------------

If you are running PPS then it may look like this:

-----------------------------------------------------------------------------
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
xtime-a.timefreq .ACTS.           1 u   40   64  377   59.228   -8.503   0.516
-bonehed.lcs.mit 18.26.4.106      2 u   44   64  377   84.259    4.194   0.503
+clock.sjc.he.ne .CDMA.           1 u   41   64  377   23.634   -0.518   0.465
+SHM(0)          .GPS.            0 l   50   64  377    0.000    6.631   5.331
*SHM(1)          .PPS.            0 l   49   64  377    0.000    0.222   0.310
-----------------------------------------------------------------------------

If the value under "reach" for the SHM lines remains zero, check that gpsd is running;
cgps reports a 3D fix; and the '-n' option was used.  Some GPSes
specialized for time service can report time with signal lock on only
one satellite, but with most devices a 3D fix is required.

When the SHM(0) line does not appear at all, check your ntp.conf and
the system logs for error messages from ntpd.

Notice the 1st and 3rd servers, stratum 1 servers, disagree by more than
8 mSec.  The 1st and 2nd servers disagree by over 12 mSec.  Our local
PPS reference agrees to the clock.sjc.he.net server within the expected
jitter of the GR-601W in use.

When no other chimers or local reference clocks appear in the NTP
configuration, the system clock will lock onto the GPS clock, but this
is a fragile setup - you can lose your only time reference if the GPS
is temporarily unable to get satellite lock.

You should always have at least two (preferably four) fallback chimers
in your ntpd.conf for proper ntpd operation, in case your GPS fails to
report time.  The 'pool' command makes this happen.  And you'll need
to adjust the offsets (fudges) in your ntp.conf so the SHM(0) time is
consistent with your other chimers (and other local reference clocks,
if you have any). We'll describe how to diagnose and tune your chimer
configuration in a later section.

The gpsd developers would like to receive information about the
offsets (fudges) observed by users for each type of receiver.  Please
check the GPS hardware table at <<HARDWARE>>; if your GPS is not
present or doesn't have a recommended fudge, send us the output of the
"ntpq -p" command and the make and type of receiver.

== Feeding chrony from GPSD ==

chrony is an alternative open-source implementation of NTP service,
originally designed for systems with low-bandwidth or intermittent
TCP/IP service.  It interoperates with ntpd using the same NTP
protocols.  Unlike ntpd which is designed to always be connected to
multiple internet time sources, chrony is designed for long periods
of offline use.  Like ntpd, it can either operate purely as a client
or provide time service. The chrony project has a home page at
<<CHRONY>>. Its documentation includes an instructive feature comparison
with ntpd at <<CHRONY-COMPARE>>.

gpsd can provide reference clock information to chronyd similarly to
the way it talks to ntpd.  The advantage to using chrony is that the
PPS time resolution is in nanoseconds.  This is 1,000 times more
precision than the microsecond time resolution provided to ntpd.  This
only matters if you has an RS-232 connected 1PPS refclock.  When
gpsd supports the new ntpd protocol this difference will disappear.

gpsd, when run as root, talks to chronyd using a socket named
/var/run/chrony.ttyXX.sock (where ttyXX is replaced by the GPS device
name.  This allows multiple GPS to feed one chronyd.

No gpsd configuration is required to talk to chronyd. chronyd is
configured using the file /etc/chrony.conf or /etc/chrony/chrony.conf.
Check your distributions documentation for the correct location.  To get
chronyd to connect to gpsd using the basic ntpd compatible SHM method
add this to use this basic chrony.conf file:

-----------------------------------------------------------------------------
server 0.us.pool.ntp.org
server 1.us.pool.ntp.org
server 2.us.pool.ntp.org
server 3.us.pool.ntp.org

driftfile /etc/chrony/chrony.drift

# delay 0.0 is right, but use 0.2 to avoid NMEA
# time fighting with PPS time
# or use noprefer and a good offset
refclock SHM 0 offset 0.0 delay 0.2
refclock SHM 1 offset 0.0 delay 0.0 prefer
-----------------------------------------------------------------------------

If you are outside of the USA replace the pool servers with one in your
local area. See <<USE-POOL>> for further information.

The offset option is functionally like ntpd's time1 option, used to 
correct known and constant latency.

To get chronyd to connect to gpsd using the more precise socket 
method add this to your chrony.conf file (replacing ttyXX
with your device name).  

If running as root:

-----------------------------------------------------------------------------
server 0.us.pool.ntp.org
server 1.us.pool.ntp.org
server 2.us.pool.ntp.org
server 3.us.pool.ntp.org

driftfile /etc/chrony/chrony.drift

# delay 0.0 is right, but use 0.2 to avoid NMEA
# time fighting with PPS time
# or use noprefer and a good offset
refclock SHM 0 offset 0.0 delay 0.2
refclock SHM 1 offset 0.0 delay 0.0 noprefer
#refclock PPS
refclock SOCK /var/run/chrony.ttyXX.sock prefer
-----------------------------------------------------------------------------

If not running as root change the "refclock SOCK" line to:

-----------------------------------------------------------------------------
refclock SOCK /tmp/chrony.ttyXX.sock prefer
-----------------------------------------------------------------------------

Finally note that chronyd needs to be started before gpsd so the
socket is ready when gpsd starts up.

If running as root, the preferred starting procedure is:

-----------------------------------------------------------------------------
$ su - (or sudo -s )
# killall -9 gpsd chronyd
# chrony -f /etc/chrony/chrony.conf -s -r
# sleep 2
# gpsd -n /dev/ttyXX
# sleep 2
# cgps
-----------------------------------------------------------------------------

After you have verified with cgps that your GPS has a good 3D lock you
can check how chrony is doing by running 'chronyc sources'.  Your output
will look like this:

-----------------------------------------------------------------------------
# chronyc sources

210 Number of sources = 7
MS Name/IP address         Stratum Poll Reach LastRx Last sample
===============================================================================
#* SHM0                          0   4   377    22  -1646us[-3345us] +/- 100ms
#? SHM1                          0   4   377    19   -126ms[ -126ms] +/- 67us
#? SOC2                          0   4     0   10y     +0ns[   +0ns] +/- 0ns
^? vimo.dorui.net                3   6   377    23   -123ms[ -125ms] +/- 71ms
^? time.gac.edu                  2   6   377    24   -127ms[ -128ms] +/- 55ms
^? 2001:470:1:24f::2:3           2   6   377    24   -122ms[ -124ms] +/- 44ms
^? 142.54.181.202                2   6   377    22   -126ms[ -128ms] +/- 73ms
-----------------------------------------------------------------------------

The stratum is as in ntpq.  The Poll is how many seconds elapse between samples.
The Reach is as in ntpq. LastRx is the time since the last successful
sample.  Last sample is the offset and jitter of the source.

To keep chronyd from preferring NMEA time over PPS time, you can add an 
overlarge fudge to the NMEA time.  Or add the suffix 'noselect' so it
is never used, just monitored.

== NTP performance tuning ==

For good time stability, you should always have at least four other
chimers in your ntpd or chrony configuration besides your GPS
- in case, for example, your GPS is temporarily unable to achieve
satellite lock, or has an attack of temporarity insanity. You can find
public NTP chimers to add to your configuration at <<USE-POOL>>. 

To minimize latency variations, use the national and regional
pool domains for your country and/or nearby ones.  Your ntp.conf
configuration line should probably look like this

-----------------------------------------------------------------------------
pool us.pool.ntp.org iburst
-----------------------------------------------------------------------------

where "us" may be replaced by one of the zone/country codes the Pool
project supports (list behind the "Global" link at <<ZONES>>). The
"pool" tag expands to four randomly chosen servers by default.  "iburst"
implements a fast start algorithm that also weeds out bad servers.

Note that a chimer can be a poor performer for either of three
reasons. It may be shipping bad time, or the best routes between you
and it have large latency variations (jitter), or it may have an asymetric
route, confusing NTP.

The standard tool for tuning ntpd is "ntpq" ("NTP query program"). To
show a list of all servers declared in ntp.conf and their statistics,
invoke it with the "-p" option. On a sample system configured with 7
servers from the NTP pool project and one PPS GPS attached via RS232,
this is the output:

------------------------------------------------------------------------
$ ntpq -p
 remote          refid         st t when poll reach delay offset jitter
========================================================================
-arthur.testserv 162.23.41.56   2 u 62     64 377 5.835 -1.129 8.921
-ntppublic.uzh.c 130.60.159.7   3 u 62     64 377 6.121 -4.102 6.336
-smtp.irtech.ch  162.23.41.56   2 u 35     64 377 15.521 -1.677 8.678
+time2.ethz.ch   .PPS.          1 u 27     64 377 5.938 -1.713 16.404 
-callisto.mysnip 192.53.103.104 2 u 53     64 377 49.357 -0.274 5.125 
-shore.naturalne 122.135.113.81 3 u 22     64 377 14.676 -0.528 2.601 
-ntp.univ-angers 195.220.94.163 2 u 41     64 377 40.678 -1.847 13.391 
+SHM(0)          .GPS.          0 l  4     64 377 0.000 34.682 7.952 
*SHM(1)          .PPS.          0 l  3     64 377 0.000 -2.664 0.457
------------------------------------------------------------------------

The interesting columns are "remote", "st", "reach" and "offset".

"remote" is the name of the remote NTP server. The character in its
first column shows its current state: "-" or "x" for out-of-tolerance
servers, "+" for good servers ("truechimers"), and "*" for the one good
server currently used as the primary reference. The calculations used to
determine a server's state are outside the scope of this document;
details are available in NTPv4 RFC 5905.

"st" shows the remote server's stratum.

"reach" is the octal representation of the remote server's reachability.
A bit is set if the corresponding poll of the server was successful,
i.e. the server returned a reply. New poll results are shifted in from
the least significant bit; results older than 8 polls are discarded. In
the absence of network problems, this should show "377".

"offset" shows the mean offset in the times reported between this local
host and the remote server in milliseconds. This is the value that can
be fudged with the "time1" parameter of the GPS server line in ntp.conf.
If the offset is positive, reduce the time1 value and vice versa.

A more detailed description of the output is available at
<<NTPQ-OUTPUT>>.

In order to determine the correct GPS offset, do the following:

[start=1]
1. Add these lines to ntp.conf:

-----------------------------------------------------------------------------
statsdir /var/log/ntpstats/
statistics peerstats
filegen peerstats file peerstats type day enable
-----------------------------------------------------------------------------

Or, if you are running chronyd add these to chrony.conf:

-----------------------------------------------------------------------------
logdir /var/log/chrony
log statistics measurements tracking
-----------------------------------------------------------------------------

This enables logging of the peer server statistics.

[start=2]
2. Make sure the directory exists properly.  For ntpd as root do:

-----------------------------------------------------------------------------
   # mkdir -p /var/log/ntpstats
   # chown ntp:ntp /var/log/ntpstats
-----------------------------------------------------------------------------

For chronyd as root do:

-----------------------------------------------------------------------------
   # mkdir -p /var/log/chrony
   # chown root:root /var/log/chrony
-----------------------------------------------------------------------------

[start=3]
3. Start ntpd (or chronyd) and let it run for at least four hours.
Periodically check progress with "ntpq -p" or "chronyc sources" and wait
until change has settled out.

[start=4]
4. Calculate the average GPS offset using this script (a copy is
included as contrib/ntpoffset in the GPSD distribution):

-----------------------------------------------------------------------------
awk '
     /127\.127\.28\.0/ { sum += $5 * 1000; cnt++; }
     END { print sum / cnt; }
' </var/log/ntpstats/peerstats
-----------------------------------------------------------------------------

This prints the average offset.

[start=5]
5. Adjust the "time1" value for unit 0 of your ntp.conf (the non-PPS
   channel) by subtracting the average offset from step 4.

6. Restart ntpd.

== Chrony peformance tuning

The easiest way to determine the offset with chronyd is probably to
configure the source whose offset should be measured with the noselect
option and a long poll, let chronyd run for at least 30 minutes and
observe the offset reported in the chronyc sourcestats output. For
example:

SHM 0 configured as:
refclock SHM 0 poll 8 filter 1000 noselect

-----------------------------------------------------------------------------
# chronyc sourcestats
210 Number of sources = 6
Name/IP Address            NP  NR  Span  Frequency  Freq Skew  Offset  Std Dev
==============================================================================
SHM0                       21   9   85m      4.278      4.713   +495ms  8896us
SHM1                       20   8   307      0.000      0.002     +0ns   202ns
mort.cihar.com             21   8   72m      0.148      0.798   +668us   490us
vps2.martinpoljak.net       6   4   17m    -53.200    141.596    -24ms    15ms
ntp1.kajot.cz              25  16   91m     -0.774      1.494    -11ms  1859us
ntp1.karneval.cz           17  10   89m      0.127      0.539  -4131us   574us

In this case (Garmin 18x) the offset specified in the config for the
SHM 0 source should be around 0.495.
-----------------------------------------------------------------------------

== Providing public NTP service ==

<<NTP-FAQ>> has good advice on things to be sure you have done - and
are ready to do - before becoming a public chimer. One detail it
doesn't mention is that you'll need to un-firewall UDP port 123.

If and when you are ready to go public, see <<JOIN-POOL>>. 

== Acknowledgments ==
Beat Bolli <bbolli@ewanet.ch> wrote much of the section on NTP
performance tuning.

== References ==

[bibliography]
- [[[WIKI-NTP]]] http://en.wikipedia.org/wiki/Network_Time_Protocol[Network Time Protocol]

- [[[NTP-FAQ]]] http://www.ntp.org/ntpfaq/[NTP FAQ]

- [[[RFC-5905] http://www.ietf.org/rfc/rfc5905.txt[Network Time Protocol Version 4: Protocol and Algorithms Specification]

- [[[HARDWARE]]] http://catb.org/gpsd/hardware.html[Compatible Hardware]

- [[UBLOX-TIMING]] http://www.u-blox.com/images/downloads/Product_Docs/Timing_AppNote_%28GPS.G6-X-11007%29.pdf[GPS-based timing considerations with u-blox 6 receivers]

- [[[RPI]]] http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html[The Raspberry Pi as a Stratum-1 NTP Server]

- [[[NTP.ORG]]] http://www.ntp.org/[Home of the Network Time Protocol project]

- [[[USE-POOL]]] http://www.pool.ntp.org/en/use.html[How do I use pool.ntp.org?]

- [[[JOIN-POOL]]] http://www.pool.ntp.org/en/join.html[How do I join pool.ntp.org?]

- [[[CHRONY]]] http://chrony.tuxfamily.org/[Chrony Home]

- [[[CHRONY-COMPARE]]] http://chrony.tuxfamily.org/manual.html#Comparison-with-ntpd[ntpd (comparison with chrony)]

- [[[NTPQ-OUTPUT]]] http://nlug.ml1.co.uk/2012/01/ntpq-p-output/831[ntpq output description]

- [[[SIRF-WOBBLE]]] http://www.megapathdsl.net/~hmurray/ntp/GPSSiRF-off.gif[Peer Offset of SiRF units]

- [[[ZONES]]] http://www.pool.ntp.org/zone