Ken ICHIKAWA
2013-06-20 04:30:15 UTC
Current pi servo steps clock without any condition on start.
This patch adds a new servo option "configured_pi_f_offset". The option is similar
to configured_pi_offset but only affects in the first clock update. Therefore,
if this option is set as 0.0, we can prevent clock step on start.
The new servo option can be specified from phc2sys by using -F option.
This feature is usefull when we need to restart phc2sys without system
clock jump. Restarting phc2sys is needed to change its configuration.
changes since v2:
- manual page fix.
- also apply max_offset along with max_f_offset in servo step1.
- add a variable to check if first update is done.
changes since v1:(http://sourceforge.net/mailarchive/message.php?msg_id=31039874)
- remake as a new servo option.
Signed-off-by: Ken ICHIKAWA <***@jp.fujitsu.com>
---
phc2sys.8 | 16 ++++++++++++++--
phc2sys.c | 8 +++++++-
pi.c | 19 ++++++++++++++++++-
pi.h | 11 ++++++++++-
4 files changed, 49 insertions(+), 5 deletions(-)
diff --git a/phc2sys.8 b/phc2sys.8
index 8e03e81..d7a4569 100644
--- a/phc2sys.8
+++ b/phc2sys.8
@@ -19,6 +19,10 @@ phc2sys \- synchronize two clocks
] [
.BI \-I " ki"
] [
+.BI \-S " step"
+] [
+.BI \-F " step"
+] [
.BI \-R " update-rate"
] [
.BI \-N " clock-readings"
@@ -87,8 +91,16 @@ Specify the integral constant of the PI controller. The default is 0.3.
.BI \-S " step"
Specify the step threshold of the PI controller. It is the maximum offset that
the controller corrects by changing the clock frequency instead of stepping the
-clock. The clock is always stepped on start. The value of 0.0 disables stepping
-after the start. The default is 0.0.
+clock. The clock is stepped on start regardless of the option if the offset is
+larger than 100 nanoseconds (unless the
+.BI \-F
+option is used). The value of 0.0 disables stepping after the start. The default
+is 0.0.
+.TP
+.BI \-F " step"
+Specify the step threshold applied only on the first update. It is the maximum
+offset that is corrected by adjusting clock. The value of 0.0 disables stepping
+on start. The default is 0.0000001 (100 nanoseconds).
.TP
.BI \-R " update-rate"
Specify the slave clock update rate when running in the direct synchronization
diff --git a/phc2sys.c b/phc2sys.c
index 594fc1e..8f9e18b 100644
--- a/phc2sys.c
+++ b/phc2sys.c
@@ -555,6 +555,7 @@ static void usage(char *progname)
" -P [kp] proportional constant (0.7)\n"
" -I [ki] integration constant (0.3)\n"
" -S [step] step threshold (disabled)\n"
+ " -F [step] step threshold only on start (0.0000001)\n"
" -R [rate] slave clock update rate in HZ (1.0)\n"
" -N [num] number of master clock readings per update (5)\n"
" -O [offset] slave-master time offset (0)\n"
@@ -593,7 +594,7 @@ int main(int argc, char *argv[])
progname = strrchr(argv[0], '/');
progname = progname ? 1+progname : argv[0];
while (EOF != (c = getopt(argc, argv,
- "c:d:hs:P:I:S:R:N:O:i:u:wn:xl:mqv"))) {
+ "c:d:s:P:I:S:F:R:N:O:i:u:wn:xl:mqvh"))) {
switch (c) {
case 'c':
dst_clock.clkid = clock_open(optarg);
@@ -627,6 +628,11 @@ int main(int argc, char *argv[])
0.0, DBL_MAX))
return -1;
break;
+ case 'F':
+ if (get_arg_val_d(c, optarg, &configured_pi_f_offset,
+ 0.0, DBL_MAX))
+ return -1;
+ break;
case 'R':
if (get_arg_val_d(c, optarg, &phc_rate, 0.0, DBL_MAX))
return -1;
diff --git a/pi.c b/pi.c
index 78cbd3f..89080c4 100644
--- a/pi.c
+++ b/pi.c
@@ -35,6 +35,7 @@
double configured_pi_kp = 0.0;
double configured_pi_ki = 0.0;
double configured_pi_offset = 0.0;
+double configured_pi_f_offset = 0.0000001; /* 100 nanoseconds */
int configured_pi_max_freq = 900000000;
struct pi_servo {
@@ -46,7 +47,9 @@ struct pi_servo {
double kp;
double ki;
double max_offset;
+ double max_f_offset;
int count;
+ int first_update;
};
static void pi_destroy(struct servo *servo)
@@ -88,7 +91,14 @@ static double pi_sample(struct servo *servo,
else if (s->drift > s->maxppb)
s->drift = s->maxppb;
- *state = SERVO_JUMP;
+ if (!s->first_update ||
+ (s->max_f_offset && (s->max_f_offset < fabs(offset))) ||
+ (s->max_offset && (s->max_offset < fabs(offset))))
+ *state = SERVO_JUMP;
+ else
+ *state = SERVO_LOCKED;
+
+ s->first_update = 0;
ppb = s->drift;
s->count = 2;
break;
@@ -134,6 +144,7 @@ struct servo *pi_servo_create(int fadj, int max_ppb, int sw_ts)
s->servo.sample = pi_sample;
s->drift = fadj;
s->maxppb = max_ppb;
+ s->first_update = 1;
if (configured_pi_kp && configured_pi_ki) {
s->kp = configured_pi_kp;
@@ -152,6 +163,12 @@ struct servo *pi_servo_create(int fadj, int max_ppb, int sw_ts)
s->max_offset = 0.0;
}
+ if (configured_pi_f_offset > 0.0) {
+ s->max_f_offset = configured_pi_f_offset * NSEC_PER_SEC;
+ } else {
+ s->max_f_offset = 0.0;
+ }
+
if (configured_pi_max_freq && s->maxppb > configured_pi_max_freq) {
s->maxppb = configured_pi_max_freq;
}
diff --git a/pi.h b/pi.h
index 954f495..2f31bce 100644
--- a/pi.h
+++ b/pi.h
@@ -36,13 +36,22 @@ extern double configured_pi_ki;
/**
* When set to a non-zero value, this variable controls the maximum allowed
* offset before a clock jump occurs instead of the default clock-slewing
- * mechanism
+ * mechanism.
*
* Note that this variable is measured in seconds, and allows fractional values.
*/
extern double configured_pi_offset;
/**
+ * When set to zero, the clock is not stepped on start. When set to a non-zero
+ * value, the value bahaves as a threshold and the clock is stepped on start if
+ * the offset is bigger than the threshold.
+ *
+ * Note that this variable is measured in seconds, and allows fractional values.
+ */
+extern double configured_pi_f_offset;
+
+/**
* When set to a non-zero value, this variable sets an additional limit for
* the frequency adjustment of the clock. It's in ppb.
*/
This patch adds a new servo option "configured_pi_f_offset". The option is similar
to configured_pi_offset but only affects in the first clock update. Therefore,
if this option is set as 0.0, we can prevent clock step on start.
The new servo option can be specified from phc2sys by using -F option.
This feature is usefull when we need to restart phc2sys without system
clock jump. Restarting phc2sys is needed to change its configuration.
changes since v2:
- manual page fix.
- also apply max_offset along with max_f_offset in servo step1.
- add a variable to check if first update is done.
changes since v1:(http://sourceforge.net/mailarchive/message.php?msg_id=31039874)
- remake as a new servo option.
Signed-off-by: Ken ICHIKAWA <***@jp.fujitsu.com>
---
phc2sys.8 | 16 ++++++++++++++--
phc2sys.c | 8 +++++++-
pi.c | 19 ++++++++++++++++++-
pi.h | 11 ++++++++++-
4 files changed, 49 insertions(+), 5 deletions(-)
diff --git a/phc2sys.8 b/phc2sys.8
index 8e03e81..d7a4569 100644
--- a/phc2sys.8
+++ b/phc2sys.8
@@ -19,6 +19,10 @@ phc2sys \- synchronize two clocks
] [
.BI \-I " ki"
] [
+.BI \-S " step"
+] [
+.BI \-F " step"
+] [
.BI \-R " update-rate"
] [
.BI \-N " clock-readings"
@@ -87,8 +91,16 @@ Specify the integral constant of the PI controller. The default is 0.3.
.BI \-S " step"
Specify the step threshold of the PI controller. It is the maximum offset that
the controller corrects by changing the clock frequency instead of stepping the
-clock. The clock is always stepped on start. The value of 0.0 disables stepping
-after the start. The default is 0.0.
+clock. The clock is stepped on start regardless of the option if the offset is
+larger than 100 nanoseconds (unless the
+.BI \-F
+option is used). The value of 0.0 disables stepping after the start. The default
+is 0.0.
+.TP
+.BI \-F " step"
+Specify the step threshold applied only on the first update. It is the maximum
+offset that is corrected by adjusting clock. The value of 0.0 disables stepping
+on start. The default is 0.0000001 (100 nanoseconds).
.TP
.BI \-R " update-rate"
Specify the slave clock update rate when running in the direct synchronization
diff --git a/phc2sys.c b/phc2sys.c
index 594fc1e..8f9e18b 100644
--- a/phc2sys.c
+++ b/phc2sys.c
@@ -555,6 +555,7 @@ static void usage(char *progname)
" -P [kp] proportional constant (0.7)\n"
" -I [ki] integration constant (0.3)\n"
" -S [step] step threshold (disabled)\n"
+ " -F [step] step threshold only on start (0.0000001)\n"
" -R [rate] slave clock update rate in HZ (1.0)\n"
" -N [num] number of master clock readings per update (5)\n"
" -O [offset] slave-master time offset (0)\n"
@@ -593,7 +594,7 @@ int main(int argc, char *argv[])
progname = strrchr(argv[0], '/');
progname = progname ? 1+progname : argv[0];
while (EOF != (c = getopt(argc, argv,
- "c:d:hs:P:I:S:R:N:O:i:u:wn:xl:mqv"))) {
+ "c:d:s:P:I:S:F:R:N:O:i:u:wn:xl:mqvh"))) {
switch (c) {
case 'c':
dst_clock.clkid = clock_open(optarg);
@@ -627,6 +628,11 @@ int main(int argc, char *argv[])
0.0, DBL_MAX))
return -1;
break;
+ case 'F':
+ if (get_arg_val_d(c, optarg, &configured_pi_f_offset,
+ 0.0, DBL_MAX))
+ return -1;
+ break;
case 'R':
if (get_arg_val_d(c, optarg, &phc_rate, 0.0, DBL_MAX))
return -1;
diff --git a/pi.c b/pi.c
index 78cbd3f..89080c4 100644
--- a/pi.c
+++ b/pi.c
@@ -35,6 +35,7 @@
double configured_pi_kp = 0.0;
double configured_pi_ki = 0.0;
double configured_pi_offset = 0.0;
+double configured_pi_f_offset = 0.0000001; /* 100 nanoseconds */
int configured_pi_max_freq = 900000000;
struct pi_servo {
@@ -46,7 +47,9 @@ struct pi_servo {
double kp;
double ki;
double max_offset;
+ double max_f_offset;
int count;
+ int first_update;
};
static void pi_destroy(struct servo *servo)
@@ -88,7 +91,14 @@ static double pi_sample(struct servo *servo,
else if (s->drift > s->maxppb)
s->drift = s->maxppb;
- *state = SERVO_JUMP;
+ if (!s->first_update ||
+ (s->max_f_offset && (s->max_f_offset < fabs(offset))) ||
+ (s->max_offset && (s->max_offset < fabs(offset))))
+ *state = SERVO_JUMP;
+ else
+ *state = SERVO_LOCKED;
+
+ s->first_update = 0;
ppb = s->drift;
s->count = 2;
break;
@@ -134,6 +144,7 @@ struct servo *pi_servo_create(int fadj, int max_ppb, int sw_ts)
s->servo.sample = pi_sample;
s->drift = fadj;
s->maxppb = max_ppb;
+ s->first_update = 1;
if (configured_pi_kp && configured_pi_ki) {
s->kp = configured_pi_kp;
@@ -152,6 +163,12 @@ struct servo *pi_servo_create(int fadj, int max_ppb, int sw_ts)
s->max_offset = 0.0;
}
+ if (configured_pi_f_offset > 0.0) {
+ s->max_f_offset = configured_pi_f_offset * NSEC_PER_SEC;
+ } else {
+ s->max_f_offset = 0.0;
+ }
+
if (configured_pi_max_freq && s->maxppb > configured_pi_max_freq) {
s->maxppb = configured_pi_max_freq;
}
diff --git a/pi.h b/pi.h
index 954f495..2f31bce 100644
--- a/pi.h
+++ b/pi.h
@@ -36,13 +36,22 @@ extern double configured_pi_ki;
/**
* When set to a non-zero value, this variable controls the maximum allowed
* offset before a clock jump occurs instead of the default clock-slewing
- * mechanism
+ * mechanism.
*
* Note that this variable is measured in seconds, and allows fractional values.
*/
extern double configured_pi_offset;
/**
+ * When set to zero, the clock is not stepped on start. When set to a non-zero
+ * value, the value bahaves as a threshold and the clock is stepped on start if
+ * the offset is bigger than the threshold.
+ *
+ * Note that this variable is measured in seconds, and allows fractional values.
+ */
+extern double configured_pi_f_offset;
+
+/**
* When set to a non-zero value, this variable sets an additional limit for
* the frequency adjustment of the clock. It's in ppb.
*/
--
1.7.1
1.7.1