Signed-off-by: Jürgen Appel <[email protected]>
---
1pps2phc.service | 42 ++++++++++++++++++++++++++++++++++++++++++
config.c | 1 +
servo.c | 4 ++++
ts2phc.c | 45 ++++++++++++++++++++++++++++++++++++++++++++-
ts2phc.h | 2 ++
5 files changed, 93 insertions(+), 1 deletion(-)
create mode 100644 1pps2phc.service
diff --git a/1pps2phc.service b/1pps2phc.service
new file mode 100644
index 0000000..00e5fda
--- /dev/null
+++ b/1pps2phc.service
@@ -0,0 +1,42 @@
+[Unit]
+
+# This example unit file shows how to configure a systemd-service that keeps
+# ptp3 locked to an external 100ms-hardware-1PPS pulse connected to ptp3.SDP0
+
+Description=Lock phc3 to 1pps
+
+After=network.target
+
+# This service roughly sets the PHC clock to within 1 s of the intended
offset
+After=initializePHC.service
+
+# Optional: As soon as we are locked, we want to use chrony to use /dev/ptp3
as time source
+# Add the line "BindsTo=1pps2phc.service" to the [Unit] section in
+# chrony's chrony.service configuration, and you are guaranteed that
+# chrony is only running as long as your PHC is actually locked and is
restarted when lock is lost.
+#Wants=chrony.service
+
+[Service]
+Type=forking
+PIDFile=/run/ts2phc_1pps%i.pid
+
+# We start up ts2phc and give the process up to 3 minutes to lock to within
100 ns
+TimeoutStartSec=180
+ExecStart=/usr/local/sbin/ts2phc -l 5 -c eth3 -s extpps \
+ --ts2phc.extts_correction=-35 \
+ --ts2phc.pin_index=0 \
+ --ts2phc.channel=0 \
+ --ts2phc.extts_polarity=both \
+ --ts2phc.pulsewidth=100000000 \
+ --message_tag=1pps \
+ --servo_offset_threshold=100 \
+ --systemd_pidfile=/run/ts2phc_1pps%i.pid
+
+Restart=on-failure
+
+# Optional: Enable an external Hardware-1PPS-output on ptp3.SDP1 as long as
the lock is stable
+ExecStartPost=/usr/local/sbin/testptp -d /dev/ptp3 -i 0 -L 1,2 -p 1000000000
+ExecStopPost=/usr/local/sbin/testptp -d /dev/ptp3 -i 0 -L 1,0
+
+[Install]
+WantedBy=multi-user.target
diff --git a/config.c b/config.c
index cb4421f..76a1056 100644
--- a/config.c
+++ b/config.c
@@ -329,6 +329,7 @@ struct config_item config_tab[] = {
GLOB_ITEM_INT("socket_priority", 0, 0, 15),
GLOB_ITEM_DBL("step_threshold", 0.0, 0.0, DBL_MAX),
GLOB_ITEM_INT("step_window", 0, 0, INT_MAX),
+ GLOB_ITEM_STR("systemd_pidfile", NULL),
GLOB_ITEM_INT("summary_interval", 0, INT_MIN, INT_MAX),
PORT_ITEM_INT("syncReceiptTimeout", 0, 0, UINT8_MAX),
GLOB_ITEM_INT("tc_spanning_tree", 0, 0, 1),
diff --git a/servo.c b/servo.c
index ea171cd..85fe665 100644
--- a/servo.c
+++ b/servo.c
@@ -107,6 +107,10 @@ static int check_offset_threshold(struct servo *s,
int64_t offset)
if (s->curr_offset_values)
s->curr_offset_values--;
} else {
+ if (! s->curr_offset_values) {
+ // lock became unstable after
having been stable
+ pr_info("servo got unlocked");
+ }
s->curr_offset_values = s->num_offset_values;
}
return s->curr_offset_values ? 0 : 1;
diff --git a/ts2phc.c b/ts2phc.c
index 6a8cad9..13bf474 100644
--- a/ts2phc.c
+++ b/ts2phc.c
@@ -436,6 +436,9 @@ static void ts2phc_synchronize_clocks(struct
ts2phc_private *priv, int autocfg)
struct ts2phc_clock *c;
int valid, err;
+ pid_t pid;
+ FILE *pid_file;
+
if (autocfg) {
if (!priv->ref_clock) {
pr_debug("no reference clock, skipping");
@@ -499,8 +502,45 @@ static void ts2phc_synchronize_clocks(struct
ts2phc_private *priv, int autocfg)
goto servo_unlock;
}
break;
- case SERVO_LOCKED:
case SERVO_LOCKED_STABLE:
+ if (priv->pidfile && !priv->is_forked) {
+ priv->is_forked = true;
+ pid = fork();
+ switch (pid) {
+ case -1:
+ pr_crit("fork failed");
+ exit(EXIT_FAILURE);
+ case 0: /* child */
+ chdir("/");
+ close(0);
+ fopen("/dev/null",
"r+");
+ dup2(0,1);
+ dup2(0,2);
+ setsid();
+ break;
+ pr_info("forked &
detached (pid=%d)",
+ pid);
+ pid_file = fopen(priv-
>pidfile, "w");
+ if (!pid_file) {
+
pr_err("cannot create pidfile");
+
_exit(EXIT_FAILURE);
+ } else {
+
fprintf(pid_file,"%d\n", pid);
+
fclose(pid_file);
+
_exit(EXIT_SUCCESS);
+ }
+ if (clockadj_set_freq(c->clkid, -adj)) {
+ goto servo_unlock;
+ }
+ case SERVO_LOCKED:
+ if (priv->is_forked) {
+ // servo has relocked
+ exit(EXIT_FAILURE);
+ }
if (clockadj_set_freq(c->clkid, -adj)) {
goto servo_unlock;
}
@@ -670,6 +710,9 @@ int main(int argc, char *argv[])
print_set_syslog(config_get_int(cfg, NULL, "use_syslog"));
print_set_level(config_get_int(cfg, NULL, "logging_level"));
+ priv.pidfile = config_get_string(cfg, NULL, "systemd_pidfile");
+ priv.is_forked = false;
+
STAILQ_INIT(&priv.sinks);
priv.cfg = cfg;
diff --git a/ts2phc.h b/ts2phc.h
index 4833ded..6529f34 100644
--- a/ts2phc.h
+++ b/ts2phc.h
@@ -55,6 +55,8 @@ struct ts2phc_private {
bool state_changed;
LIST_HEAD(port_head, ts2phc_port) ports;
LIST_HEAD(clock_head, ts2phc_clock) clocks;
+ char *pidfile;
+ bool is_forked;
};
struct ts2phc_clock *ts2phc_clock_add(struct ts2phc_private *priv,
--
_______________________________________________
Linuxptp-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel