pendulum-project / ntpd-rs

A full-featured implementation of the Network Time Protocol, including NTS support.
https://trifectatech.org
Other
697 stars 40 forks source link

Add Pulse Per Second (PPS) Support #882

Open rlaager opened 12 months ago

rlaager commented 12 months ago

I could be missing it, but at a quick glance, I'm not seeing any support for PPS input. Ideally, there should be support for two configurations:

A) Using SHM from gpsd. You might call this "SHM support" and consider it a separate feature request.

B) Taking PPS from the kernel PPS API and using it to discipline the clock. The seconds would be numbered from other (e.g. Internet) sources.

I use configuration B in production with NTPsec (and formerly with classic ntpd). I have telecom grade GPS clocks which provide a PPS output (among other things).

While such devices can often act as NTP servers, sometimes this is a separately licensed (expensive) feature. In any case, their NTP server implementations are generally not as good in some respects (e.g. not supporting NTS). Likewise, newer ones tend to support PTP, but again, that can be an expensive licensed feature.

So I just use PPS from them. This is probably more accurate anyway, and allows me to be stratum 1 instead of stratum 2. I'm not trying to operate standalone (i.e. with no Internet access), so I don't need to get the TOD from GPS via serial. (And on my previous clocks, it was wrong due to GPS rollover anyway.)

davidv1992 commented 11 months ago

We indeed do not support this yet, primarily because we didn't have people who wanted it and so couldn't ask questions, so thank you for asking :).

I'll add this to the discussion internally for prioritization, but already have a few more specific questions:

rlaager commented 11 months ago

I'm using an Ocilloquartz (now ADVA) product. I was using a Symmetricom product before. I've got another system where I'm using a u-blox GPS evaluation board.

They all output a PPS which is connected into the computer on a serial port control line (DCD, I think).

The steps to configure on Debian (and with NTPsec) are:

  1. Install pps-tools and setserial.
  2. /etc/modules-load.d/pps-ldisc.conf contains pps_ldisc
  3. /etc/systemd/system/pps-ldisc@.service contains:
    
    [Unit]
    Description=Line Discipline for PPS Timekeeping for %i
    Before=ntpsec.service
    BindsTo=dev-%i.device
    Wants=systemd-modules-load.service
    After=systemd-modules-load.service
    After=setserial.service

[Service] ExecStart=/usr/sbin/ldattach pps /dev/%i Type=forking

[Install] WantedBy=ntpsec.service

4. `systemctl enable pps-ldisc@ttyS0`
5. One-time (or just reboot): `modprobe pps_ldisc` and `systemctl start pps-ldisc@ttyS0`
6. Then in `/etc/ntpsec/ntp.conf` (or `/etc/ntp.conf if building from source):

server 127.127.22.0 minpoll 3 maxpoll 3 prefer fudge 127.127.22.0 refid PPS


You can test the PPS input with `sudo ppstest /dev/pps0` (or `sudo ppswatch /dev/pps0`). You can see `ntpd` using with `ntpq -p` which should show a `PPS` line with `o` indicating it is being used:
 remote                                   refid      st t when poll reach   delay   offset   jitter

======================================================================================================= oPPS(0) .PPS. 0 l - 8 377 0.0000 0.0041 0.0008



Another good way of testing this would be to get a Raspberry Pi (which are finally relatively available again) and a GPS HAT for it.

Follow some HOWTO that uses gpsd and NTP or NTPsec, like this, which is the scenario "A" in the issue description:
https://www.ntpsec.org/white-papers/stratum-1-microserver-howto/
https://gpsd.gitlab.io/gpsd/gpsd-time-service-howto.html
or my notes:
https://coderich.net/2019/10/01/raspberry-pi-3-stratum-1-ntp-server-2/

I recommend that because you'll probably eventually want to support that too, and because following a HOWTO exactly as written is the best first step.

Once you have that working, convert it to the simpler scenario "B" (where you are just using PPS, no gpsd/SHM), still with NTP or NTPsec, using the notes above in this comment.

Once you have that working, stop NTP/NTPsec and work on implementing support in ntpd-rs for using the kernel PPS API to get the pulses. As with anything, start by just logging them or whatever. Once you can get pulses into ntpd-rs, then wire them in as a clock source to discipline the clock. At that point, you have a working scenario B.

Then you might consider implementing scenario A, talking to gpsd via SHM interface. If you go down the SHM road, see the recent changes relating to 32-bit time_t rollover: https://lists.ntpsec.org/pipermail/devel/2023-January/010167.html

Alternatively, you might want to implement the chrony socket interface. I don't know anything about it, but it's apparently a thing that exists and is probably better than the SHM interface. Since you're new, you might just skip SHM entirely.

I hope this helps. I'm available for more questions, though my response times may be longer than normal for the next month or two.
davidv1992 commented 11 months ago

Thank you for the information, this will definitely help when we get started on it. Timeline wise, we hope to have capacity to start working on this sometime this fall, but we don't have anything concrete yet.

Frankkkkk commented 3 weeks ago

@davidv1992 if it can help, I may be able to lend you root access to a PPS-"enabled" Raspberry Pi. It's rather easy to cross-compile to the armv7l arch and it may allow you to test code easily. Ping me if needed 👍

davidv1992 commented 3 weeks ago

We have such a raspberry pi ourselves so we should be good on that front, but thank you for the offer.