Skip to content

Instantly share code, notes, and snippets.

@john-g-g
Created December 21, 2019 21:03
Show Gist options
  • Save john-g-g/28fde21c8d875f4ceb76bb9a68b51e9b to your computer and use it in GitHub Desktop.
Save john-g-g/28fde21c8d875f4ceb76bb9a68b51e9b to your computer and use it in GitHub Desktop.
Script to configure raspberry pi hardware/software to act as GPSDO based chrony time server
#!/bin/bash
set -euo pipefail
if (( EUID != 0 )); then
echo "This script must be executed as root, eg, 'sudo $0'"
exit
fi
DEVICE=$(tr -d '\0' </proc/device-tree/model)
# install required software
apt-get install -y chrony pps-tools gpsd gpsd-clients
# backup /boot/config.txt
cp /boot/config.txt "/boot/config.txt.$(date +%s)"
# disable the console getty programs
# rpi 2
if [[ ${DEVICE} =~ 'Raspberry Pi 2' ]]; then
systemctl stop serial-getty@ttyAMA0.service
systemctl disable serial-getty@ttyAMA0.service
fi
# rpi 3
if [[ ${DEVICE} =~ 'Raspberry Pi 3' ]]; then
systemctl stop serial-getty@ttyS0.service
systemctl disable serial-getty@ttyS0.service
fi
# disable bluetooth on rpi 3
# see https://github.com/raspberrypi/linux/blob/rpi-4.19.y/arch/arm/boot/dts/overlays/disable-bt-overlay.dts
if [[ ${DEVICE} =~ 'Raspberry Pi 3' ]]; then
grep -q '^dtoverlay=pi3-disable-bt' /boot/config.txt || \
cat <<-"EOF" >> /boot/config.txt
# Do not use /dev/ttyAMA0 UART for Bluetooth
dtoverlay=pi3-disable-bt
EOF
grep -q '^enable_uart=1' /boot/config.txt || \
cat <<-"EOF" >> /boot/config.txt
# Enable hardware uart
enable_uart=1
init_uart_baud=115200
EOF
# disable the hciuart service that nominally attempts to talk to the UART
systemctl disable hciuart
fi
# disable cpu frequency scaling for more accurate timekeeping
grep -q '^force_turbo=1' /boot/config.txt || \
cat <<"EOF" >> /boot/config.txt
# cpu frequency stability
force_turbo=1
EOF
# edit /boot/cmdline.txt to disable serial console by removing: console=serial0,115200
cp /boot/cmdline.txt "/boot/cmdline.txt.$(date +%s)"
sed -i "s/console=serial0,115200//" /boot/cmdline.txt
# enable pps support in the kernel
## ADJUST GPIO PIN TO CORRECT PIN!!!
cp /boot/config.txt "/boot/config.txt.$(date +%s)"
grep -q '^dtoverlay=pps-gpio,gpiopin=pps-gpio,gpiopin=18' || \
cat <<"EOF" >> /boot/config.txt
# enable GPS PPS
dtoverlay=pps-gpio,gpiopin=18
EOF
# add pps-gpio module
echo 'pps-gpio' >> /etc/modules
# remove ntp-servers from /etc/dhcp/dhclient.conf
cp /etc/dhcp/dhclient.conf "/etc/dhcp/dhclient.conf.$(date +%s)"
sed -i 's/option ntp-servers//' /etc/dhcp/dhclient.conf
sed -i 's/, dhcp6.sntp-servers//' /etc/dhcp/dhclient.conf
sed -i 's/, ntp-servers//' /etc/dhcp/dhclient.conf
# delete these related files
rm -f /etc/dhcp/dhclient-exit-hooks.d/ntp \
/lib/dhcpcd/dhcpcd-hooks/50-ntp.conf \
/var/lib/ntp/ntp.conf.dhcp \
/etc/dhcp/dhclient-exit-hooks.d/chrony
# add gpsd config
cp /etc/default/gpsd "/etc/default/gpsd.$(date +%s)"
sed -i 's/^DEVICES=".*"$/DEVICES="\/dev\/ttyAMA0 \/dev\/pps0"/' /etc/default/gpsd
sed -i 's/^GPSD_OPTIONS=".*"$/GPSD_OPTIONS="-n"/' /etc/default/gpsd
# disable timedsync
systemctl stop systemd-timesyncd
systemctl daemon-reload
systemctl disable systemd-timesyncd
# configure chrony
cp /etc/default/gpsd "/etc/chrony/chrony.conf.$(date +%s)"
cat <<"EOF" > /etc/chrony/chrony.conf
# See chrony.conf(5) for more information about usuable directives.
pool us.pool.ntp.org iburst
# PPS: /dev/pps0: Kernel-mode PPS ref-clock for the precise seconds
refclock PPS /dev/pps0 refid PPS precision 1e-9 lock NMEA poll 3 trust prefer
# SHM(2), gpsd: PPS data from shared memory provided by gpsd
refclock SHM 2 refid PPSx precision 1e-9 poll 3 trust
# SOCK, gpsd: PPS data from socket provided by gpsd
refclock SOCK /var/run/chrony.pps0.sock refid PPSy precision 1e-9 poll 3 trust
# SHM(0), gpsd: NMEA data from shared memory provided by gpsd
refclock SHM 0 refid NMEA precision 1e-3 offset 0.5 delay 0.2 poll 3 trust require
# This directive specify the location of the file containing ID/key pairs for
# NTP authentication.
keyfile /etc/chrony/chrony.keys
# This directive specify the file into which chronyd will store the rate
# information.
driftfile /var/lib/chrony/chrony.drift
# Uncomment the following line to turn logging on.
log tracking measurements statistics
# Log files location.
logdir /var/log/chrony
# Stop bad estimates upsetting machine clock.
maxupdateskew 100.0
# This directive enables kernel synchronisation (every 11 minutes) of the
# real-time clock. Note that it can’t be used along with the 'rtcfile' directive.
rtcsync
# Step the system clock instead of slewing it if the adjustment is larger than
# one second, but only in the first three clock updates.
makestep 1 3
logchange 0.5
local stratum 10
allow 0/0
EOF
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment