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
ntpd
. 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 ntpd
is enabled
by adding flags to the DEFS_LOCAL
line of the
ntpd
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
timeval
format. Both
select()
and SIGIO
are supported by the
routine. The -DTTYCLK
flag is used to compile support for
this discipline in ntpd
. This flag is automatically
included if the clkdefs.h
file is found in the
/usr/include/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
-DCHUCLK
flag is used to
compile support for this discipline in ntpd
. This flag is
automatically included if the chudefs.h
file is found in
the /usr/include/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
ppsclock
module captures a timestamp in Unix
timeval
format for later retrieval using a special
ioctl()
system call. The -DPPS
flag is used to
compile support for this module in ntpd
. 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 versions of both the tty_clk
and
chu_clk
programs. 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 programs are small, unobtrusive, and do
nothing unless specifically enabled by an application program, it
probably doesn't matter which version 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 DisciplineThe 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, be used, as it is the
string terminator. Passing an empty string to CLK_SETSTR
turns off timestamping. Passing NULL
will produce undefined
results.
tty_chu
Line DisciplineThe 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 ModuleThe 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.
On FreeBSD 2.2 and later systems the TIOCDCDTIMESTAMP ioctl is used to read the timestamp when the DCD serial go active. To use this the PPS signal must be tied to the serial port DCD signal through the appropriate level converters and pulse stretch circuitry if necessary. This enhances the accuracy of the driver to a few microseconds. Using FreeBSD 2.2 the measured delay between activation of the PPS signal and the time the timestamp is made on a 66MHz 486DX2 is 19us and on a 100MHz Pentium is 6us. The driver does NOT compensate for this.
The TIOCDCDTIMESTAMP timestamping ioctl() is used automatically on FreeBSD systems if available. It is integrated into the refclock_gtlin() function so any driver using it will benefit from the enhanced accuracy.