Clock freq Sparc

Aaron J. Grier aaron at frye.com
Tue May 20 17:35:17 UTC 2008


On Thu, May 15, 2008 at 02:54:07PM +0100, Neil Mayes wrote:
> I have got a board with a clock frequency of 7.372800 MHz, which means
> the way the ERC32 BSP handles the clock and timer will introduce
> errors.  I am suspecting most people pick whole MHz for their boards?
> 
> Has anybody used something more general for the scalar/counter when
> the frequency is not a complete MHz?
> 
> Should I accept the loss in granularity, any thoughts really? I am not
> fussed about long term drift since it is correct frequently via GPS.

we have a 68k system running at 24.117MHz (23MiHz) PLLd up from a 32kHz
crystal.  I was concerned about system time drift since the tick lengths
were odd, and made some modifications to RTEMS' time of day routines to
keep a microsecond overflow counter, and use that to adjust the clock
watchdog timer.  this doesn't affect the tick length or the scheduling
quantum -- only the system time-of-date and associated calls such as
rtems_task_wake_when().

I've attached my original patch for 4.5.0.  I have applied it to our
local 4.6.6 branch, but it has not gone through any sort of testing
there, and doesn't appear to have been integrated back into the master
OAR repository.  (it would need to be updated for the conversion to
timespec.)

-- 
  Aaron J. Grier  |   Frye Electronics, Tigard, OR   |  aaron at frye.com
-------------- next part --------------
Index: 0.31/c/src/exec/score/macros/rtems/score/tod.inl
--- 0.31/c/src/exec/score/macros/rtems/score/tod.inl Fri, 29 Sep 2000 20:11:24 -0700 kaben (rtems/L/b/27_tod.inl 1.1 664)
+++ 0.32/c/src/exec/score/macros/rtems/score/tod.inl Sat, 25 May 2002 17:15:34 -0700 aaron (rtems/L/b/27_tod.inl 1.2 664)
@@ -24,7 +24,8 @@
 
 #define _TOD_Tickle_ticks() \
   _TOD_Current.ticks++; \
-  _Watchdog_Ticks_since_boot++
+  _Watchdog_Ticks_since_boot++; \
+  _TOD_Cumulative_slop += _TOD_Slop_per_tick;
 
 /*PAGE
  *
Index: 0.31/c/src/exec/score/inline/rtems/score/tod.inl
--- 0.31/c/src/exec/score/inline/rtems/score/tod.inl Fri, 29 Sep 2000 20:11:24 -0700 kaben (rtems/M/b/3_tod.inl 1.1 664)
+++ 0.32/c/src/exec/score/inline/rtems/score/tod.inl Sat, 25 May 2002 17:15:34 -0700 aaron (rtems/M/b/3_tod.inl 1.2 664)
@@ -30,6 +30,7 @@
 {
   _TOD_Current.ticks += 1;
   _Watchdog_Ticks_since_boot += 1;
+  _TOD_Cumulative_slop += _TOD_Slop_per_tick;
 }
 
 /*PAGE
Index: 0.31/c/src/exec/score/include/rtems/score/tod.h
--- 0.31/c/src/exec/score/include/rtems/score/tod.h Fri, 29 Sep 2000 20:11:24 -0700 kaben (rtems/M/b/32_tod.h 1.1 664)
+++ 0.32/c/src/exec/score/include/rtems/score/tod.h Sat, 25 May 2002 17:15:34 -0700 aaron (rtems/M/b/32_tod.h 1.2 664)
@@ -101,9 +101,15 @@
  *  per clock tick, this value will contain only the integer portion
  *  of the division.  This means that the interval between clock ticks
  *  can be a source of error in the current time of day.
+ *
+ *  To help alleviate this problem, we keep a running error (in
+ *  microseconds) and adjust the scheduling of the seconds watchdog
+ *  accordingly.
  */
 
 SCORE_EXTERN unsigned32 _TOD_Ticks_per_second;
+SCORE_EXTERN signed32 _TOD_Slop_per_tick;
+SCORE_EXTERN signed32 _TOD_Cumulative_slop;
 
 /*
  *  This is the control structure for the watchdog timer which
Index: 0.31/c/src/exec/score/src/coretodtickle.c
--- 0.31/c/src/exec/score/src/coretodtickle.c Fri, 29 Sep 2000 20:11:24 -0700 kaben (rtems/O/b/36_coretodtic 1.1 664)
+++ 0.32/c/src/exec/score/src/coretodtickle.c Sat, 25 May 2002 17:15:34 -0700 aaron (rtems/O/b/36_coretodtic 1.2 664)
@@ -62,6 +62,31 @@
     }
   }
 
+  /* tickle the seconds timer */
   _Watchdog_Tickle_seconds();
-  _Watchdog_Insert_ticks( &_TOD_Seconds_watchdog, _TOD_Ticks_per_second );
+
+  /* prepare to schedule the next tick */
+  if (_TOD_Slop_per_tick == 0)
+    _Watchdog_Insert_ticks( &_TOD_Seconds_watchdog, _TOD_Ticks_per_second );
+  else if (_TOD_Slop_per_tick > 0) { /* running fast */
+    if (_TOD_Cumulative_slop > _TOD_Microseconds_per_tick) {
+      _TOD_Cumulative_slop%=_TOD_Microseconds_per_tick;
+      _Watchdog_Insert_ticks(
+         &_TOD_Seconds_watchdog, _TOD_Ticks_per_second + 1
+      );
+    } else _Watchdog_Insert_ticks(
+       &_TOD_Seconds_watchdog, _TOD_Ticks_per_second
+      );
+  } else { /* running slow */
+    if (_TOD_Cumulative_slop < (-1 * _TOD_Microseconds_per_tick)) {
+      /* C doesn't really do modular arithmetic, so we fake it */
+      _TOD_Cumulative_slop%=_TOD_Microseconds_per_tick;
+      _TOD_Cumulative_slop+=_TOD_Microseconds_per_tick;
+      _Watchdog_Insert_ticks(
+         &_TOD_Seconds_watchdog, _TOD_Ticks_per_second - 1
+      );
+    } else _Watchdog_Insert_ticks(
+       &_TOD_Seconds_watchdog, _TOD_Ticks_per_second
+      );
+  }
 }
Index: 0.31/c/src/exec/score/src/coretod.c
--- 0.31/c/src/exec/score/src/coretod.c Fri, 29 Sep 2000 20:11:24 -0700 kaben (rtems/O/b/38_coretod.c 1.1 664)
+++ 0.32/c/src/exec/score/src/coretod.c Sat, 25 May 2002 17:15:34 -0700 aaron (rtems/O/b/38_coretod.c 1.2 664)
@@ -48,9 +48,14 @@
 
   if ( microseconds_per_tick == 0 )
     _TOD_Ticks_per_second = 0;
-  else
+  else {
     _TOD_Ticks_per_second =
        TOD_MICROSECONDS_PER_SECOND / microseconds_per_tick;
+    _TOD_Slop_per_tick =
+       TOD_MICROSECONDS_PER_SECOND / _TOD_Ticks_per_second
+       - microseconds_per_tick;
+    _TOD_Cumulative_slop = 0;
+  }
 
   _Watchdog_Initialize( &_TOD_Seconds_watchdog, _TOD_Tickle, 0, NULL );
 


More information about the users mailing list