Reference clock support maintains the fiction that the clock is actually an ordinary peer in the NTP tradition, but operating at a synthetic stratum of zero. The entire suite of algorithms used to filter the received data, select the best clocks or peers and combine them to produce a local clock correction are operative as with ordinary NTP peers. In this way, defective clocks can be detected and removed from the peer population. As no packets are exchanged with a reference clock, however, we replace the transmit, receive and packet procedures with separate code to simulate them.
Radio and modem reference clocks by convention have addresses in the
127.127.t.u,, where t is the
clock type and u in the range 0-3 is used to distinguish multiple
instances of clocks of the same type. Most clocks require a serial port
or special bus peripheral. The particular device is normally specified
by adding a soft link
/dev/devicedd to the
particular hardware device involved, where
corresponds to the unit number.
The best way to understand how the clock drivers work is to study the
ntp_refclock.c module and one of the drivers already
implemented, such as
maintain the peer variables in a state analogous to an actual peer and
pass received data on through the clock filters. Routines
called to initialize and terminate reference clock associations, should
this ever be necessary. A set of utility routines is included to open
serial devices, process sample data, edit input lines to extract
embedded timestamps and to perform various debugging functions.
The main interface used by these routines is the
refclockproc structure, which contains for most drivers the
decimal equivalents of the year, day, month, hour, second and
millisecond/microsecond decoded from the ASCII timecode. Additional
information includes the receive timestamp, exception report, statistics
tallies, etc. In addition, there may be a driver-specific unit structure
used for local control of the device. The support routines are passed a
pointer to the
peer structure, which is used for all peer-
specific processing and contains a pointer to the
refclockproc structure, which in turn contains a pointer to
the unit structure, if used. A table
contains the peer structure pointer for each configured clock type and
Many drivers support the
ppsclock line disciplines or streams modules described in
the included in the Line Disciplines and Streams
Modules page. The
tty_clk module reduces latency errors
due to the operating system and serial port code in slower systems. The
ppsclock module is an interface for the PPS signal provided
by some radios. It can be connected via a level converter/pulse
generator described in the Gadget Box PPS Level
Converter and CHU Modem page.
By convention, reference clock drivers are named in the form
refclock_xxxx.c, where xxxx is a unique
string. Each driver is assigned a unique type number, long-form driver
name, short-form driver name, and device name. The existing assignments
are in the Reference Clock Drivers page
and its dependencies. Drivers are conditionally compiled using a unique
flag string in the
CLOCKDEFS line described in the Configuration Options page.
The standard clock driver interface includes a set of common support
routines some of which do such things as start and stop the device, open
the serial port, and establish special functions such as PPS signal
support. Other routines read and write data to the device and process
time values. Most drivers need only a little customizing code to, for
instance, transform idiosyncratic timecode formats to standard form,
poll the device as necessary, and handle exception conditions. A
standard interface is available for remote debugging and monitoring
programs, such as
xntpdc, as well as
filegen facility, which can be used to record device
status on a continuous basis.
The interface code and this documentation have been developed over some time and required not a little hard work converting old drivers, etc. Should you find success writing a driver for a new radio or modem service, please consider contributing it to the common good. Send the driver file itself and patches for the other files to Dave Mills (email@example.com).
A new reference clock implementation needs to supply in addition to the driver itself several changes to existing files.
REFCLK_xxxxidentification code should be recorded in the list opposite its assigned type number.
./lib/clktypearray is used by certain display functions. A unique short-form name of the driver should be entered together with its assigned identification code.
clocktypesarray is used for certain control message displays functions. It should be initialized with the reference clock class assigned to the driver, as per the NTP specification RFC-1305. See the
./include/ntp_control.hheader file for the assigned classes.
refclock_confarray is a set of pointers to transfer vectors in the individual drivers. The external name of the transfer vector should be initialized in correspondence with the type number.
refclock_newpeer- initialize and start a reference clock
refclock_unpeer- shut down a clock
refclock_transmit- simulate the transmit procedure
refclock_sample- process a pile of samples from the clock
fudgetime1can be added to the final offset to compensate for various systematic errors. The routine returns one if success and zero if failure due to invalid timecode data or very noisy offsets.
Note that no provision is included for the year, as provided by some (but not all) radio clocks. Ordinarily, the year is implicit in the Unix file system and hardware/software clock support, so this is ordinarily not a problem. Nevertheless, the absence of the year should be considered more a bug than a feature and may be supported in future.
refclock_receive- simulate the receive and packet procedures
refclock_gtlin- groom next input line and extract timestamp
tty_clkline discipline/streams module, it returns that as the timestamp; otherwise, it returns the buffer timestamp. The routine return code is the number of characters in the line.
refclock_open- open serial port for reference clock
refclock_ioctl- set serial port control functions
termios), SYSV (
termio) and BSD (
sgtty) interfaces with varying degrees of success. The routine sets up the
ppsclockstreams module/line discipline, if compiled in the daemon and requested in the call. The routine returns one if success and zero if failure.
refclock_control- set and/or return clock values
fudgetimes, fudgevalues,reference ID and stratum.
refclock_buginfo- return debugging info