sys: include predicted drift in adjtime() offset
In drivers with periodic drift removal include in the adjustment also a prediction of the error gained in half of the interval to move the mean offset of the clock closer to zero. E.g. offset of a stable clock drifting by 10 ppm should now be closer to 0 +/- 5 microseconds instead of 5 +/- 5 microseconds.
This commit is contained in:
parent
18d514d552
commit
b6a27df5b9
3 changed files with 12 additions and 9 deletions
|
@ -108,7 +108,7 @@ start_adjust(void)
|
||||||
{
|
{
|
||||||
struct timeval newadj, oldadj;
|
struct timeval newadj, oldadj;
|
||||||
struct timeval T1;
|
struct timeval T1;
|
||||||
double elapsed, accrued_error;
|
double elapsed, accrued_error, predicted_error;
|
||||||
double adjust_required;
|
double adjust_required;
|
||||||
double rounding_error;
|
double rounding_error;
|
||||||
double old_adjust_remaining;
|
double old_adjust_remaining;
|
||||||
|
@ -120,8 +120,9 @@ start_adjust(void)
|
||||||
|
|
||||||
UTI_DiffTimevalsToDouble(&elapsed, &T1, &T0);
|
UTI_DiffTimevalsToDouble(&elapsed, &T1, &T0);
|
||||||
accrued_error = elapsed * current_freq;
|
accrued_error = elapsed * current_freq;
|
||||||
|
predicted_error = DRIFT_REMOVAL_INTERVAL / 2.0 * current_freq;
|
||||||
|
|
||||||
adjust_required = - (accrued_error + offset_register);
|
adjust_required = - (accrued_error + offset_register + predicted_error);
|
||||||
|
|
||||||
UTI_DoubleToTimeval(adjust_required, &newadj);
|
UTI_DoubleToTimeval(adjust_required, &newadj);
|
||||||
UTI_TimevalToDouble(&newadj, &adjustment_requested);
|
UTI_TimevalToDouble(&newadj, &adjustment_requested);
|
||||||
|
@ -133,7 +134,7 @@ start_adjust(void)
|
||||||
|
|
||||||
UTI_TimevalToDouble(&oldadj, &old_adjust_remaining);
|
UTI_TimevalToDouble(&oldadj, &old_adjust_remaining);
|
||||||
|
|
||||||
offset_register = rounding_error - old_adjust_remaining;
|
offset_register = rounding_error - old_adjust_remaining - predicted_error;
|
||||||
|
|
||||||
T0 = T1;
|
T0 = T1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -127,7 +127,7 @@ start_adjust(void)
|
||||||
{
|
{
|
||||||
struct timeval newadj, oldadj;
|
struct timeval newadj, oldadj;
|
||||||
struct timeval T1;
|
struct timeval T1;
|
||||||
double elapsed, accrued_error;
|
double elapsed, accrued_error, predicted_error;
|
||||||
double adjust_required;
|
double adjust_required;
|
||||||
struct timeval exact_newadj;
|
struct timeval exact_newadj;
|
||||||
double rounding_error;
|
double rounding_error;
|
||||||
|
@ -140,8 +140,9 @@ start_adjust(void)
|
||||||
|
|
||||||
UTI_DiffTimevalsToDouble(&elapsed, &T1, &T0);
|
UTI_DiffTimevalsToDouble(&elapsed, &T1, &T0);
|
||||||
accrued_error = elapsed * current_freq;
|
accrued_error = elapsed * current_freq;
|
||||||
|
predicted_error = DRIFT_REMOVAL_INTERVAL / 2.0 * current_freq;
|
||||||
|
|
||||||
adjust_required = - (accrued_error + offset_register);
|
adjust_required = - (accrued_error + offset_register + predicted_error);
|
||||||
|
|
||||||
UTI_DoubleToTimeval(adjust_required, &exact_newadj);
|
UTI_DoubleToTimeval(adjust_required, &exact_newadj);
|
||||||
|
|
||||||
|
@ -160,7 +161,7 @@ start_adjust(void)
|
||||||
|
|
||||||
UTI_TimevalToDouble(&oldadj, &old_adjust_remaining);
|
UTI_TimevalToDouble(&oldadj, &old_adjust_remaining);
|
||||||
|
|
||||||
offset_register = rounding_error - old_adjust_remaining;
|
offset_register = rounding_error - old_adjust_remaining - predicted_error;
|
||||||
|
|
||||||
T0 = T1;
|
T0 = T1;
|
||||||
UTI_TimevalToDouble(&newadj, &adjustment_requested);
|
UTI_TimevalToDouble(&newadj, &adjustment_requested);
|
||||||
|
|
|
@ -118,7 +118,7 @@ start_adjust(void)
|
||||||
{
|
{
|
||||||
struct timeval newadj, oldadj;
|
struct timeval newadj, oldadj;
|
||||||
struct timeval T1;
|
struct timeval T1;
|
||||||
double elapsed, accrued_error;
|
double elapsed, accrued_error, predicted_error;
|
||||||
double adjust_required;
|
double adjust_required;
|
||||||
struct timeval exact_newadj;
|
struct timeval exact_newadj;
|
||||||
double rounding_error;
|
double rounding_error;
|
||||||
|
@ -132,8 +132,9 @@ start_adjust(void)
|
||||||
|
|
||||||
UTI_DiffTimevalsToDouble(&elapsed, &T1, &T0);
|
UTI_DiffTimevalsToDouble(&elapsed, &T1, &T0);
|
||||||
accrued_error = elapsed * current_freq;
|
accrued_error = elapsed * current_freq;
|
||||||
|
predicted_error = DRIFT_REMOVAL_INTERVAL / 2.0 * current_freq;
|
||||||
|
|
||||||
adjust_required = - (accrued_error + offset_register);
|
adjust_required = - (accrued_error + offset_register + predicted_error);
|
||||||
|
|
||||||
UTI_DoubleToTimeval(adjust_required, &exact_newadj);
|
UTI_DoubleToTimeval(adjust_required, &exact_newadj);
|
||||||
|
|
||||||
|
@ -163,7 +164,7 @@ start_adjust(void)
|
||||||
|
|
||||||
UTI_TimevalToDouble(&oldadj, &old_adjust_remaining);
|
UTI_TimevalToDouble(&oldadj, &old_adjust_remaining);
|
||||||
|
|
||||||
offset_register = rounding_error - old_adjust_remaining;
|
offset_register = rounding_error - old_adjust_remaining - predicted_error;
|
||||||
|
|
||||||
T0 = T1;
|
T0 = T1;
|
||||||
UTI_TimevalToDouble(&newadj, &adjustment_requested);
|
UTI_TimevalToDouble(&newadj, &adjustment_requested);
|
||||||
|
|
Loading…
Reference in a new issue