ntplogtemp: Record nvme temperatures on Asahi
[ntpsec.git] / docs / driver_howto.adoc
blob9778270d24ec28544a249bb850f53767ab74b872
1 = How to Write a Reference Clock Driver
2 include::include-html.ad[]
4 [cols="10%,90%",frame="none",grid="none",style="verse"]
5 |==============================
6 |image:pic/pogo4.gif[]|
7 {millshome}pictures.html[from 'Pogo', Walt Kelly]
9 You need a little magic.
11 |==============================
13 == Related Links
15 include::includes/misc.adoc[]
17 == Table of Contents
19 * link:#desc[Description]
20 * link:#file[Files Which Need to be Changed]
21 * link:#intf[Interface Routine Overview]
22 * link:#pps[Pulse-per-Second Interface]
24 '''''
26 == When Not to Write a Driver
28 If the device you are trying to support is an exotic GPS, you should
29 probably not write an +ntpd+ driver for it.  Instead, check to see if
30 it is already supported by {GPSD}, a project with which NTPsec
31 cooperates closely.  The GPSD people are specialists in managing GPSes
32 and better at it than we are, supporting a much broader range of
33 devices, and GPSD is designed to feed clock samples to +ntpd+ from any
34 of them.  If you need to write a driver for a GPS, they'll take it and
35 should have it.
37 If you have a non-GPS time source (like a time radio or GPSDO) that
38 you want to support, consider link:generic_howto.html[writing a mode
39 for it in the generic driver] rather than a full driver of its own;
40 this will be easier.  The generic driver is so called because it
41 factors out a lot of I/O and housekeeping code common to all drivers,
42 allowing you support a new device type by writing only a parser for
43 its sentences.
45 [[desc]]
46 == Structure of a Driver
48 NTP reference clock support maintains the fiction that the clock is
49 actually an ordinary server in the NTP tradition, but operating at a
50 synthetic stratum of zero. The entire suite of algorithms filter the
51 received data and select the best sources to correct the system clock.
52 No packets are exchanged with a reference clock; however, the transmit,
53 receive and packet procedures are replaced with code to simulate them.
55 The driver assumes three timescales: standard time maintained by a
56 distant laboratory such as USNO or NIST, reference time maintained by
57 the external radio and the system time maintained by NTP. The radio
58 synchronizes reference time via radio, satellite or modem. As the
59 transmission means may not always be reliable, most radios continue to
60 provide clock updates for some time after signal loss using an internal
61 reference oscillator. In such cases the radio may or may not reveal the
62 time since last synchronized or the estimated time error.
64 All three timescales run only in Coordinated Universal Time (UTC) and
65 are not adjusted for local timezone or standard/daylight time. The local
66 timezone, standard/daylight indicator and year, if provided, are
67 ignored. However, it is important to determine whether a leap second is
68 to be inserted in the UTC timescale in the near future so NTP can insert
69 it in the system timescale at the appropriate epoch.
71 The interface routines in the +ntp_refclock.c+ source file call the
72 following driver routines via a transfer vector:
74 +startup+::
75   The association has just been mobilized. The driver may allocate a
76   private structure and open the device(s) required.
77 +shutdown+::
78   The association is about to be demobilized. The driver should close
79   all device(s) and free private structures.
80 +receive+::
81   A timecode string is ready for retrieval using the +refclock_gtlin()+
82   or +refclock_gtraw()+ routines and provide clock updates.
83 +poll+::
84   Called at poll timeout, by default 64 s. Ordinarily, the driver will
85   send a poll sequence to the radio as required.
86 +timer+::
87   Called once per second. This can be used for housekeeping functions.
88   In the case with pulse-per-second (PPS) signals, this can be used to
89   process the signals and provide clock updates.
91 The receive routine retrieves a timecode string via serial or parallel
92 port, PPS signal or other means. It decodes the timecode in days, hours,
93 minutes, seconds and nanoseconds and checks for errors. It provides
94 these data along with the on-time timestamp to the +refclock_process+
95 routine, which saves the computed offset in a 60-sample circular buffer.
96 On occasion, either by timeout, sample count or call to the poll
97 routine, the driver calls +refclock_receive+ to process the circular
98 buffer samples and update the system clock.
100 The best way to understand how the clock drivers work is to study one of
101 the drivers already implemented, such as +refclock_spectracom.c+. The
102 main interface is the +refclockproc+ structure, which contains for most
103 drivers the decoded timecode, on-time timestamp, reference timestamp,
104 exception reports and statistics tallies, etc. The support routines are
105 passed a pointer to the +peer+ structure, which contains a pointer to
106 the +refclockproc+ structure, which in turn contains a pointer to the
107 unit structure, if used. For legacy purposes, a table
108 +typeunit[type][unit]+ contains the peer structure pointer for each
109 configured clock type and unit. This structure should not be used for
110 new implementations.
112 Radio and modem reference clocks by convention have addresses of the
113 form +127.127.t.u+, where _t_ is the clock type and _u_ in the range 0-3
114 is used to distinguish multiple instances of clocks of the same type.
115 These addresses used to be exposed as part of the refclock
116 configuration syntax, but are no longer.  Nothing in ntpd now actually
117 requires this form of address for clocks, but it is still generated
118 so as not to hand surprises to legacy +ntpq+ instances that still make
119 the assumption.
121 Most clocks require a serial or parallel port or special bus peripheral.
122 The particular device is normally specified by adding a soft link
123 +/dev/deviceu+ to the particular hardware device.
125 By convention, reference clock drivers are named in the form
126 +refclock_xxxx.c+, where +xxxx+ is a unique string. Each driver is
127 assigned a unique long-form driver name, short-form driver name and
128 device name. The existing assignments are in the
129 link:refclock.html[Reference Clock Drivers] page and its dependencies.
131 == Conventions, Fudge Factors and Flags
133 Most drivers support manual or automatic calibration for systematic
134 offset bias using values encoded in the +refclock+ configuration command.
135 By convention, the +time1+ value defines the calibration offset in
136 seconds. For those drivers that support statistics collection using the
137 +filegen+ utility and the +clockstats+ file, the +flag4+ switch enables
138 the utility.
140 If the calibration feature has been enabled, the +flag1+ switch is set
141 and the PPS signal is actively disciplining the system time, the +time1+
142 value is automatically adjusted to maintain a residual offset of zero.
143 Once the its value has stabilized, the value can be inserted in the
144 configuration file and the calibration feature disabled.
146 [[file]]
147 == Files Which Need to be Changed
149 When a new reference clock driver is installed, the following files need
150 to be edited. Note that changes are also necessary to properly integrate
151 the driver in the configuration and makefile scripts, but these are
152 decidedly beyond the scope of this page.
154 +./include/ntp.h+::
155   The reference clock type defines are used in many places. Each driver
156   is assigned a unique type number. Unused numbers are clearly marked in
157   the list. A unique +REFCLK_xxxx+ identification code should be
158   recorded in the list opposite its assigned type number.
159 +./libntp/clocktypes.c+::
160   The +./libntp/clktype+ array is used by certain display functions. A
161   unique short-form name of the driver should be entered together with
162   its assigned identification code.
163 +./ntpd/ntp_control.c+::
164   The +clocktypes+ array is used for certain control message displays
165   functions. It should be initialized with the reference clock class
166   assigned to the driver, as per the NTP specification RFC 1305. See the
167   +./include/ntp_control.h+ header file for the assigned classes.
168 +./ntpd/refclock_conf.c+::
169   This file contains a list of external structure definitions which are
170   conditionally defined. A new set of entries should be installed
171   similar to those already in the table. The +refclock_conf+ array is a
172   set of pointers to transfer vectors in the individual drivers. The
173   external name of the transfer vector should be initialized in
174   correspondence with the type number.
176 [[intf]]
177 == Interface Routine Overview
179 +refclock_newpeer+ - initialize and start a reference clock.::
180   Allocates and initializes the interface structure which
181   supports a reference clock in the form of an ordinary NTP peer. A
182   driver-specific support routine completes the initialization, if used.
183   Default peer variables which identify the clock and establish its
184   reference ID and stratum are set here. It returns one if success and
185   zero if the clock address is invalid or already running, insufficient
186   resources are available or the driver declares a bum rap.
187 +refclock_unpeer+ - shut down a clock::
188   Shuts down a clock and returns its resources to the system.
189 +refclock_transmit+ - simulate the transmit procedure::
190   Implements the NTP transmit procedure for a reference
191   clock. This provides a mechanism to call the driver at the NTP poll
192   interval, as well as provides a reachability mechanism to detect a
193   broken radio or other madness.
194 +refclock_process+ - insert a sample in the circular buffer::
195   Saves the offset computed from the on-time timestamp and
196   the days, hours, minutes, seconds and nanoseconds in the circular
197   buffer. Note that no provision is included for the year, as provided
198   by some (but not all) radio clocks. Ordinarily, the year is implicit
199   in the Unix file system and hardware/software clock support, so this
200   is ordinarily not a problem.
201 +refclock_receive+ - simulate the receive and packet procedures::
202   Simulates the NTP receive and packet procedures for a
203   reference clock. This provides a mechanism in which the ordinary NTP
204   filter, selection and combining algorithms can be used to suppress
205   misbehaving radios and to mitigate between them when more than one is
206   available for backup.
207 +refclock_gtraw+, +refclock_gtlin+ - read the buffer and on-time timestamp::
208   These routines return the data received from the clock and the on-time
209   timestamp. The +refclock_gtraw+ routine returns a batch of one or more
210   characters returned by the Unix terminal routines in raw mode. The
211   +refclock_gtlin+ routine removes the parity bit and control characters
212   and returns all the characters up to and including the line
213   terminator. Either routine returns the number of characters delivered.
214 +refclock_open+ - open a serial port for reference clock::
215   Opens a serial port for I/O and sets default options. It
216   returns the file descriptor if success and zero if failure.
217 +refclock_ioctl+ - set serial port control functions::
218   Attempts to hide the internal, system-specific details of
219   serial ports. It can handle POSIX (+termios+), SYSV (+termio+) and BSD
220   (+sgtty+) interfaces with varying degrees of success. The routine
221   returns one if success and zero if failure.
222 +refclock_ppsapi+::
223   Initializes the Pulse-per-Second interface (see below).
224 +refclock_pps+::
225   Called once per second to read the latest PPS offset
226   and save it in the circular buffer (see below).
228 [[pps]]
229 == Pulse-per-Second Interface
231 When the Pulse-per-Second Application Interface (RFC 2783) is present, a
232 compact PPS interface is available to all drivers. See the
233 link:prefer.html[Mitigation Rules and the Prefer Peer] page for further
234 information. To use this interface, include the +timeppps.h+ and
235 +refclock_pps.h+ header files and define the +refclock_ppsctl+ structure
236 in the driver private storage. The +timepps.h+ file is specific to each
237 operating system and may not be available for some systems.
239 To use the interface, call +refclock_ppsapi+ from the startup routine
240 passing the device file descriptor and +refclock_ppsctl+ structure
241 pointer. Then, call +refclock_pps+ from the timer routine passing the
242 association pointer and +refclock_ppsctl+ structure pointer. See the
243 +refclock_pps.c+ file for examples and calling sequences. If the PPS
244 signal is valid, the offset sample will be save in the circular buffer
245 and a bit set in the association flags word indicating the sample is
246 valid and the driver an be selected as a PPS peer. If this bit is set
247 when the poll routine is called, the driver calls the
248 +refclock_receive+ routine to process the samples in the circular
249 buffer and update the system clock.
251 '''''
253 include::includes/footer.adoc[]