=====PC Engines APU1 - Hopf NTP Server=====
====Requirements====
* PC Enginges board, with DCD line (APU = ok, ALIX = not ok)
* Debian 10 installed.
* Getty on ttyS0 disabled.
* APU1 to Hopf 7001 system connected over serial (see wiring below).
* Hopf 7245 interface card configured for NTP (see 7245 interface board documentation).
* [[http://www.ntp.org/downloads.html|NTP source code]] download.
====Documentation====
* [[https://www.hopf.com/documents_en.php|Hopf documentation]]
* {{ ::7001-7015dcf77_v0801_en.pdf |Hopf 7001DCF77 system}}
* {{ ::7245_v0600_en.pdf |Hopf 7245 interface board}}
* {{ :apu1.pdf |PC Engines APU1 board}}
* Interface board 7245 DIP-switch settings.
1 = on
0 = off
SW1 SW2 SW3
12345678 12345678 12345678
11111001 11000111 11111110
====Serial cable====
* Construct a serial cable to route PPS to DCD.
Hopf 7245 1 GND --------- 5 GND PC Engines
S1 RS232 2 TXD --------- 2 RXD APU1 board
6 RTS (PPS) --- 1 DCD
====Install packages====
* Install required tooling.
apt install build-essential libcap-dev pps-tools
====Create device symlinks and PPS device====
* Create new udev rules file.
cat > /etc/udev/rules.d/hopf.rules <
* Reload the udev rules or reboot to test.
ls -l /dev/refc*
lrwxrwxrwx 1 root root 5 Jan 4 14:37 /dev/refclock-0 -> ttyS0
lrwxrwxrwx 1 root root 4 Jan 4 14:37 /dev/refclockpps-0 -> pps0
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 1578145727.901770116, sequence: 1313 - clear 1578145072.692767609, sequence: 2
source 0 - assert 1578145728.000351551, sequence: 1314 - clear 1578145072.692767609, sequence: 2
source 0 - assert 1578145728.901731373, sequence: 1315 - clear 1578145072.692767609, sequence: 2
source 0 - assert 1578145729.000557999, sequence: 1316 - clear 1578145072.692767609, sequence: 2
^C
====Install NTP====
* Disable and remove other time sync applications.
apt-get remove --purge ntp chrony
timedatectl set-ntp false
systemctl stop systemd-timesyncd
systemctl disable systemd-timesyncd
* Add ntp user.
groupadd ntp
useradd -c "Network Time Protocol" -d /var/lib/ntp -g ntp -s /bin/false ntp
usermod -a -G dialout ntp
* Create directories.
install -v -o ntp -g ntp -d /var/lib/ntp
install -v -o ntp -g ntp -d /var/log/ntpstats
* Compile source code.
tar zxf ntp-4.2.8p13.tar.gz
cd ntp-4.2.8p13
# from Linux From Scratch
./configure CFLAGS="-O2 -g -fPIC" \
--prefix=/usr \
--bindir=/usr/sbin \
--sysconfdir=/etc \
--enable-linuxcaps \
--enable-parse-clocks \
--with-lineeditlibs=readline \
--docdir=/usr/share/doc/ntp-4.2.8p13
make
make install
* Add systemd services.
cat > /etc/systemd/system/ntpd.service < /etc/systemd/system/pps.server <
====Hopf DCF /etc/ntp.conf====
* Create /etc/ntpd.conf.
#Stratum level when no ref source available
tos orphan 12
# Hopf DCF clock
# Mode 12 + 128 (pps) = 140
server 127.127.8.0 mode 140
fudge 127.127.8.0 refid PPS # Reference identifier
#leapfile /etc/leap_second
restrict -4 default notrap nomodify nopeer noquery
restrict -6 default notrap nomodify nopeer noquery
restrict 127.0.0.1
restrict ::1
statsdir /var/log/ntpstats/
statistics loopstats peerstats clockstats
filegen loopstats file loopstats type day enable
filegen peerstats file peerstats type day enable
filegen clockstats file clockstats type day enable
driftfile /var/lib/ntp/ntp.drift
====Check timecode====
ntpq -c 'cv 0 timecode'
timecode="\x02CB154556010120\x0a\x0d\x03"
====Nagios Hopf 7001 check====
#!/bin/bash
#
# Tested with Hopf 7001 DCF Base station with 7245 serial interface boards
# Datastring 7001/6021
#
# BS, 2013/05
ntpq="/usr/bin/ntpq"
# get timecode variable, received from the clock
eval `$ntpq -c 'cv 0 timecode'`
function quit {
case "$2" in
0) echo "OK: $1"
exit 0
;;
1) echo "Warning: $1"
exit 1
;;
2) echo "Critical: $1"
exit 2
;;
3) echo "Unknown: $1"
exit 3
;;
esac
}
function clockstat {
# Status nibble from hex
hex0=0000
hex1=0001
hex2=0010
hex3=0011
hex4=0100
hex5=0101
hex6=0110
hex7=0111
hex8=1000
hex9=1001
hexA=1010
hexB=1011
hexC=1100
hexD=1101
hexE=1110
hexF=1111
eval statnibble='hex$1'
snibble=${!statnibble}
case ${snibble:0:2} in
00)
textstatus="time/date invalid"
exitcode=2
;;
01)
textstatus="crystal operation"
exitcode=1
;;
10)
textstatus="radio operation"
exitcode=0
;;
11)
textstatus="radio operation (high accuracy)"
exitcode=0
;;
esac
case ${snibble:2:1} in
0)
dss="standard time"
;;
1)
dss="daylight saving time"
;;
esac
case ${snibble:3:1} in
0)
ann="no announcement hour"
;;
1)
ann="announcement (ds-st-ds)"
;;
esac
quit "status hex=\"$1\", bin=\"$snibble\": $textstatus, $dss, $ann" $exitcode
}
# check for complete string, for example: \x028D194223310513\x0a\x0d\x03
# This is from the Hopf 7245 serial interface board
#
# x20 = Space
# x0D = CR (carriage return)
# x0A = LF (line feed)
# x02 = STX (start of text)
# x03 = ETX (end of text)
#
if [[ $timecode == \\x02*\\x0a\\x0d\\x03 ]];
then
clockstat ${timecode:4:1}
else
quit "Timecode not complete" 3 # return Unkown status
fi
=====Troubleshooting=====
* Show peer status: ntpq -p
* Show timecode from receiver: ntpq -c 'cv 0 timecode'
* Show client list (max. 600): ntpdc -n -c monlist
## ntp 2.4.7 removed monlist in favour of ntpq's mrulist
ntpq -c "mrulist"
{{tag>[hardware alix ntp]}}