TL-MR3020 NTP server, part 2
Part 1 was about the hardware, now for the software
Step 1: pps-gpio-poll package
This architecture doesn't support device tree yet, so it has a special pps driver. The repo for the driver package is at https://github.com/mlichvar/openwrt-pps-gpio-poll
I downloaded the lede-sdk for the ar71xx platform, and put the above git repo under the sdk's package/ dir.
# update the packages
./scripts/feeds update
# create a local signing key
./staging_dir/host/bin/usign -G -s ./key-build -p ./key-build.pub -c "Local build key"
# build the new package
make
# new package should be in this dir
ls bin/targets/ar71xx/generic/packages/*pps*
Step 2: build openwrt/lede image
Then I downloaded the lede-imagebuilder and built a sysupgrade image for my router. I already had openwrt on my TL-MR3020, so I'll be using sysupgrade to write the image to flash.
# change __LEDE_IMAGEBUILDER_DIR__ to whatever dir you put it in
cd __LEDE_IMAGEBUILDER_DIR__
# change __LEDE_SDK_DIR__ to whatever dir you put that in
cp __LEDE_SDK_DIR__/bin/targets/ar71xx/generic/packages/kmod-pps-gpio-poll*.ipk packages/
# build a TL-MR3020 image
make image PROFILE=tl-mr3020-v1 DEVICE_TYPE=lowrouter PACKAGES="kmod-pps chrony kmod-nbd nbd pps-tools kmod-pps-gpio-poll gpsd gpsd-clients kmod-usb-acm -iw -hostapd-common -kmod-ath -kmod-ath9k -kmod-ath9k-common -kmod-cfg80211 -kmod-mac80211 -swconfig -wpad-mini"
# check the image size
ls -l bin/targets/ar71xx/generic/*sysupgrade*
# copy the image to my router's ramdisk
scp bin/targets/ar71xx/generic/lede-17.01.6-ar71xx-generic-tl-mr3020-v1-squashfs-sysupgrade.bin root@mr3020.lan:/tmp/
I've removed all wireless to make room for gpsd and chrony. My GPS shows up as a usb-acm serial device, you might need a different kmod-usb-* package for different modules. Even with those changes, I only have 896kb free on the 4MB flash. I included nbd so I could use network storage for other packages and logging.
Step 3: apply image
After using sysupgrade to apply the image, I waited for it to reboot.
Step 4: configure sysntpd & gpsd
After it came back, I disabled sysntpd in /etc/config/system
under section config timeserver ntp
with option enabled 0
. I configured gpsd in /etc/config/gpsd
to auto start and listen on /dev/ttyACM0
. I started gpsd and verified that it was working with cgps
.
Step 5: enable and test pps
I then loaded the pps module with insmod pps-gpio-poll gpio=29
.
Kernel messages:
[ 146.578832] pps pps0: new PPS source pps_gpio_poll
[ 146.582189] pps-gpio-poll: Registered GPIO 29 as PPS source (precision 85 ns)
Verify pps is returning results:
# ppstest /dev/pps0
..
source 0 - assert 1544389003.000044807, sequence: 33 - clear 0.000000000, sequence: 0
Step 6: chronyd
configure chrony in /etc/chrony/chrony.conf
:
refclock PPS /dev/pps0 refid PPS poll 4 prefer
refclock SHM 0 delay 0.2 refid NMEA noselect poll 6 dpoll 0
Start chronyd and verify that the PPS source is working with chronyc sources
:
MS Name/IP address Stratum Poll Reach LastRx Last sample
===============================================================================
#* PPS 0 4 377 22 +62ns[ -264ns] +/- 16ns
Step 7: results
After setting up logging to the nbd drive and graphing with chrony-graph (instructions skipped because it'd make this long article even longer), this system stays in very close sync with the gps (+/- 60ns 50% of the time, +/-440ns 99% of the time):
Interestingly, there's a 55us offset between my two local clocks. I am still figuring out where this is coming from.