You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2023/09/29 05:03:17 UTC
[nuttx] 02/02: adjtime(): Improve configuration and math
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 <jp...@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. */