2b15cb3d09
Thanks to roberto for providing pointers to wedge this into HEAD. Approved by: roberto
254 lines
11 KiB
HTML
254 lines
11 KiB
HTML
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
|
|
|
<html>
|
|
|
|
<head>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
|
<meta name="GENERATOR" content="Mozilla/4.01 [en] (Win95; I) [Netscape]">
|
|
<title>Shared Memory Driver</title>
|
|
<link href="scripts/style.css" type="text/css" rel="stylesheet">
|
|
<style type="text/css">
|
|
table.dlstable { font-size:85%; }
|
|
td.ttf{ font-family:Courier; font-weight:bold; }
|
|
</style>
|
|
</head>
|
|
|
|
<body>
|
|
<h3>Shared Memory Driver</h3>
|
|
<p>Last update:
|
|
<!-- #BeginDate format:En2m -->8-Aug-2014 19:17<!-- #EndDate -->
|
|
UTC</p>
|
|
<hr>
|
|
<h4>Synopsis</h4>
|
|
<p>Address: 127.127.28.<i>u</i><br>
|
|
Reference ID: <tt>SHM</tt><br>
|
|
Driver ID: <tt>SHM</tt></p>
|
|
|
|
<h4>Description</h4>
|
|
<p>This driver receives its reference clock info from a shared
|
|
memory-segment. The shared memory-segment is created with owner-only
|
|
access by default, unless otherwise requested by the mode word for units
|
|
≥2. Units 0 and 1 are always created with owner-only access for
|
|
backward compatibility.
|
|
</p>
|
|
|
|
|
|
<h4>Structure of shared memory-segment</h4>
|
|
<pre>struct shmTime {
|
|
int mode; /* 0 - if valid is set:
|
|
* use values,
|
|
* clear valid
|
|
* 1 - if valid is set:
|
|
* if count before and after read of data is equal:
|
|
* use values
|
|
* clear valid
|
|
*/
|
|
volatile int count;
|
|
time_t clockTimeStampSec;
|
|
int clockTimeStampUSec;
|
|
time_t receiveTimeStampSec;
|
|
int receiveTimeStampUSec;
|
|
int leap;
|
|
int precision;
|
|
int nsamples;
|
|
volatile int valid;
|
|
unsigned clockTimeStampNSec; /* Unsigned ns timestamps */
|
|
unsigned receiveTimeStampNSec; /* Unsigned ns timestamps */
|
|
int dummy[8];
|
|
};</pre>
|
|
|
|
<h4>Operation mode=0</h4>
|
|
<p>Each second, the value of <code>valid</code> of the shared memory-segment is checked:</p>
|
|
<p>If set, the values in the record (clockTimeStampSec, clockTimeStampUSec, receiveTimeStampSec, receiveTimeStampUSec, leap, precision) are passed to <i>NTPD</i>, and <code>valid</code> is cleared and <code>count</code> is bumped.</p>
|
|
<p>If not set, <code>count</code> is bumped.</p>
|
|
<h4>Operation mode=1</h4>
|
|
<p>Each second, <code>valid</code> in the shared memory-segment is checked:</p>
|
|
<p>If set, the <code>count</code> field of the record is remembered, and the values in the record (clockTimeStampSec, clockTimeStampUSec, receiveTimeStampSec, receiveTimeStampUSec, leap, precision) are read. Then, the remembered <code>count</code> is compared to current value of <code>count</code> now in the record. If both are equal, the values read from the record are passed to <i>NTPD</i>. If they differ, another process has modified the record while it was read out (was not able to produce this case), and failure is reported to <i>NTPD</i>. The <code>valid</code> flag is cleared and <code>count</code> is bumped.</p>
|
|
<p>If not set, <code>count</code> is bumped</p>
|
|
|
|
<h4>Mode-independent post-processing</h4>
|
|
After the time stamps have been successfully plucked from the SHM
|
|
segment, some sanity checks take place:
|
|
<ul>
|
|
<li>The receive time stamp of the SHM data must be in the last 5
|
|
seconds before the time the data is processed. This helps in weeding
|
|
out stale data.
|
|
<li>If the absolute difference between remote and local clock
|
|
exceeds the limit (either <i>time2</i> or the default of 4hrs), then
|
|
the sample is discarded. This check is disabled when <i>flag1</i> is
|
|
set to 1.
|
|
</ul>
|
|
|
|
<h4>GPSD</h4>
|
|
|
|
<a href="http://gpsd.berlios.de/"><i>GPSD</i></a>
|
|
knows how to talk to many GPS devices.
|
|
It can work with <i>NTPD</i> through the SHM driver.
|
|
<P>
|
|
The <i>GPSD</i> man page suggests setting minpoll and maxpoll to 4.
|
|
That was an attempt to reduce jitter.
|
|
The SHM driver was fixed (ntp-4.2.5p138) to collect data each second rather than
|
|
once per polling interval so that suggestion is no longer reasonable.
|
|
<P>
|
|
<b>Note:</b> The <i>GPSD</i> client driver (type 46) uses the <i>GPSD</i>
|
|
client protocol to connect and talk to <i>GPSD</i>, but using the
|
|
SHM driver is the ancient way to have <i>GPSD</i> talk to <i>NTPD</i>. There
|
|
are some tricky points when using the SHM interface to interface
|
|
with <i>GPSD</i>, because <i>GPSD</i> will use two SHM clocks, one for the
|
|
serial data stream and one for the PPS information when
|
|
available. Receivers with a loose/sloppy timing between PPS and serial data
|
|
can easily cause trouble here because <i>NTPD</i> has no way to join the two
|
|
data streams and correlate the serial data with the PPS events.
|
|
</p>
|
|
<p>
|
|
|
|
<h4>Clockstats</h4>
|
|
If flag4 is set when the driver is polled, a clockstats record is written.
|
|
The first 3 fields are the normal date, time, and IP address common to all clockstats records.
|
|
<P>
|
|
The 4th field is the number of second ticks since the last poll.
|
|
The 5th field is the number of good data samples found. The last 64 will be used by <i>NTPD</i>.
|
|
The 6th field is the number of sample that didn't have valid data ready.
|
|
The 7th field is the number of bad samples.
|
|
The 8th field is the number of times the the mode 1 info was update while <i>NTPD</i> was trying to grab a sample.
|
|
<P>
|
|
|
|
Here is a sample showing the GPS reception fading out:
|
|
<pre>
|
|
54364 84927.157 127.127.28.0 66 65 1 0 0
|
|
54364 84990.161 127.127.28.0 63 63 0 0 0
|
|
54364 85053.160 127.127.28.0 63 63 0 0 0
|
|
54364 85116.159 127.127.28.0 63 62 1 0 0
|
|
54364 85180.158 127.127.28.0 64 63 1 0 0
|
|
54364 85246.161 127.127.28.0 66 66 0 0 0
|
|
54364 85312.157 127.127.28.0 66 50 16 0 0
|
|
54364 85375.160 127.127.28.0 63 41 22 0 0
|
|
54364 85439.155 127.127.28.0 64 64 0 0 0
|
|
54364 85505.158 127.127.28.0 66 36 30 0 0
|
|
54364 85569.157 127.127.28.0 64 0 64 0 0
|
|
54364 85635.157 127.127.28.0 66 0 66 0 0
|
|
54364 85700.160 127.127.28.0 65 0 65 0 0
|
|
</pre>
|
|
|
|
<h4>The 'mode' word</h4>
|
|
|
|
<p>
|
|
Some aspects of the driver behavior can be adjusted by setting bits of
|
|
the 'mode' word in the server configuration line:<br>
|
|
<tt>server 127.127.28.</tt><i>x</i><tt> mode </tt><i>Y</i>
|
|
</p>
|
|
|
|
<table border="1" width="100%">
|
|
<caption>mode word bits and bit groups</caption>
|
|
<tbody><tr>
|
|
<th align="center">Bit</th>
|
|
<th align="center">Dec</th>
|
|
<th align="center">Hex</th>
|
|
<th align="left">Meaning</th>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td align="center">0</td>
|
|
<td align="center">1</td>
|
|
<td align="center">1</td>
|
|
<td>The SHM segment is private (mode 0600). This is the fixed
|
|
default for clock units 0 and 1; clock units >1 are mode
|
|
0666 unless this bit is set for the specific unit.</td>
|
|
</tr><tr>
|
|
<td align="center">1-31</td>
|
|
<td align="center">-</td>
|
|
<td align="center">-</td>
|
|
<td><i>reserved -- do not use</i></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
<h4>Fudge Factors</h4>
|
|
<dl>
|
|
<dt><tt>time1 <i>time</i></tt>
|
|
<dd>Specifies the time offset calibration factor, in seconds and fraction, with default 0.0.
|
|
<dt><tt>time2 <i>time</i></tt>
|
|
<dd>Maximum allowed difference between remote and local
|
|
clock, in seconds. Values <1.0 or >86400.0 are ignored, and the
|
|
default value of 4hrs (14400s) is used instead. See also flag 1.
|
|
<dt><tt>stratum <i>number</i></tt>
|
|
<dd>Specifies the driver stratum, in decimal from 0 to 15, with default 0.
|
|
<dt><tt>refid <i>string</i></tt>
|
|
<dd>Specifies the driver reference identifier, an ASCII string from one to four characters, with default <tt>SHM</tt>.
|
|
<dt><tt>flag1 0 | 1</tt>
|
|
<dd><i>Skip</i> the difference limit check if set. Useful
|
|
for systems where the RTC backup cannot keep the time over
|
|
long periods without power and the SHM clock must be able
|
|
to force long-distance initial jumps. <i>Check</i> the
|
|
difference limit if cleared (default).
|
|
<dt><tt>flag2 0 | 1</tt>
|
|
<dd>Not used by this driver.
|
|
<dt><tt>flag3 0 | 1</tt>
|
|
<dd>Not used by this driver.
|
|
<dt><tt>flag4 0 | 1</tt>
|
|
<dd>If flag4 is set, clockstats records will be written when the driver is polled.
|
|
</dl>
|
|
|
|
<h4>Public vs. Private SHM segments</h4>
|
|
|
|
<p>The driver attempts to create a shared memory segment with an
|
|
identifier depending on the unit number. This identifier (which can be
|
|
a numeric value or a string) clearly depends on the method used, which
|
|
in turn depends on the host operating system:</p>
|
|
|
|
<ul>
|
|
<li><p>
|
|
<tt>Windows</tt> uses a file mapping to the page file with the
|
|
name '<tt>Global\NTP</tt><i>u</i>' for public accessible
|
|
mappings, where <i>u</i> is the clock unit. Private /
|
|
non-public mappings are created as
|
|
'<tt>Local\NTP</tt><i>u</i>'.
|
|
</p><p>
|
|
Public access assigns a NULL DACL to the memory mapping, while
|
|
private access just uses the default DACL of the process creating
|
|
the mapping.
|
|
</p>
|
|
</li>
|
|
<li><p>
|
|
<tt>SYSV IPC</tt> creates a shared memory segment with a key value
|
|
of <tt>0x4E545030</tt> + <i>u</i>, where <i>u</i> is again
|
|
the clock unit. (This value could be hex-decoded as 'NTP0',
|
|
'NTP1',..., with funny characters for units > 9.)
|
|
</p><p>
|
|
Public access means a permission set of 0666, while private access
|
|
creates the mapping with a permission set of 0600.
|
|
</p>
|
|
</li>
|
|
</ul>
|
|
|
|
<p>There's no support for POSIX shared memory yet.</p>
|
|
|
|
<p><i>NTPD</i> is started as root on most POSIX-like operating systems
|
|
and uses the setuid/setgid system API to run under reduced rights once
|
|
the initial setup of the process is done. One consequence out of this
|
|
is that the allocation of SHM segments must be done early during the
|
|
clock setup. The actual polling of the clock is done as the run-time
|
|
user; deferring the creation of the SHM segment to this point will
|
|
create a SHM segment owned by the runtime-user account. The internal
|
|
structure of <i>NTPD</i> does not permit the use of a fudge flag if
|
|
this is to be avoided; this is the reason why a mode bit is used for
|
|
the configuration of a public segment.
|
|
</p>
|
|
|
|
<p>When running under Windows, the chosen user account must be able to
|
|
create a SHM segment in the global object name space for SHM clocks with
|
|
public access. Otherwise the session isolation used by Windows kernels
|
|
after WinXP will get into the way if the client program does not run in
|
|
the same session.
|
|
</p>
|
|
|
|
<h4>Additional Information</h4>
|
|
<p><a href="../refclock.html">Reference Clock Drivers</a></p>
|
|
|
|
<hr>
|
|
<script type="text/javascript" language="javascript" src="scripts/footer.txt"></script>
|
|
</body>
|
|
|
|
</html>
|
|
|