LinuxPPS installation

From LinuxPPS
Jump to: navigation, search

Downloading the code

As of kernel 2.6.34 there is no need for patching to get basic LinuxPPS support working. You can use 2.6.34 directly.
See or a mirror for a current version.

Compiling the code

The kernel code

Once you have downloaded the code by following the instructions above, you will need to compile the kernel with PPS support.

When you run the kernel configuration tool of your choice (such as make menuconfig you will find the following in the PPS support section. The following options will enable serial line support.

<M> PPS support
[ ]   Use low level IRQ timestamps
[ ]   PPS debugging messages
      *** PPS clients support ***
<M>   Kernel timer client (Testing client, use for debug)
<M>   PPS line discipline
[ ]   Parallel printer support     

If you cannot locate the PPS support section, you may not have enabled experimental drivers. You will find the following options in the Code maturity level options section.

[*] Prompt for development and/or incomplete code/drivers             
[*]   Select only drivers expected to compile cleanly (NEW)                            

NOTE: the PPS support -> Parallel printer support may be forced off if you selected PPS support as a module and Character devices -> Parallel printer support as a kernel built-in. Please make them both modules to resolve the issue.

Now recompile the kernel and reboot.

The userland tools

Now that you have a kernel with PPS support, you will need to build the LinuxPPS userspace tools.
You can browse the pps-tools repository via gitweb.
Please get the code:

$ cd /usr/src
$ git clone git:// pps-tools

Header files

Optionally, when we have older header files, we update the header files using the versions from your new kernel.

$ cd /usr/include
$ mv linux linux.old
$ mv asm asm.old
$ mv asm-generic asm-generic.old
$ ln -s /lib/modules/$(uname -r)/build/include/linux linux
$ ln -s /lib/modules/$(uname -r)/build/arch/x86/include/asm asm
$ ln -s /lib/modules/$(uname -r)/build/include/asm-generic asm-generic

Optionally, for building ntpd later:

$ cd /usr/include
$ cp /usr/src/pps-tools/timepps.h timepps.h

Building the tools

Now we will build the ppstest tool.

$ cd /usr/src/pps-tools
$ make

If you encounter an error, you most likely did not follow the instructions above.

Now you have the ppstest userspace tool.

Obtaining ldattach

You will also need the ldattach tool, which can be found in the util-linux-ng package v2.14 and up.
If your distribution does not provide you such a package, or a working version of ldattach is not yet included, then you will have to build this tool from it's sources. Please refer to for the sourcecode and your distro provider for an updated util-linux package.

Testing the new system

After you have loaded LinuxPPS, you should see a new directory in sysfs: /sys/class/pps. In that directory you will find all of your clients.

$ find  /sys/class/pps/
$ tree /sys/class/pps/pps0
|-- assert
|-- clear
|-- dev
|-- echo
|-- mode
|-- name
|-- path
|-- power
|   `-- wakeup
|-- subsystem -> ../../../../class/pps
`-- uevent

If you do not see anything, you have not loaded a client module. As an example, to load the 8250 serial line support, run the following commands to use /dev/ttyS0 as a PPS source:

$ sudo modprobe 8250
$ ldattach 18 /dev/ttyS0

You should now verify that you have the proper device nodes in the /dev directory. You should get something like this:

$ ls -l /dev/pps*
crw-rw-r-- 1 root dialout 253, 0 Aug  8 18:58 /dev/pps0
crw-rw-r-- 1 root dialout 253, 1 Aug  8 18:58 /dev/pps1

If you do not see them, add the following into your udev configuration file:

SUBSYSTEM=="pps", MODE="0664" GROUP="dialout"

Alternatively, you can create the proper device nodes with the mknod utility. Please refer to the appropriate manual pages in either case.

Now you can test the PPS support by running the ppstest tool (as root). You should get output like the following:

$ sudo ppstest /dev/pps0
trying PPS source "/dev/pps0"
found PPS source "/dev/pps0"
ok, found 1 source(s), now start fetching data...
source 0 - assert 1186592699.388832443, sequence: 364 - clear  0.000000000, sequence: 0
source 0 - assert 1186592700.388931295, sequence: 365 - clear  0.000000000, sequence: 0
source 0 - assert 1186592701.389032765, sequence: 366 - clear  0.000000000, sequence: 0

If you wish to find a specific source, you can use the ppsfind utility. The following is an example of how to locate the ktimer testing device:

$ ppsfind ktimer
pps0: name=ktimer path=

You may also wish to view the /sys/class/pps/*/{assert,clear} files. These record the PPS event times. Depending on your PPS source's capabilities, one of them may be empty.

$ ls -l /sys/class/pps/*/{assert,clear}
/sys/class/pps/pps0/assert  /sys/class/pps/pps1/assert
/sys/class/pps/pps0/clear   /sys/class/pps/pps1/clear

The ktimer test module only creates assert events, so you will only see things in the assert file. The clear file will be empty. Reading the assert file will show you the last assert event time and sequence number:

$ cat /sys/class/pps/pps0/assert
$ cat /sys/class/pps/pps0/assert 

You should get a different number each time your PPS source generates an event. This should take exactly one second between events.

If all is OK you can find out how to compile ntpd for LinuxPPS and your clock.

Alexander Gordeev's hardpps patch

Optional steps for using the kernel consumer:

The kernel code

Download the latest patch for your kernel, e.g. patch-2.6.36-ts17.bz2, and apply over an already working LinuxPPS installation.
Build the kernel.
Boot into the new kernel.

The userland tools

If you did not already do so, get timepps.h from and put it in /usr/include.
Also /usr/include/linux/pps.h may have to be updated too (but this is ugly, hope it will be merged mainline soon).

Use this (new) timepps.h to re-compile ntpd using the normal steps to do this. (see above)
Install the new ntpd.
Check ntp.conf; if you are using the NMEA refclock, set flag3 to 1.
Start ntpd
After a while ntptime should show stuff like:

 $ ntptime
 ntp_gettime() returns code 0 (OK)
   time d059cb28.f3c6215c  Fri, Oct  8 2010 18:54:00.952, (.952242917),
   maximum error 1242 us, estimated error 6 us, TAI offset 0
 ntp_adjtime() returns code 0 (OK)
   modes 0x0 (),
   offset 0.000 us, frequency 3.680 ppm, interval 256 s,
   maximum error 1242 us, estimated error 6 us,
   time constant 4, precision 0.001 us, tolerance 500 ppm,
   pps frequency 3.673 ppm, stability 0.018 ppm, jitter 11.356 us,
   intervals 41, jitter exceeded 2, stability exceeded 0, errors 0.