This is an automated email from the ASF dual-hosted git repository. xiaoxiang pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 0611f39cdcf0151ba23a4b995b0992db3edbba75 Author: Petteri Aimonen <j...@git.mail.kapsi.fi> AuthorDate: Thu Sep 28 10:52:15 2023 +0300 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. --- sched/Kconfig | 28 ++++++++++++---------------- sched/clock/clock_adjtime.c | 38 ++++++++++++++++++-------------------- 2 files changed, 30 insertions(+), 36 deletions(-) diff --git a/sched/Kconfig b/sched/Kconfig index 40f6a06f4b..1fd87a54c9 100644 --- a/sched/Kconfig +++ b/sched/Kconfig @@ -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--- - 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. + Set limit of adjtime() clock slewing as parts per million. - 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. + In real time systems we do not want the time to adjust too quickly. + For example CLOCK_ADJTIME_SLEWLIMIT=1000 will slow or speed the timer + tick period by at most 0.1 percent of the nominal value. -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 diff --git a/sched/clock/clock_adjtime.c b/sched/clock/clock_adjtime.c index 8c8d833320..3d8941dfac 100644 --- a/sched/clock/clock_adjtime.c +++ b/sched/clock/clock_adjtime.c @@ -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. */