Most radio and modem clocks used for a primary (stratum-1) NTP server utilize serial ports operating at speeds of 9600 baud or greater. The timing jitter contributed by the serial port hardware and software driver can accumulate to several milliseconds on a typical Unix workstation. In order to reduce these errors, a set of special line disciplines and stream modules can be configured in the Unix kernel. These routines intercept special characters or signals provided by the radio or modem clock and save a local timestamp for later processing.
The routines can be compiled in the kernel in older BSD-derived
systems, or installed as System V streams modules and either compiled in
the kernel or dynamically loaded when required. In either case, they
require minor changes in some kernel files and in the NTP daemon
xntpd
. The streams modules can be pushed and popped from
the streams stack using conventional System V streams program
primitives. Note that not all Unix kernels support line disciplines and
of those that do, not all support System V streams. The disciplines here
are known to work correctly with SunOS 4.x kernels, but have not been
tested for other kernels.
There are two line disciplines and a special streams module included
in the distribution. Support for each in xntpd
is enabled
by adding flags to the DEFS_LOCAL
line of the
xntpd
configuration file ./Config.local
. This
can be done automatically by the autoconfiguration build procedures, or
can be inserted/deleted after the process has completed.
tty_clk
select()
and
SIGIO
are supported by the routine. The -DCLK
flag is used to compile support for this discipline in
xntpd
. This flag is automatically included if the
clkdefs.h
file is found in the /sys/sys
directory, or it can be added (or deleted) manually. This module must be
configured in the kernel during the kernel build process, as described
in the README
file in the ./kernel
directory.
tty_chu
-DCHU
flag is
used to compile support for this discipline in xntpd
. This
flag is automatically included if the chudefs.h
file is
found in the /sys/sys
directory, or it can be added (or
deleted) manually. This module must be configured in the kernel during
the kernel build process, as described in the README
file
in the ./kernel
directory.
ppsclock
ioctl()
system
call. The -DPPS
flag is used to compile support for this
discipline in xntpd
. This flag is automatically included if
the ppsclock.h
file is found in the /sys/sys
directory, or it can be added (or deleted) manually. This module must
also be configured in the kernel during the kernel build process, as
described in the README
file in the ./kernel
directory.
There are two sets of line disciplines. The tty_clk.c
and chu_clk.c
are designed for use with older BSD systems
and are compiled in the kernel. The tty_clk_STREAMS.c
and
chu_clk_STREAMS.c
are designed for use with System V
streams, in which case they can be either compiled in the kernel or
dynamically loaded. Since these disciplines are small, unobtrusive, and
to nothing unless specifically enabled by an application program, it
probably doesn't matter which method is chosen. Instructions on how to
configure and build a kernel supporting either or both of these line
disciplines is in the README
file in the
./kernel
directory.
tty_clk
Line Discipline
The tty_clk line discipline defines a new ioctl(),
CLK_SETSTR
, which takes a pointer to a string of no more
than 32 characters. Until the first CLK_SETSTR
is
performed, the discipline will simply pass through characters. Once it
is passed a string by CLK_SETSTR
, any character in that
string will be immediately followed by a timestamp in Unix timeval
format. You can change the string whenever you want by doing another
CLK_SETSTR
. The character must be an exact, 8 bit match.
The character '\000' cannot, unfortunately, be used, as it is the string
terminator. Passing an empty string to CLK_SETSTR
turns off
stamping. Passing NULL
will produce undefined results.
tty_chu
Line Discipline
The tty_chu line discipline translates data received from the CHU
modem and returns chucode
structures, as defined in
chudefs.h, and expected by the Scratchbuilt CHU Receiver reference clock
driver. Depending on the settings of PEDANTIC
and
ANAL_RETENTIVE
used when compiling the kernel, some
checking of the data may or may not be necessary.
ppsclock
Stream Module
The ppsclock streams module implements an ioctl()
CIOGETEV
, which takes a pointer to the structure
struct ppsclockev { struct timeval tv; u_int serial; };The ppsclock module is pushed on the streams stack of the serial port connected to the PPS signal. The port must be configured for local operation, rather than remote (modem) operation. At each positive-going edge of the DCD signal, the routine latches the current local timestamp and increments a counter. At each
CIOGETEV ioctl()
call,
the current values of the timestamp and counter are returned in the
ppsclockev
structure.