Discussion:
[Linuxptp-devel] [PATCH RFC v2 0/2] Servo for use with SyncE
Richard Cochran
2015-07-24 20:35:08 UTC
Permalink
These patches add a new servo type that keep the frequency adjustment
always zero. This is useful in a Synchronous Ethernet network, where
a slave clock will use this servo together with 'freq_noadj 1' and
'step_threshold 0.000000001' in the configuration.


Richard Cochran (2):
Add a servo that inhibits all frequency adjustment
Add a configuration option to use the "nullf" servo.

config.c | 2 ++
makefile | 6 ++---
nullf.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
nullf.h | 26 +++++++++++++++++++++
ptp4l.8 | 12 ++++++----
servo.c | 4 ++++
servo.h | 1 +
7 files changed, 122 insertions(+), 8 deletions(-)
create mode 100644 nullf.c
create mode 100644 nullf.h
--
2.1.4


------------------------------------------------------------------------------
Richard Cochran
2015-07-24 20:35:09 UTC
Permalink
When running with Synchronous Ethernet (SyncE), the correct clock
frequency is provided by the link partner. In this case, only the
offset needs correcting.

This patch provides SyncE nodes with an way to keep the frequency
correction dialed to zero.

Signed-off-by: Richard Cochran <***@gmail.com>
---
makefile | 6 ++---
nullf.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
nullf.h | 26 +++++++++++++++++++++
servo.c | 4 ++++
servo.h | 1 +
5 files changed, 113 insertions(+), 3 deletions(-)
create mode 100644 nullf.c
create mode 100644 nullf.h

diff --git a/makefile b/makefile
index 0f22b16..a8e5ce8 100644
--- a/makefile
+++ b/makefile
@@ -24,7 +24,7 @@ CFLAGS = -Wall $(VER) $(incdefs) $(DEBUG) $(EXTRA_CFLAGS)
LDLIBS = -lm -lrt $(EXTRA_LDFLAGS)
PRG = ptp4l pmc phc2sys hwstamp_ctl phc_ctl timemaster
OBJ = bmc.o clock.o clockadj.o clockcheck.o config.o fault.o \
- filter.o fsm.o linreg.o mave.o mmedian.o msg.o ntpshm.o phc.o \
+ filter.o fsm.o linreg.o mave.o mmedian.o msg.o ntpshm.o nullf.o phc.o \
pi.o port.o print.o ptp4l.o raw.o servo.o sk.o stats.o tlv.o \
transport.o tsproc.o udp.o udp6.o uds.o util.o version.o

@@ -49,8 +49,8 @@ ptp4l: $(OBJ)
pmc: msg.o pmc.o pmc_common.o print.o raw.o sk.o tlv.o transport.o udp.o \
udp6.o uds.o util.o version.o

-phc2sys: clockadj.o clockcheck.o linreg.o msg.o ntpshm.o phc.o phc2sys.o pi.o \
- pmc_common.o print.o raw.o servo.o sk.o stats.o sysoff.o tlv.o \
+phc2sys: clockadj.o clockcheck.o linreg.o msg.o ntpshm.o nullf.o phc.o \
+ phc2sys.o pi.o pmc_common.o print.o raw.o servo.o sk.o stats.o sysoff.o tlv.o \
transport.o udp.o udp6.o uds.o util.o version.o

hwstamp_ctl: hwstamp_ctl.o version.o
diff --git a/nullf.c b/nullf.c
new file mode 100644
index 0000000..5512837
--- /dev/null
+++ b/nullf.c
@@ -0,0 +1,79 @@
+/**
+ * @file nullf.c
+ * @brief Implements a clock servo that always set the frequency offset to zero.
+ * @note Copyright (C) 2015 Richard Cochran <***@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#include <stdlib.h>
+#include <math.h>
+
+#include "nullf.h"
+#include "print.h"
+#include "servo_private.h"
+
+struct nullf_servo {
+ struct servo servo;
+};
+
+static void nullf_destroy(struct servo *servo)
+{
+ struct nullf_servo *s = container_of(servo, struct nullf_servo, servo);
+ free(s);
+}
+
+static double nullf_sample(struct servo *servo, int64_t offset,
+ uint64_t local_ts, double weight,
+ enum servo_state *state)
+{
+ if (!offset) {
+ *state = SERVO_LOCKED;
+ return 0.0;
+ }
+
+ if ((servo->first_update && servo->first_step_threshold &&
+ servo->first_step_threshold < fabs(offset)) ||
+ (servo->step_threshold && servo->step_threshold < fabs(offset))) {
+ *state = SERVO_JUMP;
+ } else {
+ *state = SERVO_UNLOCKED;
+ }
+
+ return 0.0;
+}
+
+static void nullf_sync_interval(struct servo *servo, double interval)
+{
+}
+
+static void nullf_reset(struct servo *servo)
+{
+}
+
+struct servo *nullf_servo_create(void)
+{
+ struct nullf_servo *s;
+
+ s = calloc(1, sizeof(*s));
+ if (!s)
+ return NULL;
+
+ s->servo.destroy = nullf_destroy;
+ s->servo.sample = nullf_sample;
+ s->servo.sync_interval = nullf_sync_interval;
+ s->servo.reset = nullf_reset;
+
+ return &s->servo;
+}
diff --git a/nullf.h b/nullf.h
new file mode 100644
index 0000000..9e8bc7b
--- /dev/null
+++ b/nullf.h
@@ -0,0 +1,26 @@
+/**
+ * @file nullf.h
+ * @note Copyright (C) 2015 Richard Cochran <***@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef HAVE_NULLF_H
+#define HAVE_NULLF_H
+
+#include "servo.h"
+
+struct servo *nullf_servo_create(void);
+
+#endif
diff --git a/servo.c b/servo.c
index 2739ebd..b936a85 100644
--- a/servo.c
+++ b/servo.c
@@ -20,6 +20,7 @@

#include "linreg.h"
#include "ntpshm.h"
+#include "nullf.h"
#include "pi.h"
#include "servo_private.h"

@@ -43,6 +44,9 @@ struct servo *servo_create(enum servo_type type, int fadj, int max_ppb, int sw_t
case CLOCK_SERVO_NTPSHM:
servo = ntpshm_servo_create();
break;
+ case CLOCK_SERVO_NULLF:
+ servo = nullf_servo_create();
+ break;
default:
return NULL;
}
diff --git a/servo.h b/servo.h
index 4be8c23..0a182a4 100644
--- a/servo.h
+++ b/servo.h
@@ -56,6 +56,7 @@ enum servo_type {
CLOCK_SERVO_PI,
CLOCK_SERVO_LINREG,
CLOCK_SERVO_NTPSHM,
+ CLOCK_SERVO_NULLF,
};

/**
--
2.1.4


------------------------------------------------------------------------------
Richard Cochran
2015-07-24 20:35:10 UTC
Permalink
Signed-off-by: Richard Cochran <***@gmail.com>
---
config.c | 2 ++
ptp4l.8 | 12 +++++++-----
2 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/config.c b/config.c
index ee0f302..934caa2 100644
--- a/config.c
+++ b/config.c
@@ -534,6 +534,8 @@ static enum parser_result parse_global_setting(const char *option,
cfg->clock_servo = CLOCK_SERVO_LINREG;
else if (!strcasecmp("ntpshm", value))
cfg->clock_servo = CLOCK_SERVO_NTPSHM;
+ else if (!strcasecmp("nullf", value))
+ cfg->clock_servo = CLOCK_SERVO_NULLF;
else
return BAD_VALUE;

diff --git a/ptp4l.8 b/ptp4l.8
index caeb805..0bdccb1 100644
--- a/ptp4l.8
+++ b/ptp4l.8
@@ -318,11 +318,13 @@ generated by the master.
The default is 0 (disabled).
.TP
.B clock_servo
-The servo which is used to synchronize the local clock. Valid values are pi for
-a PI controller, linreg for an adaptive controller using linear regression, and
-ntpshm for the NTP SHM reference clock to allow another process to synchronize
-the local clock (the SHM segment number is set to the domain number).
-The default is pi.
+The servo which is used to synchronize the local clock. Valid values
+are "pi" for a PI controller, "linreg" for an adaptive controller
+using linear regression, "ntpshm" for the NTP SHM reference clock to
+allow another process to synchronize the local clock (the SHM segment
+number is set to the domain number), and "nullf" for a servo that
+always dials frequency offset zero (for use in SyncE nodes).
+The default is "pi."
.TP
.B pi_proportional_const
The proportional constant of the PI controller. When set to 0.0, the
--
2.1.4


------------------------------------------------------------------------------
Richard Cochran
2015-07-24 20:38:59 UTC
Permalink
Post by Richard Cochran
These patches add a new servo type that keep the frequency adjustment
always zero. This is useful in a Synchronous Ethernet network, where
a slave clock will use this servo together with 'freq_noadj 1' and
^^^^^^^^^^^^
Oops, that text is stale.

Let's try it again:

These patches add a new servo type that keep the frequency
adjustment always zero. This is useful in a Synchronous Ethernet
network, where a slave clock will use this servo together with
'step_threshold 0.000000001' in the configuration.

Thanks,
Richard


------------------------------------------------------------------------------
Miroslav Lichvar
2015-07-27 09:24:41 UTC
Permalink
Post by Richard Cochran
These patches add a new servo type that keep the frequency adjustment
always zero. This is useful in a Synchronous Ethernet network, where
a slave clock will use this servo together with 'freq_noadj 1' and
'step_threshold 0.000000001' in the configuration.
Add a servo that inhibits all frequency adjustment
Add a configuration option to use the "nullf" servo.
Looks good to me. I don't have a SyncE capable HW, so I changed the
locking condition to allow a small offset and it worked as expected.

Thanks,
--
Miroslav Lichvar

------------------------------------------------------------------------------
Loading...