Re: SatPulse: server-oriented alternative to gpsd for chrony

James Clark <[email protected]> Thu, 23 Apr 2026 14:46:22 +0700
Newsgroups gmane.comp.time.chrony.user
Message-ID <CANz3_EZBqCMC4pMfERY7qmT-fT=ZcmEWC584j3+iX=c3XetRGA@mail.gmail.com>
--000000000000e37cf806501bd8ac
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

On Mon, Apr 20, 2026 at 9:30=E2=80=AFPM Miroslav Lichvar <[email protected]=
om>
wrote:

> > If a PHC is available, the current SatPulse refclock handles this and
> > provides sawtooth-corrected samples to chrony.  So the question is what
> > could be the advantages of an alternative approach.
>
> But the SOCK samples are based on the system clock?


Yes.


> In a test with a
> config that has both "phc" and "ntp" sections, the offset seems to be
> moving when I step either of the PHC or the system clock. It's not
> clear to me what is going on there.


Here is how things currently work. In satpulsed's normal mode of operation,
it aims to keep the PHC in sync with the GPS. It expects to be the only
process adjusting the PHC (it should detect and report if anything else is
changing the PHC, but it doesn't do that yet). It monitors the
synchronization status and switches between different modes, which
determine the clock quality that satpulsed reported to ptp4l; the main mode
is  "tracking", which is used when the PHC is in sync with the GPS.
Immediately after reading each PHC timestamp, it uses
PTP_SYS_OFFSET_EXTENDED/PRECISE ioctl to get a cross-sample. When in
tracking mode, it generates a chrony sample from the cross-sample, assuming
the PHC value in the cross-sample provides the true time.


> I'd expect it to be independent
> from the system clock. There is also an issue that satpulsed is still
> controlling the clock. Could there be a new option to disable that in
> order for chronyd to synchronize it?
>

Yes! For the last few days, I have been implementing a new mode of
operation that does not synchronize the PHC. The samples sent to chrony are
generated from cross-samples, as in the current syncing mode.  It uses GPS
messages to associate PHC timestamps with their true times and apply
sawtooth corrections to timestamps. It then fits a local linear
PHC-to-true-time mapping and evaluates it at the PHC value from the
cross-sample.

It is configured just by putting `sync=3Dfalse` in the `[phc]` section;
there's also a new `[sample.phc]` that can configure various parameters of
the sample generation algorithm. This is on the phc-sample branch, if you
want to try it.

I think this will work a little bit better than the syncing approach when
the you don't need the PHC to be synchronized:
- it is less stateful, and lets chrony do more of the work
- it starts up much quicker (about 5s vs 30s)
- avoids any possible conflict with chrony hardware timestamping

It preserves most features of the syncing mode:
- handles Intel dual-edge timestamping automatically
- handles all the CM4/CM5 quirks
- applies sawtooth corrections

Like the syncing mode, it requires 1PPS.

I have put in code to detect and handle PHC discontinuities, so I think it
should also work with chrony disciplining the PHC, but my feeling is that
this approach is not ideal for that, and another refclock which works along
the lines you suggested here would work better:

> > I think tv should be the timestamp from the extts event (if using a
> > PHC) or pps assert/clear provided by the kernel (rounded to
> > microseconds). Offset should be the difference to the top of the
> > second indicated by the serial message and the sawtooth correction.

One question here: for the purpose of determining the difference, should
the PHC be treated as being in TAI or UTC?
On the SatPulse side, I would imagine this being a separate path enabled by
putting something like `clock=3D"phc"` in the`[ntp]` section. I think it
could be implemented reusing some of the code from the mode I just added.

P.S. it seems satpulsed doesn't currently work with /dev/gnss devices
> (e.g. provided by some Intel NIC drivers). I'm getting this error:
>
> ioctl(TCGETS) /dev/gnss0: inappropriate ioctl for device
>
> The serial-specific ioctls need to be disabled in this case or their
> errors ignored.
>

Thanks. I have put in a fix for this on master (and phc-sample), but it's a
bit more complicated than just not doing the serial-specific ioctls: I have
to switch over to using poll for timeouts rather the the VMIN/VTIME serial
timeouts. I think Go's netpoller will work with /dev/gnss*, but I am not
100% sure. So it would be great if you could try it out.

James

--000000000000e37cf806501bd8ac
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div dir=3D"ltr"><div dir=3D"ltr"><div dir=3D"ltr">On Mon,=
 Apr 20, 2026 at 9:30=E2=80=AFPM Miroslav Lichvar &lt;<a href=3D"mailto:mli=
[email protected]" target=3D"_blank">[email protected]</a>&gt; wrote:</div=
><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"marg=
in:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1e=
x">
&gt; If a PHC is available, the current SatPulse refclock handles this and<=
br>
&gt; provides sawtooth-corrected samples to chrony.=C2=A0 So the question i=
s what<br>
&gt; could be the advantages of an alternative approach.<br>
<br>
But the SOCK samples are based on the system clock?</blockquote><div><br></=
div><div>Yes.</div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=
=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding=
-left:1ex"> In a test with a<br>
config that has both &quot;phc&quot; and &quot;ntp&quot; sections, the offs=
et seems to be<br>
moving when I step either of the PHC or the system clock. It&#39;s not<br>
clear to me what is going on there.</blockquote><div><br></div><div>Here is=
 how things currently work. In satpulsed&#39;s normal mode of operation, it=
 aims to keep the PHC in sync with the GPS. It expects to be the only proce=
ss adjusting the PHC (it should detect and report if anything else is chang=
ing the PHC, but it doesn&#39;t do that yet). It monitors the synchronizati=
on status and switches between different modes, which determine the clock q=
uality that satpulsed reported to ptp4l; the main mode is=C2=A0 &quot;track=
ing&quot;, which is=C2=A0used when the PHC is in sync with the GPS. Immedia=
tely after reading each PHC timestamp, it uses PTP_SYS_OFFSET_EXTENDED/PREC=
ISE ioctl to get a cross-sample. When in tracking mode, it generates a chro=
ny sample from the cross-sample, assuming the PHC value in the cross-sample=
 provides the true time.</div><div>=C2=A0</div><blockquote class=3D"gmail_q=
uote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,2=
04);padding-left:1ex"> I&#39;d expect it to be independent<br>
from the system clock. There is also an issue that satpulsed is still<br>
controlling the clock. Could there be a new option to disable that in<br>
order for chronyd to synchronize it?<br></blockquote><div><br></div><div>Ye=
s!=C2=A0For the last few days, I have been implementing a new mode of opera=
tion that does not synchronize the PHC. The samples sent to chrony are gene=
rated from cross-samples, as in the current syncing mode.=C2=A0 It uses GPS=
 messages to associate PHC timestamps with their true times and apply sawto=
oth corrections to timestamps. It then fits a local linear PHC-to-true-time=
 mapping and evaluates it at the PHC value from the cross-sample.</div><div=
><br></div><div>It is configured just by putting `sync=3Dfalse` in the `[ph=
c]` section; there&#39;s also a new `[sample.phc]` that can configure vario=
us parameters of the sample generation algorithm. This is on the phc-sample=
 branch, if you want to try it.</div><div><br></div><div>I think this will =
work a little bit better than the syncing approach when the you don&#39;t n=
eed the PHC to be synchronized:</div><div>- it is less stateful, and lets c=
hrony do more of the work</div><div>- it starts up much quicker (about 5s v=
s 30s)</div><div>- avoids any possible conflict with chrony hardware timest=
amping</div><div><br></div><div>It preserves most features of the syncing m=
ode:</div><div>- handles Intel dual-edge timestamping automatically</div><d=
iv>- handles all the CM4/CM5 quirks</div><div>- applies sawtooth correction=
s</div><div><br></div><div>Like the syncing mode, it requires 1PPS.</div><d=
iv><br></div><div>I have put in code to detect and handle PHC discontinuiti=
es, so I think it should also work with chrony disciplining the PHC, but=C2=
=A0my feeling is that this approach is not ideal for that, and another refc=
lock=C2=A0which works along the lines you suggested here would work better:=
</div><div><br></div><div>&gt; &gt; I think tv should be the timestamp from=
 the extts event (if using a<br>&gt; &gt; PHC) or pps assert/clear provided=
 by the kernel (rounded to<br>&gt; &gt; microseconds). Offset should be the=
 difference to the top of the<br>&gt; &gt; second indicated by the serial m=
essage and the sawtooth correction.</div><div><br></div><div>One question h=
ere: for the purpose of determining the difference, should the PHC be treat=
ed as being in TAI or UTC?</div><div>On the SatPulse side, I would imagine =
this being a separate path enabled by putting something like `clock=3D&quot=
;phc&quot;` in the`[ntp]` section. I think it could be implemented reusing =
some of the code from the mode I just added.</div><div><br></div><blockquot=
e class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px s=
olid rgb(204,204,204);padding-left:1ex">
P.S. it seems satpulsed doesn&#39;t currently work with /dev/gnss devices<b=
r>
(e.g. provided by some Intel NIC drivers). I&#39;m getting this error:<br>
<br>
ioctl(TCGETS) /dev/gnss0: inappropriate ioctl for device<br>
<br>
The serial-specific ioctls need to be disabled in this case or their<br>
errors ignored.<br></blockquote><div><br></div><div>Thanks. I have put in a=
 fix for this on master (and phc-sample), but it&#39;s a bit more complicat=
ed than just not doing the serial-specific ioctls: I have to switch over to=
 using poll for timeouts rather the the VMIN/VTIME serial timeouts. I think=
 Go&#39;s netpoller will work with /dev/gnss*, but I am not 100% sure. So i=
t would be great if you could try it out.</div><div><br></div><div>James</d=
iv></div></div>
</div>
</div>

--000000000000e37cf806501bd8ac--

-- 
To unsubscribe email chrony-users-request-kWFZVVI9zxvPqho9SqqRMmD2FQJk+8+b@public.gmane.org 
with "unsubscribe" in the subject.
For help email chrony-users-request-kWFZVVI9zxvPqho9SqqRMmD2FQJk+8+b@public.gmane.org 
with "help" in the subject.
Trouble?  Email [email protected]