You need a little magic.
Last update: 11-Jul-2009 20:44
NTP reference clock support maintains the fiction that the clock is actually an ordinary server in the NTP tradition, but operating at a synthetic stratum of zero. The entire suite of algorithms filter the received data and select the best sources to correct the system clock. No packets are exchanged with a reference clock; however, the transmit, receive and packet procedures are replaced with code to simulate them.
The driver assumes three timescales: standard time maintained by a distant laboratory such as USNO or NIST, reference time maintained by the external radio and the system time maintained by NTP. The radio synchronizes reference time via radio, satellite or modem. As the transmission means may not always be reliable, most radios continue to provide clock updates for some time after signal loss using an internal reference oscillator. In such cases the radio may or may not reveal the time since last synchronized or the estimated time error.
All three timescales run only in Coordinated Universal Time (UTC) and are not adjusted for local timezone or standard/daylight time. The local timezone, standard/daylight indicator and year, if provided, are ignored. However, it is important to determine whether a leap second is to be inserted in the UTC timescale in the near future so NTP can insert it in the system timescale at the appropriate epoch.
The interface routines in the ntp_refclock.c source file call the following driver routines via a transfer vector:
The receive routine retrieves a timecode string via serial or parallel port, PPS signal or other means. It decodes the timecode in days, hours, minutes, seconds and nanoseconds and checks for errors. It provides these data along with the on-time timestamp to the refclock_process routine, which saves the computed offset in a 60-sample circular buffer. On occasion, either by timeout, sample count or call to the poll routine, the driver calls refclock_receive to process the circular buffer samples and update the system clock.
The best way to understand how the clock drivers work is to study one of the drivers already implemented, such as refclock_wwvb.c. The main interface is the refclockproc structure, which contains for most drivers the decoded timecode, on-time timestamp, reference timestamp, exception reports and statistics tallies, etc. The support routines are passed a pointer to the peer structure, which contains a pointer to the refclockproc structure, which in turn contains a pointer to the unit structure, if used. For legacy purposes, a table typeunit[type][unit] contains the peer structure pointer for each configured clock type and unit. This structure should not be used for new implementations.
Radio and modem reference clocks by convention have addresses of the form 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 or parallel port or special bus peripheral. The particular device is normally specified by adding a soft link /dev/deviceu to the particular hardware device.
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. All drivers supported by the particular hardware and operating system are automatically detected in the autoconfigure phase and conditionally compiled.
Most drivers support manual or automatic calibration for systematic offset bias using values encoded in the fudge configuration command. By convention, the time1 value defines the calibration offset in seconds. For those drivers that support statistics collection using the filegen utility and the clockstats file, the flag4 switch enables the utility.
If the calibration feature has been enabled, the flag1 switch is set and the PPS signal is actively disciplining the system time, the time1 value is automatically adjusted to maintain a residual offset of zero. Once the its value has stabilized, the value can be inserted in the configuration file and the calibration feature disabled.
When a new reference clock driver is installed, the following files need to be edited. Note that changes are also necessary to properly integrate the driver in the configuration and makefile scripts, but these are decidedly beyond the scope of this page.
When the Pulse-per-Second Application Interface (RFC 2783) is present, a compact PPS interface is available to all drivers. See the Mitigation Rules and the Prefer Peer page for further information. To use this interface, include the timeppps.h and refclock_atom.h header files and define the refclock_atom structure in the driver private storage. The timepps.h file is specific to each operating system and may not be available for some systems.
To use the interface, call refclock_ppsapi from the startup routine passing the device file descriptor and refclock_atom structure pointer. Then, call refclock_pps from the timer routine passing the association pointer and refclock_atom structure pointer. See the refclock_atom.c file for examples and calling sequences. If the PPS signal is valid, the offset sample will be save in the circular buffer and a bit set in the association flags word indicating the sample is valid and the driver an be selected as a PPS peer. If this bit is set when the poll routine is called, the driver calls the refclock_receive routine to process the samples in the circular buffer and update the system clock.