How-to use a Garmin 18x with Chrony and PPS

So does SHM(1) provided by gpsd, so there shouldn’t be a need to combine it with SHM(0) on chronyd’s end. And strictly speaking, the combining is done by gpsd, and chronyd or ntpd simply have the ability to process the combined input.

Has this line been edited? Because it looks strange: The timestamp is about 6 seconds after kernel start, not hours. It is exactly the same timestamp as the one for the message about the source having been added. And at least a quick brute-force search in the kernel sources doesn’t turn up where that message would be generated (as starting point to see what causes it being generated).

The device showing up under a new name usually means something is still using the device with the “old” name.

As I understand it, chrony/ntp needs the PPS discipline signal to know when the NMEA/GPS time/second actually starts. Without it, the NMEA/GPS will be ignored because the offset would vary way too much to be reliabe. SOCKS output from GPSD combines the PPS with NMEA, so Chrony would recieve not only the second, but also exactly when that second starts. In all the examples I’ve seen using SHM, it’s always using both SHM0 and SHM1 for the NMEA and PPS lines (or a different PPS source if not using SHM1). I haven’t come across any reference either, to gpsd having a combined PPS disciplined SHM, like it is for SOCK.

It was a quick cut and paste I did of the last line previous to it. I had meant to edit the time to something similar to what I see. But you’r in luck, as I just checked the server and sure enough, it dropped PPS again.

[30252.431226] pps pps0: removed

Its been around the 30k+ range that last few times, though I have seen it as high as in the 50k time range.

Yeah, I found that out when I tried searching up information on ldattach. That’s when I lreaned about searching for the PID and killing whatever process is still trying to run, but strangely (not strangely?), nothing is found.

pidof pps - returns nothing
ps -ef | grep pps - returns the gpsd instance that is running, and the search I just did.

So as far as I can see, there is no pps_ldisc at all running on the system. ppstest returns "/dev/pps0" (No such file or directory).

If I now run ldattach -s 38400 PPS /dev/ttyS0, I get:

[40066.581950] pps pps1: new PPS source serial0
[40066.581958] pps pps1: source "/dev/ttyS0" added

Running ppstest on the new pps1 returns a working PPS signal.

I’m at a loss. The only other major change I did was downgrading from Debian 12 to 11 cause I trying out some SDR software that was made for 11, not 12. Not a big deal going back to 12, but of course that means reinstalling from ISO and re-doing all my settings again.

Just give it a try.

Not sure why I should be in luck because of the issues you’re experiencing… :wink:

That’s likely the one you apparently told to hold on to pps0.

When using gpsd, one usually doesn’t need to use ldattach or some other tool to explicitly set the line discipline. gpsd does that itself internally.

Having two processes access the same device simultaneously in many cases isn’t a good idea, strange things may happen. Linux let’s one do such things, assuming the admin knows what they’re doing, but they get to keep the pieces if things break.

So I’d use either ldattach or similar, then have chronyd access the pps device, requiring to get the seconds numbering from somewhere else (e.g., the native USB port of a u-blox). Or use gpsd to get both the PPS and seconds numbering from the same device, without ldattach.

A third option (and there’s probably more) would be to have gpsd set the line discipline, then have chronyd pick up the PPS from the pps device that that attachment created. Maybe that is what you’ve been doing implicitly, assuming gpsd is running before ldattach, so the pps0 is really not “generated” by ldattach, but gpsd. But then, you’re at the mercy of gpsd to keep up the line discipline. And if it doesn’t for whatever reason, and as the “removed” line might hint at, the PPS signal you acces becomes unavailable.

I’ll remove ldattach from startup, but as I recall when I tried to use gpsd without ldattach, gpsd would not find or use the PPS signal.

Then that is something to investigate.

I have to admit I don’t fully “trust” gpsd doing the best as far as evaluating the PPS signal for timekeeping purposes is concerned, or how that impacts chronyd/ntpd timekeeping when getting the PPS indirectly this way, vs. the timekeeping daemon accessing the PPS signal directly itself, e.g., any sample processing in the different drivers. But it would be a stable, working baseline to start from and then try to improve upon going forward, vs. having a whole bunch of unknown variables and pitfalls right in the first (or at least one of the first) step(s).

I actually skipped gpsd on the RPi servers I had running NTP, since NTP could directly access the NMEA and PPS signal with it’s built in drivers (127.127.20.u and 127.127.22.u). That and gpsd SHM never seemed to work right on the RPi setup. It would be working fine when I set it up, but when I reboot the system, it was no longer working. :person_shrugging:

Since switching to Chrony, I don’t see any way listed in it’s documents to do the same as I did with NTP except for the PPS, so I had to use gpsd. I don’t “trust” gpsd either, as imo it’s just another layer of software running inbetween the GPS and time daemon, that can add latency (little as it may be) and/or jitter. Which is kinda ironic for me to think that, cause gpsd is supposed to reduce jitter, and additonally, combine the PPS with NMEA time so that step doesn’t have to be performed by the time daemon.

I’ve removed ldattach from startup and rebooted, and kernal still found and mounted the PPS signal at bootup, which is strange cause I clearly had the issue that it wouldn’t do so after a reboot previously. I’ll need to keep testing (rebooting) to see if it sets up PPS everytime properly, but for now it appears to be working after this reboot. I’ll leave it running for now and check back again later to see if it dropped PPS again.

I use the PPS driver accessing GPIO PPS as well, plus gpsd or some external source for seconds numbering. Once used the RPi’s serial port as well, but too many manual steps making that available for replications, so don’t do that anymore. The u-blox’s USB port is a good, easier alternative for native NMEA, vs. the RPi’s UART. Or a USB-UART bridge.

Might be a timing issue. One of them, I think the timekeeping daemon, needs to first set up the SHM segments before the other can use them. So if they start in the wrong order, the communication doesn’t work.

I don’t think that is a problem. PPS is essentially about taking a timestamp of system time when a pulse occurs, and whether chronyd/ntpd does that, or gpsd does it and ships that info to the timekeeping daemon shouldn’t make much of a difference. It’s just seeing some design choices by the gpsd maintainer in other places I have looked at that don’t instill much confidence that they are not trying to do something “smart” in this area as well. But that’s my personal reason for not fully trusting gpsd.

But in general, more layers of software just doesn’t help transparency. And I am concerned that PPS sample processing in other drivers might just not be as good as in the dedicated PPS driver. But that is just a feeling, no evidence/hard indications that PPS processing in non-PPS drivers might be substantially worse than in the dedicated driver. Still, e.g., off the top of my head, I am not sure about what gpsd ships in case of a combined signal, whether it is shipping the raw PPS and NMEA info, just within the same data stream, and the timekeeping daemon then “sees” and processes them differently. Or whether gpsd already preprocesses the two streams and combines them into a new, synthesized signal, and that “cooked” data is then shipped to the timekeeping daemon. In the latter case, as you point out, I would always assume the timekeeping daemon to better handle the combining of the two than some external component whose primary purpose isn’t timekeeping.

I am not entirely sure whether “combining” in gpsd is done in the sense of synthesizing a new signal, or just shipping the two signals in a single data stream. At least in the former case, I’d assume the timekeeping daemon to do better in “combining” the signals vs. some external software doing that.

When you use gpsd, the pps device appearing is just a side effect, giving a hint, but not strictly a necessity (unless when you rely on that device because you want to access it directly, which you typically don’t when using gpsd). The crucial thing is whether gpsd is able to pick up the PPS signal.

A good indication that maybe it wasn’t ldattach that was triggering the creation of the pps device before, but gpsd.

Do you load the module ppsldisc at boot?
Because if you do, then ldattach isn’t needed as this module does it for you.

As for Chrony, the lines I used and tested…

# GPS on RS232 isn't needed for total time.
refclock SHM 0 refid GPS poll 4 precision 1e-3 offset 0.090 delay 0.2
#refclock SHM 1 refid PPS poll 2 lock GPS precision 1e-9 rate 1 width 0.5 maxlockage 32 prefer
refclock PPS /dev/pps0 lock GPS refid PPS poll 2 precision 1e-9 prefer maxlockage 32 prefer

I do not use sockets, never got that to work.

You need to use 2 lines as far as I know, then it has GPS as main source and PPS is correcting that clock.
Because GPS is delayed, it will never be selected at source.
Maxlockage is used to have a better precision as it uses more samples to determine the correct time.

One thing I did learn, you should not correct offset on the PPS signal, it will give weird effects if you do.
Also, the GPS signal needs to be less then 40msec off the real-time else PPS can’t lock.

The offset of GPS can be read with ‘chrony sourcestats’, it will tell you the offset and you can use that number directly to remove the ‘offset’

Run Chrony for like 10 minutes, then set your offset, then run 10 minutes again and it should be running near 1~5ms offset, often less, depending on the weather.

PPS should show upto 1~500ns offset, again, depending on the weather and other things.
If the offset is very high, then it’s usefull to correct it, e.g. when using an USB-PPS GPS.

During my tests and RS-232 connected PPS doesn’t need offset-corrections.

Hope this helps.

1 Like

On a typical Linux system, this is not needed. Linux will load this on demand if functionality implemented by the module is needed, just like any other module. To verify, run rmmod ppsldisc on your system (you may have to stop users of the module such as gpsd or ldattach), then start a program requiring the module, then check with lsmod.

I don’t think so. How would the module know which device to attach to if there are multiple ones, unless it blindly attaches to all eligible? If you automatically start gpsd on system boot, I believe that is what is triggering all the magic you attribute to loading of the ppsldisc module, including loading of the module itself.

Depends if the kernel is compiled with the module or not.

Mine isn’t, if I remove the ppsldisc from loading, there is NO PPS device.

Linux does not load modules automatically when they are not compiled into the kernel.

If not compiled, you need to load them yourself as add-on. Linux does not load them if not specified or compiled.

I needed to load it, and specify it in devices with GPSD for it to work when loaded.

I never got PPS automatically with Debian. Only after adding the module by hand to be loaded AND specified in GPSD so it’s activated.

Works for me.

Because loading the module is not what triggers the device node creation.

That is a contradiction in itself. If a module is compiled into the kernel, it doesn’t need to be loaded. It is inseparably contained within the binary blob that is the kernel (statically linked would be the expression if we were talking about programs, vs. dynamically linked as analogy for separate kernel modules). I guess part of the issue is generally fuzzy use of the term “module”, sometimes referring to a functional component of the kernel as such, e.g., a driver that can be enabled or disabled during kernel compilation. Other times, it refers to when such a driver is its own binary blob that needs to be loaded when needed.

Obviously cannot contradict your experience, just find it very strange.

Sure, explicitly loading a module doesn’t hurt. It just obfuscates what is really required, and thus makes it difficult to troubleshoot the whole process if things don’t work because there are more apparently moving parts than strictly required.

You lost me.

I load the module…

Then GPSD starts, with this in /etc/default/gpsd

# Devices gpsd should collect to at boot time.
# They need to be read/writeable, either by user gpsd or the group dialout.
DEVICES="/dev/ttyS0 /dev/pps0"
BAUDRATE=9600
# Other options you want to pass to gpsd

GPSD_OPTIONS="-n -N"

# Automatically hot add/remove USB GPS devices via gpsdctl
USBAUTO="false"

If I do not load the module, GPSD has no PPS.

The file does differ from version to version, options with extra ‘-s 9600’ does the same.

Anyway, if I do not load the module, I have no PPS. Not in GPSD not created.
Just NMEA.

[33656.196936] pps pps0: removed
rmmod ppsldisc
rmmod: ERROR: Module ppsldisc is not currently loaded

It’s still being unloaded on my system. However, this time around if I use ldattach it doesn’t create a new pps1, it still uses pps0.

[33656.196936] pps pps0: removed
[39812.762924] pps pps0: new PPS source serial0
[39812.762937] pps pps0: source "/dev/ttyS0" added

I’m going to go back to Debian 12 and see if that fixes it. If it does, then its more then likely an issue between the OS/driver and serial chip on the board.

Apologies, that was obviously not my intention. Your previous post contained a series of claims and statements. I was merely trying to follow the structure given by your post by breaking out individual statements/claims by quoting them, followed by my thoughts on on each specific individual statement/claim.

As that didn’t work, not sure how else to respond to be clearer. Except maybe by repeating, concisely en bloc, my assertions, but not sure that’ll help either.

  • On vanilla installations of modern major Linux distributions, explicitly loading kefnel modules is typically not required, including ppsldisc.
  • Instead, in case of ppsldisc, attaching the PPS line discipline to a serial interface using, e.g., ldattach or gpsd, will trigger automatic loading of the module.
  • It is not the loading of the ppsldisc module that causes the pps device to appear, but attaching the PPS line discipline to a serial interface, e.g., using one of the previously mentioned commands.
  • If using gpsd on a serial device, gpsd will automatically attach the PPS line discipline to it, and, if available evaluate the PPS signal.
  • The pps device appearing is a side effect of the line discipline being attached to the serial device, but it is not needed for gpsd to read the PPS signal.
  • I.e., if gpsd is used to read the PPS signal from a serial line, the pps device created from that serial line does not need to be added to gpsd’s configuration.
  • What the pps device could be used for is to let chronyd et al. access the PPS signal directly, bypassing gpsd’s handling of it. But then you are at the mercy of keeping the line discipline attached to the serial port, and gpsd simply removes the line discipline anytime it has issues doing its own internal processing of th PPS signal. I hypothesize that that is what @Mpegger have been experiencing, as they have described in this thread.
  • If you have a different experience, that surprises me. But I am happy to hear more about your setup, looking forward to learn new things.

How do you determine that? SHM 0 and SHM 2 only have NMEA for sure, but SHM 1 and SHM 3 do incorporate the PPS signal.

How do you determine this?

Sorry, I don’t understand this sentence, and since we need to be mindful of details to avoid misunderstandings, I’d rather not apply some interpretation from my side.

How do you determine this?

Reading this it seems that the /dev/pps0 option being added into /etc/default/gpsd is not actually needed. Reading through the documents (again) https://gpsd.gitlab.io/gpsd/installation.html -

This may not be a Raspi, but it is gpsd: 3.22 (revision 3.22), so I proceeded to omit the /dev/pps0 option in the config and restarted gpsd in systemctl. Lo and behold, gpsd has PPS without the added option, and testing with gpsmon shows a PPS signal. What’s more, there is only 1 PPS signal in gpsmon. Previously, there was always 2 PPS signals back to back. It seems like gpsd was detecting both the rising edge and falling edge of the PPS signal, though till now I didn’t realize that was happening. It’s possible gpsd (or kernal?) was dumping the PPS because of the 2 detected signals. I will leave it again and come back to it later to see if it indeed keeps the PPS now. If not, I’ll go back to Debian 12 for sure.

My point was not to worry about that module if you use gpsd. The pps device being created if gpsd is started, and the device being removed when gpsd is stopped, or encounters an issue, is one indication it is doing in the background whatever is needed to get the PPS signal. Using gpsmon when gpsd is running should more definitively show whether gpsd is reading the PPS signal.

Because gpsd isn’t blocking the device node.

One issue with gpsd is that it easily gives up, and unfortunately for good, when there is an issue handling the PPS signal. I would expect gpsd to pick up the PPS signal again when it is restarted. Increasing the debug level of gpsd could help identify why gpsd is dropping the line discipline (as a side effect of stopping its own processing of the PPS signal). But if the drop comes after a few hours only, that will create a lot of logs…

Sure, that could cause gpsd to drop the line discipline. One brute force way to handle this would be to detect the condition (gpsd will stop reporting time via SHM 1 when this happens, which should become visible in the output of chronyc) via script, and to then restart gpsd. Not pretty, but effective.

The RPi is a special case. Without having double-checked the source you mention, this looks like the pps0 device in this case is not related to the serial device, but a “standalone” PPS signal input via GPIO pin. And since the RPi’s on-board UART does not have a DCD line (at least not in “earlier” models), this is a case where a standalone PPS signal needs to be combined with a separate and truly NMEA-only (no PPS on serial) serial port. The version-related stuff only relates to later versions of gpsd having an automated way to detect this without specific configuration (the on-board serial device appears as /dev/ttyAMA0, which gpsd takes as a trigger when being configured to use that device to automagically usurp an existing pps0 as well), while earlier versions needed to be told more explicitly about this RPi-specific setup.

My hypothesis would be that this could have been caused by having the pps device configured in addition to gpsd already picking up the PPS signal directly from the serial device. What was the time difference between the signals? If it were the two edges of the signal, it should be 10ms, 100ms, or more (I think u-blox default pulse length is 100ms).

But overall glad it seems to work now (except for the PPS signal being dropped after some time).

Well now this is different…

PPS got dropped again, but dmesg | grep pps does not show any new pps0: removed as it usually does.

Guess I’ll go back to Debian 12, but that’ll be for tommorrow.

On my Debian 12 I have to load ppsldisc-module, when started the PPSx is created and I must define it as device else my GPSD (AMD64 Linux) doesn’t have PPS in e.g. GPSMON.

If I fail to load the module, I must use LDATTACH to get it started.
But still it must be defined in GPSD as device.

I have not seen GPSD start it by itself.
Maybe it does for USB-devices, as it can autostart those, but not for RS-232 connected.