Dear devel,

On Tuesday, 7 March 2023 15:26:48 CET, I wrote:

> I therefore suggest to change the edge-detection to use the pulse-width:
> Unless pulsewidth=NS_PER_SEC/2, from the time-interval relative to the
> previous event the edge can be determined uniquely, making involvement
> of the system time into acquiring a lock of the PHC unnecessary,
> completely avoid locking on the wrong edge and increase the capturing range.

Now, that the edge detection is independent of the system time, there is still
a problem with the 'generic' driver, as the TOD we lock to is still determined 
by CLOCK_REALTIME.

The appended patch creates an alternative to "generic" named "extpps" that 
strictly makes a phc follow the 1pps pulses, independent of the system time. 

As a nice side-effect this eliminates completely the need for offsets, 
leap-second tables, etc. within ts2phc and restricts it more precisely 
to what it claims to do: "Synchronizes one or more PTP Hardware Clocks 
using external time stamps."

After the user has set the PHC approximately to the intended time and offset:
phc_ctl /dev/ptp3 -- set adjust $(grep -v '^#' 
/usr/share/zoneinfo/leap-seconds.list | tail -1 | awk '{ print $2 }')
ts2phc will keep the phc locked, no matter what happens to the system time.
This allows locking different PHCs to different time domains, 
even if those clocks drift more than a second away.

Using separate 1PPs inputs I now can make different PHCs lock 
simultaneously to '1PPs' pulses with periods 1010 ms and 1020 ms and when using 
a stable 1PPs.

I noticed that the servo.c -code has a SERVO_LOCKED_STABLE state that is not 
used. 
Are there any plans with that? Lock-detection in combination with with sd_noify 
(https://www.freedesktop.org/software/systemd/man/sd_notify.html) would sound 
very useful to me.

Cheers, Jürgen

> =======================================
diff --git a/makefile b/makefile
index 3e3b8b3..5192a0f 100644
--- a/makefile
+++ b/makefile
@@ -26,8 +26,9 @@ PRG   = ptp4l hwstamp_ctl nsm phc2sys phc_ctl pmc timemaster 
ts2phc tz2alt
 FILTERS        = filter.o mave.o mmedian.o
 SERVOS = linreg.o ntpshm.o nullf.o pi.o refclock_sock.o servo.o
 TRANSP = raw.o transport.o udp.o udp6.o uds.o
-TS2PHC = ts2phc.o lstab.o nmea.o serial.o sock.o ts2phc_generic_pps_source.o \
- ts2phc_nmea_pps_source.o ts2phc_phc_pps_source.o ts2phc_pps_sink.o 
ts2phc_pps_source.o
+TS2PHC = ts2phc.o lstab.o nmea.o serial.o sock.o  ts2phc_extpps_pps_source.o \
+ ts2phc_generic_pps_source.o ts2phc_nmea_pps_source.o ts2phc_phc_pps_source.o \
+ ts2phc_pps_sink.o ts2phc_pps_source.o
 OBJ    = bmc.o clock.o clockadj.o clockcheck.o config.o designated_fsm.o \
  e2e_tc.o fault.o $(FILTERS) fsm.o hash.o interface.o monitor.o msg.o phc.o \
  port.o port_signaling.o pqueue.o print.o ptp4l.o p2p_tc.o rtnl.o $(SERVOS) \
diff --git a/ts2phc.c b/ts2phc.c
index 4393059..6a8cad9 100644
--- a/ts2phc.c
+++ b/ts2phc.c
@@ -467,7 +467,14 @@ static void ts2phc_synchronize_clocks(struct 
ts2phc_private *priv, int autocfg)
                        continue;
                }
 
-               offset = tmv_to_nanoseconds(tmv_sub(ts, source_tmv));
+               if (source_tmv.ns)
+                 offset = tmv_to_nanoseconds(tmv_sub(ts, source_tmv));
+               else {
+                 /* no source timestamp => lock ts.ns to nearest whole second 
*/
+                 offset = tmv_to_nanoseconds(ts) % NS_PER_SEC;
+                 if (offset > NS_PER_SEC/2)
+                   offset -= NS_PER_SEC;
+               };
 
                if (c->no_adj) {
                        pr_info("%s offset %10" PRId64, c->name,
@@ -547,7 +554,10 @@ static void usage(char *progname)
                " -q             do not print messages to the syslog\n"
                " -s [dev|name]  source of the PPS signal\n"
                "                may take any of the following forms:\n"
-               "                    generic   - an external 1-PPS without ToD 
information\n"
+               "                    generic   - an external 1-PPS without ToD 
information,\n"
+               "                                ToD information taken from 
CLOCK_REALTIME\n"
+               "                    extpps    - an external 1-PPS without ToD 
information,\n"
+               "                                lock PHCs towards nearest 
whole second."
                "                    /dev/ptp0 - a local PTP Hardware Clock 
(PHC)\n"
                "                    eth0      - a local PTP Hardware Clock 
(PHC)\n"
                "                    nmea      - a gps device connected by 
serial port or network\n"
@@ -731,6 +741,8 @@ int main(int argc, char *argv[])
 
        if (!strcasecmp(tod_source, "generic")) {
                pps_type = TS2PHC_PPS_SOURCE_GENERIC;
+       } else if (!strcasecmp(tod_source, "extpps")) {
+               pps_type = TS2PHC_PPS_SOURCE_EXTPPS;
        } else if (!strcasecmp(tod_source, "nmea")) {
                pps_type = TS2PHC_PPS_SOURCE_NMEA;
        } else {
diff --git a/ts2phc_extpps_pps_source.c b/ts2phc_extpps_pps_source.c
new file mode 100644
index 0000000..4e1f26d
--- /dev/null
+++ b/ts2phc_extpps_pps_source.c
@@ -0,0 +1,51 @@
+/**
+ * @file ts2phc_extpps_pps_source.c
+ * @note Copyright (C) 2019 Richard Cochran <richardcoch...@gmail.com>
+ * @note SPDX-License-Identifier: GPL-2.0+
+ */
+#include <stdlib.h>
+#include <time.h>
+
+#include "ts2phc_extpps_pps_source.h"
+#include "ts2phc_pps_source_private.h"
+
+struct ts2phc_extpps_pps_source {
+       struct ts2phc_pps_source pps_source;
+};
+
+static void ts2phc_extpps_pps_source_destroy(struct ts2phc_pps_source *src)
+{
+       struct ts2phc_extpps_pps_source *s =
+               container_of(src, struct ts2phc_extpps_pps_source, pps_source);
+
+       free(s);
+}
+
+static int ts2phc_extpps_pps_source_getppstime(struct ts2phc_pps_source *src,
+                                           struct timespec *ts)
+{
+       ts->tv_sec = 0;
+       ts->tv_nsec = 0;
+       return 0;
+}
+
+struct ts2phc_clock *ts2phc_extpps_pps_source_get_clock(struct 
ts2phc_pps_source *src)
+{
+       return NULL;
+}
+
+
+struct ts2phc_pps_source *ts2phc_extpps_pps_source_create(struct 
ts2phc_private *priv,
+                                                          const char *dev)
+{
+       struct ts2phc_extpps_pps_source *s;
+
+       s = calloc(1, sizeof(*s));
+       if (!s) {
+               return NULL;
+       }
+       s->pps_source.destroy = ts2phc_extpps_pps_source_destroy;
+       s->pps_source.getppstime = ts2phc_extpps_pps_source_getppstime;
+
+       return &s->pps_source;
+}
diff --git a/ts2phc_extpps_pps_source.h b/ts2phc_extpps_pps_source.h
new file mode 100644
index 0000000..1a57cd6
--- /dev/null
+++ b/ts2phc_extpps_pps_source.h
@@ -0,0 +1,15 @@
+/**
+ * @file ts2phc_extpps_pps_source.h
+ * @note Copyright (C) 2019 Richard Cochran <richardcoch...@gmail.com>
+ * @note SPDX-License-Identifier: GPL-2.0+
+ */
+#ifndef HAVE_TS2PHC_EXTPPS_PPS_SOURCE_H
+#define HAVE_TS2PHC_EXTPPS_PPS_SOURCE_H
+
+#include "ts2phc.h"
+#include "ts2phc_pps_source.h"
+
+struct ts2phc_pps_source *ts2phc_extpps_pps_source_create(struct 
ts2phc_private *priv,
+                                                         const char *dev);
+
+#endif
diff --git a/ts2phc_pps_source.c b/ts2phc_pps_source.c
index c333f65..be98567 100644
--- a/ts2phc_pps_source.c
+++ b/ts2phc_pps_source.c
@@ -5,6 +5,7 @@
  */
 #include "ts2phc.h"
 #include "ts2phc_generic_pps_source.h"
+#include "ts2phc_extpps_pps_source.h"
 #include "ts2phc_nmea_pps_source.h"
 #include "ts2phc_phc_pps_source.h"
 #include "ts2phc_pps_source_private.h"
@@ -19,6 +20,9 @@ struct ts2phc_pps_source *ts2phc_pps_source_create(struct 
ts2phc_private *priv,
        case TS2PHC_PPS_SOURCE_GENERIC:
                src = ts2phc_generic_pps_source_create(priv, dev);
                break;
+       case TS2PHC_PPS_SOURCE_EXTPPS:
+               src = ts2phc_extpps_pps_source_create(priv, dev);
+               break;
        case TS2PHC_PPS_SOURCE_NMEA:
                src = ts2phc_nmea_pps_source_create(priv, dev);
                break;
diff --git a/ts2phc_pps_source.h b/ts2phc_pps_source.h
index 293c693..519fc02 100644
--- a/ts2phc_pps_source.h
+++ b/ts2phc_pps_source.h
@@ -21,6 +21,7 @@ struct ts2phc_pps_source;
  */
 enum ts2phc_pps_source_type {
        TS2PHC_PPS_SOURCE_GENERIC,
+       TS2PHC_PPS_SOURCE_EXTPPS,
        TS2PHC_PPS_SOURCE_NMEA,
        TS2PHC_PPS_SOURCE_PHC,
 };
> =======================================


_______________________________________________
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel

Reply via email to