pc_engines_apu1_hopf_clock_ntp
Table of Contents
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).
- NTP source code download.
Documentation
- 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 <<EOF KERNEL=="ttyS0", SYMLINK+="refclock-0" KERNEL=="ttyS0", RUN+="stty -F /dev/%k 9600 cs8 -cstopb -parenb" KERNEL=="ttyS0", TAG+="systemd", ENV{SYSTEMD_WANTS}="pps.service" KERNEL=="pps0", SYMLINK+="refclockpps-0" EOF
- 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.<code> 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 <<EOF [Unit] Description=Network Time Service After=syslog.target ntpdate.service sntp.service Conflicts=systemd-timesyncd.service [Service] Type=forking ExecStart=/usr/local/bin/ntpd -g -u ntp:ntp PrivateTmp=true [Install] WantedBy=multi-user.target EOF systemctl enable ntpd systemctl start ntpd cat > /etc/systemd/system/pps.server <<EOF [Service] Type=simple ExecStart=/usr/bin/ppsldisc /dev/ttyS0 EOF
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"
pc_engines_apu1_hopf_clock_ntp.txt · Last modified: 2021/10/09 15:14 by 127.0.0.1