diff options
Diffstat (limited to 'contrib/ntp/html/howto.htm')
-rw-r--r-- | contrib/ntp/html/howto.htm | 320 |
1 files changed, 0 insertions, 320 deletions
diff --git a/contrib/ntp/html/howto.htm b/contrib/ntp/html/howto.htm deleted file mode 100644 index 6e08242..0000000 --- a/contrib/ntp/html/howto.htm +++ /dev/null @@ -1,320 +0,0 @@ -<html><head><title> -How to Write a Reference Clock Driver -</title></head><body><h3> -How to Write a Reference Clock Driver -</h3> - -<img align=left src=pic/pogo4.gif><a href=http://www.eecis.udel.edu/~mills/pictures.htm>from <i>Pogo</i>, Walt Kelly</a> - -<p>You need a little magic. -<br clear=left><hr> - -<h4>Description</h4> - -<p>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 operate just like 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, -the transmit, receive and packet procedures are replaced with separate -code to simulate them. - -<p>Radio and modem reference clocks by convention have addresses in the -form <tt>127.127.<i>t</i>.<i>u</i></tt>, where <i>t</i> is the clock -type and <i>u</i> 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 <tt>/dev/device<i>d</i>d</tt> to the particular -hardware device involved, where <tt><i>d</i></tt> corresponds to the -unit number. - -<p>The best way to understand how the clock drivers work is to study the -<tt>ntp_refclock.c</tt> module and one of the drivers already -implemented, such as <tt>refclock_wwvb.c</tt>. Routines -<tt>refclock_transmit()</tt> and <tt>refclock_receive()</tt> maintain -the peer variables in a state analogous to a network peer and pass -received data on through the clock filters. Routines -<tt>refclock_peer()</tt> and <tt>refclock_unpeer()</tt> are 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. - -<p>The main interface used by these routines is the -<tt>refclockproc</tt> 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. The support routines are passed a pointer to the -<tt>peer</tt> structure, which is used for all peer-specific processing -and contains a pointer to the <tt>refclockproc</tt> structure, which in -turn contains a pointer to the unit structure, if used. For legacy -purposes, a table <tt>typeunit[type][unit]</tt> contains the peer -structure pointer for each configured clock type and unit. - -<p>The reference clock interface supports auxiliary functions to support -in-stream timestamping, pulse-per-second (PPS) interfacing and precision -time kernel support. In most cases the drivers do not need to be aware -of them, since they are detected at autoconfigure time and loaded -automatically when the device is opened. These include the -<tt>tty_clk</tt> and <tt>ppsclock</tt> STREAMS modules and -<tt>ppsapi</tt> PPS interface described in the <a href="ldisc.htm">Line -Disciplines and Streams Modules</a> page. The <tt>tty_clk</tt> module -reduces latency errors due to the operating system and serial port code -in slower systems. The <tt>ppsclock</tt> module is an interface for the -PPS signal provided by some radios. The <tt>ppsapi</tt> PPS interface -replaces the <tt>ppsclock</tt> STREAMS module and is expected to become -the IETF standard cross-platform interface for PPS signals. In either -case, the PPS signal can be connected via a level converter/pulse -generator described in the <a href = "gadget.htm"> Gadget Box PPS Level -Converter and CHU Modem</a> page. - -<p>By convention, reference clock drivers are named in the form -<tt>refclock_<i>xxxx</i>.c</tt>, where <i>xxxx</i> 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 <a href="refclock.htm"> Reference Clock Drivers</a> page -and its dependencies. All drivers supported by the particular hardware -and operating system are automatically detected in the autoconfigure -phase and conditionally compiled. They are configured when the daemon is -started according to the configuration file, as described in the <a -href="config.htm"> Configuration Options </a> page. - -<p>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 <tt>ntpq</tt> and <tt>ntpdc</tt>, as well as -the <tt>filegen</tt> facility, which can be used to record device -status on a continuous basis. - -<p>The general organization of a typical clock driver includes a -receive-interrupt routine to read a timecode from the I/O buffer and -convert to internal format, generally in days, hours, minutes, seconds -and fraction. Some timecode formats include provisions for leap-second -warning and determine the clock hardware and software health. The -interrupt routine then calls <tt>refclock_process()</tt> with these data -and the timestamp captured at the on-time character of the timecode. -This routine saves each sample as received in a circular buffer, which -can store from a few up to 60 samples, in cases where the timecodes -arrive one per second. - -<p>The <tt>refclock_transmit()</tt> routine in the interface is called -by the system at intervals defined by the poll interval in the peer -structure, generally 64 s. This routine in turn calls the transmit poll -routine in the driver. In the intended design, the driver calls the -<tt>refclock_receive()</tt> to process the offset samples that have -accumulated since the last poll and produce the final offset and -variance. The samples are processed by recursively discarding median -outlyers until about 60 percent of samples remain, then averaging the -surviving samples. When a reference clock must be explicitly polled to -produce a timecode, the driver can reset the poll interval so that the -poll routine is called a specified number of times at 1-s intervals. - -<p>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 -(mills@udel.edu). - -<h4>Conventions, Fudge Factors and Flags</h4> - -<p>Most drivers support manual or automatic calibration for systematic -offset bias using values encoded in the <tt>fudge</tt> configuration -command. By convention, the <tt>time1</tt> value defines the calibration -offset in seconds. For those drivers that support statistics collection -using the <tt>filegen</tt> utility and the <tt>clockstats</tt> file, the -<tt>flag4</tt> switch enables the utility. When a PPS signal is -available, a special automatic calibration facility is provided. If the -<tt>flag1</tt> switch is set and the PPS signal is actively disciplining -the system time, the calibration value is automatically adjusted to -maintain a residual offset of zero. Should the PPS signal or the prefer -peer fail, the adjustment is frozen and the remaining drivers continue -to discipline the system clock with a minimum of residual error. - -<h4>Files Which Need to be Changed</h4> - -<p>A new reference clock implementation needs to supply, in addition to -the driver itself, several changes to existing files. - -<dl> - -<dt><tt>./include/ntp.h</tt> -<dd>The reference clock type defines are used in many places. Each -driver is assigned a unique type number. Unused numbers are clearly -marked in the list. A unique <tt>REFCLK_<i>xxxx</i></tt> -identification code should be recorded in the list opposite its assigned -type number. - -<p><dt><tt>./libntp/clocktypes.c</tt> -<dd>The <tt>./libntp/clktype</tt> array is used by certain display -functions. A unique short-form name of the driver should be entered -together with its assigned identification code. - -<p><dt><tt>./ntpd/ntp_control.c</tt> -<dd>The <tt>clocktypes</tt> array 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 <tt>./include/ntp_control.h</tt> header file for -the assigned classes. - -<p><dt><tt>./ntpd/refclock_conf.c</tt> -<dd>This file contains a list of external structure definitions which -are conditionally defined. A new set of entries should be installed -similar to those already in the table. The <tt>refclock_conf</tt> -array 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. - -<p><dt><tt>./acconfig.h</tt> -<dd>This is a configuration file used by the autoconfigure scheme. Add -two lines in the form: - -<p><pre> - /* Define if we have a FOO clock */ - #undef FOO -</pre> - -<p>where FOO is the define used to cause the driver to be included in -the distribution. - -<p><dt><tt>./configure.in</tt> -<dd>This is a configuration file used by the autoconfigure scheme. Add -lines similar to the following: - -<p><pre> - AC_MSG_CHECKING(FOO clock_description) - AC_ARG_ENABLE(FOO, [ --enable-FOO clock_description], - [ntp_ok=$enableval], [ntp_ok=$ntp_eac]) - if test "$ntp_ok" = "yes"; then - ntp_refclock=yes - AC_DEFINE(FOO) - fi - AC_MSG_RESULT($ntp_ok) -</pre> - -<p>(Note that <tt>$ntp_eac</tt> is the value from <tt>-- -{dis,en}able-all-clocks</tt> for non-PARSE clocks and -<tt>$ntp_eacp</tt> is the value from <tt>--{dis,en}able-parse- -clocks</tt> for PARSE clocks. See the documentation on the autoconf -and automake tools from the GNU distributions.) - -<p><dt><tt>./ntpd/Makefile.am</tt> -<dd><p>This is the makefile prototype used by the autoconfigure scheme. -Add the driver file name to the entries already in the -<tt>ntpd_SOURCES</tt> list. - -<p>Patches to <tt>automake-1.0</tt> are required for the -autoconfigure scripts to work properly. The file <tt>automake- -1.0.patches</tt> can be used for this purpose. - -<p><dt><tt>./ntpd/Makefile.am</tt> -<dd>Do the following sequence of commands: - -<p><pre> - automake - autoconf - autoheader - configure -</pre> - -<p>or simply run <tt>make</tt>, which will do this command sequence -automatically. - -</dl> - -<p><h4>Interface Routine Overview</h4> - -<dl> - -<dt><tt>refclock_newpeer</tt> - initialize and start a reference -clock -<dd>This routine allocates and initializes the interface structure which -supports a reference clock in the form of an ordinary NTP peer. A -driver-specific support routine completes the initialization, if used. -Default peer variables which identify the clock and establish its -reference ID and stratum are set here. It returns one if success and -zero if the clock address is invalid or already running, insufficient -resources are available or the driver declares a bum rap. -<p><dt><tt>refclock_unpeer</tt> - shut down a clock -<dd>This routine is used to shut down a clock and return its resources -to the system. - -<p><dt><tt>refclock_transmit</tt> - simulate the transmit procedure -<dd>This routine implements the NTP transmit procedure for a reference -clock. This provides a mechanism to call the driver at the NTP poll -interval, as well as provides a reachability mechanism to detect a -broken radio or other madness. - -<p><dt><tt>refclock_sample</tt> - process a pile of samples from the -clock -<dd>This routine converts the timecode in the form days, hours, minutes, -seconds, milliseconds/microseconds to internal timestamp format. It then -calculates the difference from the receive timestamp and assembles the -samples in a shift register. It implements a recursive median filter to -suppress spikes in the data, as well as determine a rough dispersion -estimate. A configuration constant time adjustment -<tt>fudgetime1</tt> can 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. - -<p>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. - -<p><dt><tt>refclock_receive</tt> - simulate the receive and packet -procedures -<dd>This routine simulates the NTP receive and packet procedures for a -reference clock. This provides a mechanism in which the ordinary NTP -filter, selection and combining algorithms can be used to suppress -misbehaving radios and to mitigate between them when more than one is -available for backup. - -<p><dt><tt>refclock_gtlin</tt> - groom next input line and extract -timestamp -<dd>This routine processes the timecode received from the clock and -removes the parity bit and control characters. If a timestamp is present -in the timecode, as produced by the <tt>tty_clk</tt> line -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. - -<p><dt><tt>refclock_open</tt> - open serial port for reference clock -<dd>This routine opens a serial port for I/O and sets default options. -It returns the file descriptor if success and zero if failure. - -<p><dt><tt>refclock_ioctl</tt> - set serial port control functions -<dd>This routine attempts to hide the internal, system-specific details -of serial ports. It can handle POSIX (<tt>termios</tt>), SYSV -(<tt>termio</tt>) and BSD (<tt>sgtty</tt>) interfaces with -varying degrees of success. The routine sets up the <tt>tty_clk, -chu_clk</tt> and <tt>ppsclock</tt> streams module/line discipline, -if compiled in the daemon and requested in the call. The routine returns -one if success and zero if failure. - -<p><dt><tt>refclock_control</tt> - set and/or return clock values -<dd>This routine is used mainly for debugging. It returns designated -values from the interface structure that can be displayed using ntpdc -and the clockstat command. It can also be used to initialize -configuration variables, such as <tt>fudgetimes, fudgevalues,</tt> -reference ID and stratum. - -<p><dt><tt>refclock_buginfo</tt> - return debugging info -<dd>This routine is used mainly for debugging. It returns designated -values from the interface structure that can be displayed using -<tt>ntpdc</tt> and the <tt>clkbug</tt> command. - -</dl> - -<hr><a href=index.htm><img align=left src=pic/home.gif></a><address><a -href=mailto:mills@udel.edu> David L. Mills <mills@udel.edu></a> -</address></a></body></html> |