A guide to build a NTP server with GPS/PPS
- Operation confirmed with testing in our ODROID-N2 on 4.9.141 kernel with our custom setup.
You can build your own NTP server with GPS and PPS on your ODROID.
We will use modern NMEA driver on NTP service.
Requirements:
- and some tools for making an USB GPS module GPIO-accessable
This gives you very accurate time and would be helpful for specific use cases.
The atomic clocks in the GPS satellites are monitored and compared to 'master clocks' by the GPS Operational Control Segment; this 'GPS time' is steered to within one microsecond of Universal Time.
Our GPS receiver provides 1PPS output signal but you need a wire soldering.
This pulse has a rising edge aligned with the GPS second, and is used to discipline local clocks to maintain synchronisation with Universal Time (UT).
So our local server can have a very accurate time with less than 10 microseconds of tolerance hopefully.
Make a GPS module GPIO-accessable
Before you start, you have to fix your USB GPIO module to put PPS via GPIO.
Required tools are:
- One our GPS module
- A nipper
- A screw driver
- An insulating tape
- A cutter
- A jump cable
- And soldering tools (Not in the screenshot above)
Disassemble GPS module
There are 4 screws on the back of the GPS module. They are covered by a back sticker, so you should find out where they are at by rubbing that.
And after that, cut the sticker and detach the cut part to unscrew the 4 screws.
May you can see the following photos to get help.
Uncover and soldering
Uncover the module and you can see a PCB board, which is what you have to soldering out.
Very important part of this guide. You have to soldering out a jump cable to the exact pin of the chip.
Location of the pin is shown on the following photo.
Be careful of the short circuit. PPS comes out of that pin.
If you've done so, you may clean up the cable as shown the photo below.
Assemble and connect
Place it like before and screw out again.
Connect the jump cable to the GPIO pin #11.
Connect the USB cable to the ODROID-N2, and connect LAN, power cable as well.
Well done.
Build a new kernel supporting a PPS client from GPIO
Our mainline kernel doesn't fully support PPS from GPIO. Some required setups should be done by you.
So you should build your own kernel on your ODROID-N2.
- This guide is for native build on your ODROID-N2. Don't proceed with your PC.
- Install our Ubuntu image and update/upgrade first.
A. Prepare Linux kernel source from Github
sudo apt update \ && sudo apt install git gcc build-essential libncurses-dev bc
Get the Linux kernel source from our official Github repository.
ODROID-N2
git clone --depth 1 https://github.com/hardkernel/linux.git -b odroidn2-4.9.y odroidn2-4.9.y \ && cd odroidn2-4.9.y
ODROID-C4
git clone --depth 1 https://github.com/hardkernel/linux.git -b odroidc4-4.9.y odroidc4-4.9.y \ && cd odroidc4-4.9.y
B. Add PPS support
Edit arch/arm64/boot/dts/amlogic/meson64-odroidn2.dts file to add a new device which getting PPS from GPIO #11.
ODROID-N2
vi arch/arm64/boot/dts/amlogic/meson64-odroidn2.dts
ODROID-C4
vi arch/arm64/boot/dts/amlogic/meson64-odroidc4.dts
Add following contents.
/ { ... /* add for pps-gpio */ pps { compatible = "pps-gpio"; gpios = <&gpio GPIOX_3 GPIO_ACTIVE_HIGH>; status = "okay"; }; }; ...
And make a custom menuconfig.
ODROID-N2
make odroidn2_defconfig
make menuconfig
ODROID-C4
make odroidc4_defconfig
make menuconfig
Find and enable with space key:
- Device Drivers→[*]PPS Support
- Device Drivers→[*]PPS Support→<M>PPS client using GPIO
C. Build and install a new kernel
Simple.
make -j$(expr $(nproc) - 1)
Then install the new kernel.
ODROID-N2
sudo make modules_install \ && sudo cp -f arch/arm64/boot/Image.gz /media/boot \ && sudo cp -f arch/arm64/boot/dts/amlogic/meson64_odroidn2.dtb /media/boot \ && sudo sync
sudo reboot
ODROID-C4
sudo make modules_install \ && sudo cp -f arch/arm64/boot/Image.gz /media/boot \ && sudo cp -f arch/arm64/boot/dts/amlogic/meson64_odroidc4.dtb /media/boot \ && sudo sync
sudo reboot
Check if the device drivers work
If your custom settings works well, that would make new devices at /dev. Let's check them.
ls -al /dev/{ttyACM*,gps*,pps*}
# results crw------- 1 root root 248, 0 Jan 31 14:21 /dev/pps0 crw-rw---- 1 root dialout 166, 0 Jan 31 14:53 /dev/ttyACM0
If any one on the example above doesn't exist, you've done on something wrong way, try to set/build the kernel again.
If all of them exist, make soft link files to use further after.
sudo ln -sF /dev/ttyACM0 /dev/gps0
sudo ln -sF /dev/pps0 /dev/gpspps0
ls -al /dev/{ttyACM*,gps*,pps*}
# results lrwxrwxrwx 1 root root 12 Jan 31 15:50 /dev/gps0 -> ttyACM0 lrwxrwxrwx 1 root root 9 Jan 31 15:51 /dev/gpspps0 -> /dev/pps0 crw------- 1 root root 248, 0 Jan 31 15:50 /dev/pps0 crw-rw---- 1 root dialout 166, 0 Jan 31 15:50 /dev/ttyACM0
Make sure your result like above.
Make GPS works
Install GPS related packages and configure it.
sudo apt install gpsd gpsd-clients \ && sudo dpkg-reconfigure gpsd
And test.
sudo gpsmon /dev/gps0
An example screenshot using “gpsmon /dev/gps0”.
Wait more than 5 minutes to get GPS information properly.
Make PPS works
Install PPS tools.
sudo apt install pps-tools
Test.
sudo ppstest /dev/gpspps0
# results trying PPS source "/dev/gpspps0" found PPS source "/dev/gpspps0" ok, found 1 source(s), now start fetching data... source 0 - assert 1517363638.431673232, sequence: 130 - clear 0.000000000, sequence: 0 source 0 - assert 1517363639.431676649, sequence: 131 - clear 0.000000000, sequence: 0 ...
A new row starting with “source 0 - assert …” will be added for every each second.
Install NTP service package
Install NTP service.
sudo apt install ntp
Edit /etc/ntp.conf file to use GPS/PPS.
Back up original file, and create a new configuration file including setup below.
sudo mv /etc/ntp.conf /etc/ntp.conf.bak
sudo vi /etc/ntp.conf
# /etc/ntp.conf, configuration for ntpd; see ntp.conf(5) for help # Drift file to remember clock rate across restarts driftfile /var/lib/ntp/ntp.drift # Server from generic NMEA GPS Receiver # server: NMEA serial port (/dev/gps0), mode 16 = 9600 baud + 2 = $GPGGA # fudge: flag 1 for use PPS (/dev/gpspps0), time2 for calibration time offset server 127.127.20.0 mode 18 minpoll 3 maxpoll 3 prefer fudge 127.127.20.0 flag1 1 time2 0.000 refid gPPS
Note that time2 parameter(0.000) is for editing time offset for calibrating the result time.
Lastly, restart NTP service.
sudo service ntp restart
sudo service ntp status
# results ● ntp.service - LSB: Start NTP daemon Loaded: loaded (/etc/init.d/ntp; bad; vendor preset: enabled) Active: active (running) since Wed 2018-01-31 17:44:58 KST; 3s ago Docs: man:systemd-sysv-generator(8) Process: 744 ExecStop=/etc/init.d/ntp stop (code=exited, status=0/SUCCESS) Process: 754 ExecStart=/etc/init.d/ntp start (code=exited, status=0/SUCCESS) CGroup: /system.slice/ntp.service └─765 /usr/sbin/ntpd -p /var/run/ntpd.pid -g -u 111:115 Jan 31 17:44:58 odroid ntp[754]: ...done. Jan 31 17:44:58 odroid systemd[1]: Started LSB: Start NTP daemon. Jan 31 17:44:58 odroid ntpd[765]: proto: precision = 1.375 usec (-19) Jan 31 17:44:58 odroid ntpd[765]: Listen and drop on 0 v6wildcard [::]:123 Jan 31 17:44:58 odroid ntpd[765]: Listen and drop on 1 v4wildcard 0.0.0.0:123 Jan 31 17:44:58 odroid ntpd[765]: Listen normally on 2 lo 127.0.0.1:123 Jan 31 17:44:58 odroid ntpd[765]: Listen normally on 3 eth0 192.168.100.28:123 Jan 31 17:44:58 odroid ntpd[765]: Listen normally on 4 lo [::1]:123 Jan 31 17:44:58 odroid ntpd[765]: Listen normally on 5 eth0 [fe80::4db2:ce0b:48f3:26af%2]:123 Jan 31 17:44:58 odroid ntpd[765]: Listening on routing socket on fd #22 for interface updates
Wait, and get accurate time from GPS/PPS
Wait for a while, at least 20 minutes to become stable state.
The PPS output is enabled only when it gets several satellites stably.
And you can see the results below.
ntpq -p
# results; Check that 'o' character exists before IP numbering and reach value is increasing up to 377. remote refid st t when poll reach delay offset jitter ============================================================================== oGPS_NMEA(0) .gPPS. 0 l 1 8 377 0.000 0.008 0.002
ntptime
# results; Check that estimated error is just 1 us(Microsecond). ntp_gettime() returns code 0 (OK) time de1bee1d.49adfb50 Wed, Jan 31 2018 16:26:21.287, (.287811636), maximum error 2000 us, estimated error 1 us, TAI offset 0 ntp_adjtime() returns code 0 (OK) modes 0x0 (), offset -3.606 us, frequency 1.000 ppm, interval 1 s, maximum error 2000 us, estimated error 1 us, status 0x2001 (PLL,NANO), time constant 3, precision 0.001 us, tolerance 500 ppm,
Note that ..
- The soft link file /dev/{gps0,gpspps0} will disappear when you reboot your ODROID. If you've to reboot, create a new soft link and restart NTP service.
- Using GPS module while NTP service based on GPS/PPS is running can break your NTP server work. Reboot.
- For more details for setting up GPS/PPS NTP server, visit following sites.