"Fossies" - the Fresh Open Source Software Archive

Member "PPSkit-2.1.7/README" (29 Aug 2003, 13767 Bytes) of package /linux/misc/old/PPSkit-2.1.7.tar.gz:


As a special service "Fossies" has tried to format the requested text file into HTML format (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file.

    1 (Emacs: -*- indented-text -*-)
    2 
    3 
    4 			  Implementation of
    5 	Nanosecond Time and a PPS API for the Linux 2.4 Kernel
    6 
    7 	      Copyright (c) 1996 - 2003 by Ulrich Windl
    8 		 <Ulrich.Windl@rz.uni-regensburg.de>
    9 			   29th August 2003
   10 
   11 		 This file describes ``PPSkit 2.1'',
   12 	      a small collection of files to support the
   13 	      ``Kernel Model for Precision Timekeeping''
   14 		      as described in RFC-1589,
   15 		later updates known as ``nanokernel'',
   16 		  combined with an implementation of
   17 	     the ``PPS API v1'' as described in RFC-2783.
   18 
   19 		 Mainly these algorithms are used by
   20 	  NTPv3 (Network Time Protocol, RFC1305) and NTPv4.
   21 
   22 Overview:
   23 --------
   24 
   25 This collection contains:
   26 
   27      0) A new kernel that keeps time in nanoseconds (instead of
   28         microseconds).  These changes come along with several other
   29         improvements and cleanups.
   30 
   31      1) Extensions and bugfixes for adjtimex() to adjust the value of
   32         `tickadj' (defaults to 500/HZ). This can be useful when the
   33         adjtime() doesn't work at all or is too slow (1ms on Alpha
   34         architecture, 0.5ms per second by default on i386
   35         architecture).
   36 
   37      2) New code to support PPS (pulse-per-second) clock
   38         synchronization in the kernel (also known as ``nanokernel #4'').
   39 
   40      3) Example implementation for the serial driver (implements
   41         detection of pulse on DCD pin).  The implementation uses the
   42         new PPS API for portability and nanosecond accuracy.
   43 
   44      4) Some utilities and documentation files (like this).
   45 
   46 
   47 Performance data:
   48 ----------------
   49 
   50 On my Pentium-100 with an Intel Triton II/VX chipset I have measured
   51 some (rather short-term) performance data (using my Meinberg GPS 167
   52 as PPS source).  The user-visible time resolution is about 3Ás.
   53 
   54 ---------------------------------------------
   55 Raw offset correction |	Jitter    (all in ns)
   56 samples	mean	sigma |	samples	mean	sigma
   57 ---------------------------------------------
   58  2713	19.08	82.12	2713	1462	1792
   59  1743	 2.872	18.36	1743	 947.3	1047
   60 24717  -26.85  142.82  24717    2561    3418
   61  6651   -9.29   53.36   6651    2438    2744
   62 [missing]
   63  5510  -74.95  102.04   5510    2777    4136 [*See note*]
   64 (when ignoring about the first 500 samples we get)
   65  2213	 7.604	 9.74	2213	1364	1460
   66  1367	 0.600	 5.93	1367	 944.1	1056
   67 24217  -27.16   77.97  24217    2566    3386
   68  6651   -9.29   53.36   6651    2438    2744 [*See note*]
   69  5234  -62.84   90.18   5234    2757    4174
   70 (this is PPSkit-0.9.3 with Linux-2.2.16 and GPS without SA after warmup)
   71  8174  -33.63   55.06   8174    2780    1359
   72 
   73 [*Note*]: All lines before this one probably have a wrongly computed sigma!
   74 
   75 
   76 A short History of Changes and Plans:
   77 ------------------------------------
   78 
   79 * In Linux 2.0.30 there was a module-hook for a function ``hardpps''
   80   to handle the timekeeping stuff.  As the code for timekeeping does
   81   not depend on the way the signal is fed into the hardware, but only
   82   on how the signal is detected, it was decided to add the PPS
   83   timekeeping code to kernel/time.c and to remove that hook.
   84 
   85 * The new ``hardpps'' routine expects the time of the pulse to be
   86   passed as parameters.
   87 
   88 * The interrupt routine of the serial driver collects precision
   89   timestamps that can be retrieved via the PPS API.  They can also be
   90   automatically passed to a ``hardpps()'' kernel routine to discipline
   91   the clock.  Care has been taken that the serial driver is still
   92   usable without PPS applications.
   93 
   94 * The xntp package contains code to support a CIOGETEV ioctl that
   95   reads precision time-stamps of external events on the carrier detect
   96   line of a serial port.  CIOGETEV has been implemented as a new line
   97   discipline that fills the structure `ppsclockev'.  That structure
   98   contains an event count and a ``struct timeval'' of the last event.
   99   The code has been adapted from a more complete solution made by
  100   Harald Koenig.  [Removed in 2.0]
  101 
  102 * A former implementation of the FreeBSD-like ``TIOCDCDTIMESTAMP'' has
  103   been removed again, because it required a change to the
  104   serial_struct, thus causing incompatibilities for existing binaries.
  105   Also, the CIOGETEV gets the same data.  H. Peter Anvin had
  106   implemented that function around Linux 2.1.40.
  107 
  108 * The adjtimex() system call has been extended to allow reading and
  109   modifying of ``tickadj''.  This is not strictly required for
  110   accurate clock operation, but is rather helpful if the default slew
  111   rate of 0.5ms per second is too slow for a larger correction made by
  112   ``adjtime()''.
  113 
  114 * The PPSkit (0.4) has been merged into Linux-2.2 shortly before it
  115   came out.  Thus 2.2.0 has some essential time fixes that older
  116   versions did not have (these fixes entered 2.0 when 2.1 already
  117   existed).
  118 
  119 * In preparation for exchanging the major part of the NTP code, the
  120   code has been restructured for PPSkit-0.5.  The next generation will
  121   have 64bit quantities measuring nanoseconds.  Currently noone in the
  122   kernel provides nanoseconds, but we'll be prepared.
  123 
  124 * In PPSkit-0.6 the kernel was converted to nanoseconds by brute
  125   force.  Along with the new 64bit time variables came the new kernel
  126   clock model known as the ``nanokernel'' (because it features
  127   nanoseconds and ``STA_NANO'').  It is planned to bring some of the
  128   related fixes back to the stable standard kernel.
  129 
  130 * PPSkit-0.7 finally brought the PPS API ("03" dated 1999-02-11) as
  131   well as an important fix for the jitter in the time stamps (Many
  132   thanks to Reg Clemens).  The reliability of the ``hardpps()''
  133   routine has been improved.
  134 
  135 * PPSkit-0.8 needed a new but incompatible implementation of the PPS
  136   API ("05" dated 1999-08-17).
  137 
  138 * PPSkit-0.9 featured an updated ``hardpps()'' routine from
  139   ``nanokernel #3'', dated ``1999-08-29''.  It is possible to tune the
  140   kernel time zone and periodic updates of the RTC chip (which are
  141   done whenever the system time changes).
  142 
  143 * PPSkit-1.0 featured a revised clock model (``nanokernel #4'') and
  144   revised conversion routines for the i386 architecture.
  145 
  146 * PPSkit-2.0, targeted for Linux-2.4.0, drops ``CIOGETEV'' that is
  147   obsoleted by ``PPS API''.
  148 
  149 * PPSkit-2.1 introduced a new utility, PPSspy.pl, to watch the PPS-related
  150   kernel variables.
  151 
  152 Notes on Usage:
  153 --------------
  154 
  155 * The old, now obsolete, code to activate PPS event processing has
  156   been replaced with the PPS API.  The old code was like the
  157   following:
  158 
  159 	struct serial_struct ss;
  160 	ioctl(fd, TIOCGSERIAL, &ss);	/* enable pulse detection on DCD */
  161 	ss.flags |= ASYNC_PPS_CD_POS;	/* or ``ASYNC_PPS_CD_NEG'' */
  162 	ioctl(fd, TIOCSSERIAL, &ss);
  163 
  164   The new code uses the functions ``time_pps_create'' and
  165   ``time_pps_set_param'' to activate capturing of events.  The
  166   following code is from ``draft-mogul-pps-api-05.txt'' (comments and
  167   corrections added):
  168 
  169       #include <sys/timepps.h>
  170 
  171       int fd;
  172       pps_handle_t handle;	/* handle for PPS sources */
  173       pps_params_t params;	/* selection of events, options */
  174       pps_info_t infobuf;	/* status of events */
  175       struct timespec timeout;	/* waiting time */
  176       int mode;			/* supported mode bits */
  177 
  178       /* Open a file descriptor and enable PPS on rising edges */
  179       fd = open(PPSfilename, O_RDWR, 0);
  180       time_pps_create(fd, &handle);
  181       time_pps_getcap(handle, &mode);
  182       if ((mode & PPS_CAPTUREASSERT) == 0) {
  183           fprintf(stderr, "%s cannot currently CAPTUREASSERT; mode=%#04x\n",
  184                 PPSfilename, mode);
  185           exit(1);
  186       }
  187       time_pps_getparams(handle, &params);
  188       params.mode |= PPS_CAPTURE_ASSERT;	/* capture ASSERT events */
  189       params.mode |= PPS_TSFMT_TSPEC;	/* use ``struct timespec'' format */
  190       time_pps_setparams(handle, &params);
  191 
  192       /* create a zero-valued timeout */
  193       timeout.tv_sec = 0;
  194       timeout.tv_nsec = 0;
  195 
  196       /* loop, printing the most recent timestamp every second or so */
  197       while (1) {
  198           sleep(1);
  199           time_pps_fetch(handle, PPS_TSFMT_TSPEC, &infobuf, &timeout);
  200           printf("Assert timestamp: %d.%09d, sequence: %ld\n",
  201                  infobuf.assert_timestamp.tv_sec,
  202                  infobuf.assert_timestamp.tv_nsec,
  203                  infobuf.assert_sequence);
  204       }
  205 
  206   Implementation note: The ASSERT event has been defined in terms of
  207   the ``DCD'' modem status register bit of the UART, i.e. `assert''
  208   means the bit has been set (the opposite applies to ``clear''
  209   events).  The ECHO feature has been implemented using the ``RTS''
  210   bit in the modem status register of the UART.  An active event will
  211   be signalled by clearing the bit, i.e. for an echoed ``assert''
  212   event the bit will be cleared and for an echoed ``clear'' event the
  213   bit also will be cleared. The bit will be set if all echoed event
  214   become inactive, i.e. if echoing both events, the bit will stay
  215   cleared after the first event..
  216 
  217   With ntp-4.0.99f the PPS event processing code is activated
  218   automatically with a correct configuration.  This is at least true
  219   for the PARSE based drivers.  Here is an example what ntptime may
  220   report (on a Celeron-500):
  221 
  222 ntp_gettime() returns code 0 (OK)
  223   time bdf4ec7c.1c2afdd0  Wed, Dec 27 2000 23:32:28.110, (.110031991),
  224   maximum error 1985 us, estimated error 0 us.
  225 ntp_adjtime() returns code 0 (OK)
  226   modes 0x0 (),
  227   offset 0.108 us, frequency 115.251 ppm, interval 128 s,
  228   maximum error 1985 us, estimated error 0 us,
  229   status 0x2107 (PLL,PPSFREQ,PPSTIME,PPSSIGNAL,NANO),
  230   time constant 6, precision 2.878 us, tolerance 496 ppm,
  231   pps frequency 115.251 ppm, stability 0.017 ppm, jitter 2.605 us,
  232   intervals 88, jitter exceeded 69, stability exceeded 4, errors 0.
  233 
  234   ``ntpq -p'' says something like:
  235 
  236      remote           refid      st t when poll reach   delay   offset  jitter
  237 ==============================================================================
  238 +GENERIC(1)      .GPS.            0 l   51   64  377    0.000    0.003   0.000
  239 oPPS(1)          .PPS.            0 l   60   64  377    0.000    0.004   0.000
  240 
  241 * The current implementation still leaves some room for improvement, while
  242   already working fine at several places.  As the additional code is
  243   usually inactive, only a few additional CPU cycles are needed.  Still,
  244   nanoseconds don't come for nothing.  Measurements on my Pentium 100MHz
  245   have shown that the `hardware_pps' routine takes between 250 and 12000
  246   CPU cycles per call (with debugging messages enabled, of course). For my
  247   Celeron-500 the minimum is about 230 cycles, while the maximum is at
  248   about 50000 cycles.
  249 
  250 * I once wrote the test program `gen_pps.c' that uses the RTC driver
  251   (see /proc/rtc) to create a PPS pulse on the UART's RTS pin (pin 4
  252   on "COM2" (25 pins)).  The program needs the device name for the
  253   port to use (e.g. /dev/cua0). I made a very simple cable between the
  254   DB9 and DB25 connector:
  255 
  256   (input)	(output)
  257   DB9:		DB25:
  258   ---		----
  259   1 -----------	4	(CD, RTS)
  260   5 -----------	7	(GND, GND)
  261 
  262   Unfortunately the RTC driver seems to have some problems (last seen
  263   in 2.0.36): From time to time the kernel says: ``rtc: lost some
  264   interrupts at 2Hz.'' (This is because updating the RTC will reset
  265   the divider for the periodic interrupt)
  266   [You should get a real PPS source, not this cheap trick]
  267 
  268 * Yet another program (enable_pps.c) can be used to enable detection
  269   of the PPS signal on the CD pin and exercise the kernel clock
  270   machinery.  That program expects standard input to be redirected
  271   from the desired port, event processing will be disabled unless
  272   specific options are specified.
  273 
  274   I activate PPS processing using the command (ASSERT event, hardpps)
  275   ``enable_pps -tah -j -k </dev/refclock-1'' (You can use this command
  276   to gather raw statistics about your pulses).
  277 
  278 * The programs are just my test programs to validate the code; don't
  279   expect them to synchronize your time!  Even worse, they may
  280   de-adjust your kernel clock badly.  Use ntp-4.0.99 (or later) for
  281   nice and stable NTP support.
  282 
  283 * Usually you need some level converter to connect the TTL level
  284   output of a clock to the CD input of the serial port.  A friend of
  285   mine and I have developed a simple converter that is powered from
  286   the serial port's status lines.  There's also some information about
  287   a sample device (`gadget box') on the NTP home page
  288   http://www.ntp.org/.
  289 
  290 * To get a quick start with ntp configuration and PPS read the
  291   documentation (that comes with ntp) on ``PPS'' (pps.html) and
  292   ``enable pps'' (prefer.html) and ``refclock ATOM'' (driver22.html).
  293   You are kindly advised to read ``debug.html'' before reporting
  294   problems to the NTP developers or to the newsgroup
  295   comp.protocols.time.ntp.  There's also an older FAQ, and a newer
  296   one, and a very new one...  (see http://www.ntp.org/ntpfaq/NTP-a-faq.htm)
  297 
  298 * Updating the RTC: The RTC is updated automatically if either the
  299   system time is set, or if ``STA_UNSYNC'' in ``time_status'' is
  300   clear.  You can disable the feature if you set ``rtc_update'' to
  301   zero.  If ``rtc_runs_localtime'' is non-zero, ``sys_tz'' is used to
  302   compute the local time.  By default, RTC is set to UTC.
  303 
  304   NOTE 1: In my SuSE Linux 6.3 system the ``tz_minuteswest'' were -120
  305           instead of -60 for MET.  I had to correct that value via
  306           ``echo -60 0 >/proc/sys/kernel/time/timezone''.
  307 
  308   WARNING: The sysctl interface does only limited error checking, so be
  309            very careful when writing variables!  I warned you, so
  310            don't complain.
  311 
  312 * I use the following lines to set up the system during boot, assuming
  313   the correct timezone has been set before:
  314 
  315 timezone=$(date +%z | sed -e 's/\([0-9][0-9]\)\([0-9][0-9]\)/(60*10#\1+10#\2)/')
  316 TIMESYSCTL=/proc/sys/kernel/time
  317 [ -w $TIMESYSCTL/timezone ] && echo $((-$timezone)) 0 >$TIMESYSCTL/timezone
  318 [ -w $TIMESYSCTL/rtc_runs_localtime ] && echo 1 >$TIMESYSCTL/rtc_runs_localtime