Add a new servo option which specifies first step threshold

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 <ichikawa.ken@jp.fujitsu.com>
master
Ken ICHIKAWA 2013-06-20 13:30:15 +09:00 committed by Richard Cochran
parent b796d90e80
commit 28b8dc9996
4 changed files with 49 additions and 5 deletions

View File

@ -19,6 +19,10 @@ phc2sys \- synchronize two clocks
] [ ] [
.BI \-I " ki" .BI \-I " ki"
] [ ] [
.BI \-S " step"
] [
.BI \-F " step"
] [
.BI \-R " update-rate" .BI \-R " update-rate"
] [ ] [
.BI \-N " clock-readings" .BI \-N " clock-readings"
@ -87,8 +91,16 @@ Specify the integral constant of the PI controller. The default is 0.3.
.BI \-S " step" .BI \-S " step"
Specify the step threshold of the PI controller. It is the maximum offset that 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 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 clock. The clock is stepped on start regardless of the option if the offset is
after the start. The default is 0.0. 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 .TP
.BI \-R " update-rate" .BI \-R " update-rate"
Specify the slave clock update rate when running in the direct synchronization Specify the slave clock update rate when running in the direct synchronization

View File

@ -555,6 +555,7 @@ static void usage(char *progname)
" -P [kp] proportional constant (0.7)\n" " -P [kp] proportional constant (0.7)\n"
" -I [ki] integration constant (0.3)\n" " -I [ki] integration constant (0.3)\n"
" -S [step] step threshold (disabled)\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" " -R [rate] slave clock update rate in HZ (1.0)\n"
" -N [num] number of master clock readings per update (5)\n" " -N [num] number of master clock readings per update (5)\n"
" -O [offset] slave-master time offset (0)\n" " -O [offset] slave-master time offset (0)\n"
@ -593,7 +594,7 @@ int main(int argc, char *argv[])
progname = strrchr(argv[0], '/'); progname = strrchr(argv[0], '/');
progname = progname ? 1+progname : argv[0]; progname = progname ? 1+progname : argv[0];
while (EOF != (c = getopt(argc, argv, 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) { switch (c) {
case 'c': case 'c':
dst_clock.clkid = clock_open(optarg); dst_clock.clkid = clock_open(optarg);
@ -627,6 +628,11 @@ int main(int argc, char *argv[])
0.0, DBL_MAX)) 0.0, DBL_MAX))
return -1; return -1;
break; break;
case 'F':
if (get_arg_val_d(c, optarg, &configured_pi_f_offset,
0.0, DBL_MAX))
return -1;
break;
case 'R': case 'R':
if (get_arg_val_d(c, optarg, &phc_rate, 0.0, DBL_MAX)) if (get_arg_val_d(c, optarg, &phc_rate, 0.0, DBL_MAX))
return -1; return -1;

17
pi.c
View File

@ -35,6 +35,7 @@
double configured_pi_kp = 0.0; double configured_pi_kp = 0.0;
double configured_pi_ki = 0.0; double configured_pi_ki = 0.0;
double configured_pi_offset = 0.0; double configured_pi_offset = 0.0;
double configured_pi_f_offset = 0.0000001; /* 100 nanoseconds */
int configured_pi_max_freq = 900000000; int configured_pi_max_freq = 900000000;
struct pi_servo { struct pi_servo {
@ -46,7 +47,9 @@ struct pi_servo {
double kp; double kp;
double ki; double ki;
double max_offset; double max_offset;
double max_f_offset;
int count; int count;
int first_update;
}; };
static void pi_destroy(struct servo *servo) static void pi_destroy(struct servo *servo)
@ -88,7 +91,14 @@ static double pi_sample(struct servo *servo,
else if (s->drift > s->maxppb) else if (s->drift > s->maxppb)
s->drift = s->maxppb; s->drift = s->maxppb;
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; *state = SERVO_JUMP;
else
*state = SERVO_LOCKED;
s->first_update = 0;
ppb = s->drift; ppb = s->drift;
s->count = 2; s->count = 2;
break; break;
@ -134,6 +144,7 @@ struct servo *pi_servo_create(int fadj, int max_ppb, int sw_ts)
s->servo.sample = pi_sample; s->servo.sample = pi_sample;
s->drift = fadj; s->drift = fadj;
s->maxppb = max_ppb; s->maxppb = max_ppb;
s->first_update = 1;
if (configured_pi_kp && configured_pi_ki) { if (configured_pi_kp && configured_pi_ki) {
s->kp = configured_pi_kp; 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; 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) { if (configured_pi_max_freq && s->maxppb > configured_pi_max_freq) {
s->maxppb = configured_pi_max_freq; s->maxppb = configured_pi_max_freq;
} }

11
pi.h
View File

@ -36,12 +36,21 @@ extern double configured_pi_ki;
/** /**
* When set to a non-zero value, this variable controls the maximum allowed * 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 * 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. * Note that this variable is measured in seconds, and allows fractional values.
*/ */
extern double configured_pi_offset; 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 * When set to a non-zero value, this variable sets an additional limit for
* the frequency adjustment of the clock. It's in ppb. * the frequency adjustment of the clock. It's in ppb.