adjtime(): Improve configuration and math
1) Previously adjustments less than 1 microsecond per tick would be completely ignored. Now they are applied over a shorter period at a rate of 1 us per tick. 2) Previously CLOCK_ADJTIME_PERIOD was in units of 1/100th of second. Change to milliseconds to be more generally useful unit. Change setting name to CLOCK_ADJTIME_PERIOD_MS to make the unit change easier to notice. 3) Previously CLOCK_ADJTIME_SLEWLIMIT was in percentage. Most clock crystals have better accuracy than 1%, so the minimum slew rate was excessive. Change to CLOCK_ADJTIME_SLEWLIMIT_PPM with setting value in parts per million. 4) No need to use floating point math in clock_adjtime.c.
This commit is contained in:
parent
76f6d340ee
commit
0611f39cdc
@ -217,28 +217,24 @@ config CLOCK_ADJTIME
|
||||
|
||||
if CLOCK_ADJTIME
|
||||
|
||||
config CLOCK_ADJTIME_SLEWLIMIT
|
||||
config CLOCK_ADJTIME_SLEWLIMIT_PPM
|
||||
int "Adjtime slew limit"
|
||||
default 2
|
||||
range 0 100
|
||||
default 20000
|
||||
range 1 1000000
|
||||
---help---
|
||||
Set limit of adjtime() clock slewing as parts per million.
|
||||
|
||||
In real time systems we do not want the time to adjust too quickly.
|
||||
CLOCK_ADJTIME_SLEWLIMIT defines how many seconds can time change
|
||||
during each clock.
|
||||
For example CLOCK_ADJTIME_SLEWLIMIT=1000 will slow or speed the timer
|
||||
tick period by at most 0.1 percent of the nominal value.
|
||||
|
||||
Note that CLOCK_ADJTIME_SLEWLIMIT is divided by 100 in source code,
|
||||
therefore CLOCK_ADJTIME_SLEWLIMIT=2 will result in possible 0.02 second
|
||||
adjustment.
|
||||
|
||||
config CLOCK_ADJTIME_PERIOD
|
||||
config CLOCK_ADJTIME_PERIOD_MS
|
||||
int "Adjtime period"
|
||||
default 97
|
||||
range 0 100
|
||||
default 970
|
||||
range 1 3600000
|
||||
---help---
|
||||
Define system clock adjustment period. Should be between 0.95 and 0.99.
|
||||
|
||||
Note that CLOCK_ADJTIME_PERIOD is divided by 100 in source code,
|
||||
therefore CLOCK_ADJTIME_PERIOD=97 will result in 0.97.
|
||||
Define system clock adjustment period in milliseconds.
|
||||
The adjustment commanded by adjtime() call is applied over this time period.
|
||||
|
||||
endif
|
||||
|
||||
|
@ -51,17 +51,6 @@
|
||||
is enabled!
|
||||
#endif
|
||||
|
||||
/* Set slew limit. In real time systems we don't want the time to adjust
|
||||
* too quickly. ADJTIME_SLEWLIMIT defines how many seconds can time change
|
||||
* during each clock.
|
||||
*/
|
||||
|
||||
#define ADJTIME_SLEWLIMIT (CONFIG_CLOCK_ADJTIME_SLEWLIMIT * 0.01)
|
||||
|
||||
/* Define system clock adjustment period. */
|
||||
|
||||
#define ADJTIME_PERIOD (CONFIG_CLOCK_ADJTIME_PERIOD * 0.01)
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
@ -158,7 +147,7 @@ int adjtime(FAR const struct timeval *delta, FAR struct timeval *olddelta)
|
||||
* of cycles over which we want to do the adjustment.
|
||||
*/
|
||||
|
||||
count = (USEC_PER_SEC * ADJTIME_PERIOD) / period_usec;
|
||||
count = (USEC_PER_MSEC * CONFIG_CLOCK_ADJTIME_PERIOD_MS) / period_usec;
|
||||
incr = adjust_usec / count;
|
||||
|
||||
/* Compute maximum possible period increase and check
|
||||
@ -166,7 +155,8 @@ int adjtime(FAR const struct timeval *delta, FAR struct timeval *olddelta)
|
||||
* one.
|
||||
*/
|
||||
|
||||
incr_limit = ADJTIME_SLEWLIMIT * period_usec;
|
||||
incr_limit = CONFIG_CLOCK_ADJTIME_SLEWLIMIT_PPM
|
||||
/ (USEC_PER_SEC / period_usec);
|
||||
if (incr > incr_limit)
|
||||
{
|
||||
/* It does... limit computed increase and increment count. */
|
||||
@ -175,6 +165,21 @@ int adjtime(FAR const struct timeval *delta, FAR struct timeval *olddelta)
|
||||
count = adjust_usec / incr;
|
||||
}
|
||||
|
||||
/* If requested adjustment is smaller than 1 microsecond per tick,
|
||||
* adjust the count instead.
|
||||
*/
|
||||
|
||||
if (adjust_usec == 0)
|
||||
{
|
||||
incr = 0;
|
||||
count = 0;
|
||||
}
|
||||
else if (incr == 0)
|
||||
{
|
||||
incr = 1;
|
||||
count = adjust_usec / incr;
|
||||
}
|
||||
|
||||
if (is_negative == 1)
|
||||
{
|
||||
/* Positive or negative? */
|
||||
@ -182,13 +187,6 @@ int adjtime(FAR const struct timeval *delta, FAR struct timeval *olddelta)
|
||||
incr = -incr;
|
||||
}
|
||||
|
||||
/* Ignore small differences. */
|
||||
|
||||
if (incr == 0)
|
||||
{
|
||||
count = 0;
|
||||
}
|
||||
|
||||
leave_critical_section(flags);
|
||||
|
||||
/* Initialize clock adjustment and get old adjust values. */
|
||||
|
Loading…
Reference in New Issue
Block a user