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. */