Enable PPS support in Raspian
DUNE has a task called Supervisors.ClockPPS
that is used to dicipline the clock from both IMC::GpsFix
messages and a PPS source. To get this to work, the kernel has to be compiled with two options not currently enabled by default:
- CONFIG_PPS (“PPS support” in “make menuconfig”)
- CONFIG_NTP_PPS (“PPS kernel consumer support” in “make menuconfig”)
Install dependencies
sudo apt install git bc bison flex libssl-dev
Download kernel
mkdir ppskernel cd ppskernel git clone https://github.com/raspberrypi/linux.git cd linux make mrproper zcat /proc/config.gz > .config make oldconfig
Configure kernel build options
Then comes the hard part, setting the options. Normally this is straight forward, but due to some options only showing when others are disabled, it may be a little tricky.
- Run
make menuconfig
- Go to
General setup ---> Timers subsystem --->
and disableOld Idle dynticks config
, then enterTimer tick handling
and change it toPeriodic timer ticks (constant rate, no dynticks)
- Turn on PPS support:
PPS kernel consumer support
is the option that should have become visible after changing the timer settings. If not, save and reloadmake menuconfig
. - Enter Device Drivers —> PPS support —>
<M> PPS support [ ] PPS debugging messages [*] PPS kernel consumer support *** PPS clients support *** < > Kernel timer client (Testing client, use for debug) <M> PPS line discipline <M> PPS client using GPIO *** PPS generators support ***
- Save and exit. To verify, check the
.config
file that has been created in the same folder (nano .config). These options should be present somewhere in the file:
CONFIG_PPS=y CONFIG_NTP_PPS=y # # Timers subsystem # CONFIG_TICK_ONESHOT=y CONFIG_HZ_PERIODIC=y # CONFIG_NO_HZ_IDLE is not set # CONFIG_NO_HZ_FULL is not set # CONFIG_NO_HZ is not set CONFIG_HIGH_RES_TIMERS=y # CONFIG_PREEMPT_NONE is not set CONFIG_PREEMPT_VOLUNTARY=y # CONFIG_PREEMPT is not set
Compile the kernel
make -j4 make modules
- Gain superuser privileges and transfer a copy of the new kernel to the boot partition:
sudo -i cd ~pi/ppskernel/linux-rpi-[kernel version number].y make modules_install cp ./arch/arm/boot/zImage /boot/kernel_new.img
- Tell the system to use this new kernel by adding
kernel=kernel_new.img
to/boot/config.txt
. - Reboot
Add PPS source and load kernel module
- Open
/boot/config.txt
again, anddtoverlay=pps-gpio,gpiopin=[GPIOPIN]
where GPIOPIN is the PPS signal. - Load kernel module:
sudo modprobe pps-gpio
Test and make permanent
- Test
apt-get install pps-tools sudo ppstest /dev/pps0
- Expected result is something like:
trying PPS source "/dev/pps0" found PPS source "/dev/pps0" ok, found 1 source(s), now start fetching data... source 0 - assert 1572772437.999997402, sequence: 6168 - clear 0.000000000, sequence: 0 source 0 - assert 1572772438.999997803, sequence: 6169 - clear 0.000000000, sequence: 0 source 0 - assert 1572772440.000000924, sequence: 6170 - clear 0.000000000, sequence: 0 source 0 - assert 1572772440.999998834, sequence: 6171 - clear 0.000000000, sequence: 0 source 0 - assert 1572772442.000001424, sequence: 6172 - clear 0.000000000, sequence: 0 source 0 - assert 1572772442.999999478, sequence: 6173 - clear 0.000000000, sequence: 0 source 0 - assert 1572772444.000000128, sequence: 6174 - clear 0.000000000, sequence: 0 source 0 - assert 1572772444.999999537, sequence: 6175 - clear 0.000000000, sequence: 0 source 0 - assert 1572772446.000000578, sequence: 6176 - clear 0.000000000, sequence: 0
- If successful, make permanent by opening
/etc/modules
and addingpps-gpio
to the end. - Running a DUNE configuration with
Supervisors.ClockPPS
should now work