[LinuxPPS] Using LinuxPPS correctly (newbie question)

Sidney Cadot sidney at jigsaw.nl
Tue Oct 29 19:57:03 CET 2013


Hi all,

Excuse me for this very long post, but I hope it helps to be thorough.
My actual questions are at the bottom, but I wanted to make sure to
explain everything I did so far.

Unfortunately, the Wiki at linuxpps.org is currently not very helpful
to someone like me who is just getting started, so that's why I am
here. If some of you can find time to help me understand this, I would
be quite willing to spend a few hours to write e.g. a page for
LinuxPPS novices that may be a useful addition to the Wiki.

=== Context ===

Up until recently I have been using Eric Raymond's gpsd with a
FastTrax GPS chip hooked up to a serial port to get accurate time for
my Linux desktop machine.

Today I started experimenting with LinuxPPS, hoping that I would be
able to cut out the middle man (gpsd). I feel like I am close, but not
completely there yet.

My setup is as follows:

I have a recent machine running Debian GNU/Linux, kernel 3.10-3-amd64.

I have two on-board serial ports, /dev/ttyS0 and /dev/ttyS1.

/dev/ttyS0 connects to a Fastrax UP501 GPS chip, which provides NMEA
and PPS. Both are led to a voltage-conversion circuit to convert
between CMOS (3.3V) and RS232 voltage levels. Connected are GND, TXD,
RXD, and DCD. The DCD line carries the PPS.

I use /dev/ttyS1 to generate a "fake" 10% duty cycle PPS signal on one
of its pins, from a userspace program running on the host that
continuously queries the clock (using gettimeofday), and sets the RTS
bit if the tv_usec field is less than 100000, in a busy-waiting loop.
This allows me to use an oscilloscope to check the correspondence of
the computer clock (as seen by a user space program) and the
GPS-generated PPS - see attached image for what I see on the
oscilloscope. In that example image, the difference between the PPS as
generated by the GPS ("ground truth", blue) and the "fake" PPS
(userspace time, red) is ~ 26 ms.

Of course, the goal is to get the up-edges of these two signals to
line up (if we ignore, for the moment, the latency and inaccuracy
introduced by my userspace probing of the system clock). Indeed, using
gpsd, I have been able to get these lined up to within ~10--20
microseconds. I am now trying to do the same with LinuxPPS.

==== what did I do? ====

What I tried so far is the following:

(1) I have gpsd fully disabled (just to be clear about this).

(2) I have made a symlink from /dev/ttyS0 to /dev/gps100, since a
device name /dev/gps<n> is expected by NTP's "Generic NMEA GPS
Receiver" that I will be using  (according to
http://www.eecis.udel.edu/~mills/ntp/html/drivers/driver20.html).

(3) I have started ldattach as root ("ldattach 18 /dev/ttyS0").

(4) I have started ntp (version 1:4.2.6.p5+dfsg-3 as provided in
Debian testing), the relevant part of my /etc/ntp/conf looks as
follows:

# The FastTrax chip I am using works at 9600 baud (via "mode" bit 1, value 2).
# The first NMEA sentence it produces at top-of-the-second is a
"GPGGA" sentence,
# so I direct NTP to only use that sentence type (via "mode" bit 4, value 16).
#
# The GPGGA sentence end has a lag of ~ 350 ms relative to the ground
truth (GPS PPS),
# as observed on the scope, but there's quite a bit of jitter.
#
# I do not quite understand the effect of the values for flag3 and flag4.

server 127.127.20.100 prefer mode 18 # Process only GPGGA sentences; 9600 baud.
fudge  127.127.20.100 time1 0.0 time2 0.350 flag1 1 flag2 0 flag3 1 flag4 0

# end of ntp.conf

==== what do I see? ====

What I observe is the following behavior:

(1) A /dev/pps0 is created (by the ldattach). Running 'ppstest
/dev/pps0' shows a clean record of PPSes, as sensed on the DCD line,
e.g.

source 0 - assert 1383069730.131472773, sequence: 3371 - clear
1383069731.031480751, sequence: 3372
source 0 - assert 1383069731.131483688, sequence: 3372 - clear
1383069731.031480751, sequence: 3372
source 0 - assert 1383069731.131483688, sequence: 3372 - clear
1383069732.031489599, sequence: 3373
source 0 - assert 1383069732.131479331, sequence: 3373 - clear
1383069732.031489599, sequence: 3373
source 0 - assert 1383069732.131479331, sequence: 3373 - clear
1383069733.031498002, sequence: 3374
source 0 - assert 1383069733.131506080, sequence: 3374 - clear
1383069733.031498002, sequence: 3374
source 0 - assert 1383069733.131506080, sequence: 3374 - clear
1383069734.031506895, sequence: 3375
source 0 - assert 1383069734.131508971, sequence: 3375 - clear
1383069734.031506895, sequence: 3375

The fractional second parts of the "clear" timestamp correspond to the
delay seen on the scope to a level that is (much?) better than 1 ms.
So the PPS sensing appears to be working well.

(2) NTP does not succeed to synchronize the local clock with the
settings used...

root at burgwal:~# ntpq -p
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
-195.50.171.101  145.253.2.212    2 u   26   64  377   30.783  -30.635   4.122
-mail.vive-id.nl 83.98.201.133    3 u   18   64  377   21.563  -32.265   3.567
+ntp0.bbactive.e 193.67.79.202    2 u   17   64  377   21.241  -39.839   5.816
+sisdb01.muskego 50.18.44.198     3 u   18   64  377  124.914  -39.542   3.378
*GPS_NMEA(100)   .GPS.            0 l    8   64  377    0.000  -50.205  55.522

(The 4 first servers are obtained from debian.pool.ntp.org)

Note that both the offset and jitter of the GPS_NMEA source are in the
order of tens of milliseconds; pretty bad.

==== questions ====

I am probably doing something stupid which prevents NTP from locking
onto the PPS, and that is probably because I don't understand
precisely what I am doing. I have tried to formulate a couple of
questions that are probably easy for the gurus on this mailinglist,
but not for me:

(1) What does ldattach() do, precisely?

I haven't been able to find a lot of info on this. As far as I can
tell, it directs the kernel to start monitor the serial device; when
we specify 18 (or PPS), it specifies that the DCD line must be
monitored.

Is my understanding correct that this triggers the kernel to create /dev/pps0 ?

As I understand it, the pps0 device can then be queried to give highly
precise timestamps of the moments when 0->1 and 1->0 transitions
happen; is that correct?

(2) Is it possible to direct the kernel's PPS device to listen to
another pin than DCD (eg. RTS, or RING), or is that hardwired in the
kernel driver?

(3) Turning to NTP, I feel that the page on the "Generic NMEA GPS
Receiver" (http://www.eecis.udel.edu/~mills/ntp/html/drivers/driver20.html)
is quite confusing. In particular:

- Does NTP depend on ldattach and the /dev/pps0 device being present?
If yes, how does it know that /dev/pps0 is associated with
/dev/gps100?

Couldn't NTP enable the correct line discipline on its own, while it
is running (which would make the ldattach dependency disappear)?

- Is my understanding correct that, when the fudge flag1 is set to 1,
the NTP "Generic NMEA GPS Receiver" listens to BOTH the NMEA stream
AND the PPS? If this is so, what do the numbers in "ntpq -p" mean
(delay, offset, jitter) -- do they refer to the NMEA source, the PPS
source, or some combination of both? The number are so large that I
suspect that they are from the NMEA, but if that is the case, how can
I monitor the behavior of the PPS?

- How does NTP get the PPS information, if this is enabled? (via
/dev/pps0 ? Some other way?)

(4) I don't understand the precise meanings of flag3 and flag4, could
someone explain these?

====

Kind regards, once more I apologize for the long post, and thanks in
advance for any help,

  Sidney
-------------- next part --------------
A non-text attachment was scrubbed...
Name: scope.png
Type: image/png
Size: 1990 bytes
Desc: not available
URL: <http://www.linuxpps.org/pipermail/discussions/attachments/20131029/e16d9735/attachment-0002.png>


More information about the discussions mailing list