This is the mail archive of the
ecos-patches@sourceware.org
mailing list for the eCos project.
Wallclock fix
- From: Gary Thomas <gary at mlbassoc dot com>
- To: eCos patches <ecos-patches at ecos dot sourceware dot org>
- Date: Sun, 14 Jan 2007 05:19:28 -0700
- Subject: Wallclock fix
For systems that use interrupts to run the wallclock hardware
(think I2C RTC chips), using the DSR lock for exclusion will
cause the system to hang. This change fixes that by using
a mutex instead.
--
------------------------------------------------------------
Gary Thomas | Consulting for the
MLB Associates | Embedded world
------------------------------------------------------------
Index: io/wallclock/current/ChangeLog
===================================================================
RCS file: /misc/cvsfiles/ecos/packages/io/wallclock/current/ChangeLog,v
retrieving revision 1.17
diff -u -5 -p -r1.17 ChangeLog
--- io/wallclock/current/ChangeLog 4 Oct 2003 19:47:17 -0000 1.17
+++ io/wallclock/current/ChangeLog 14 Jan 2007 12:16:41 -0000
@@ -1,5 +1,12 @@
+2007-01-14 Gary Thomas <gary@mlbassoc.com>
+
+ * src/wallclock.cxx: Use a mutex for exclusion during get/set
+ operations as the DSR lock may not be appropriate for systems
+ that need to use interrupts to accomplish these functions,
+ (e.g. I2C clock devices).
+
2003-09-23 Dan Jakubiec <firstname.lastname@systech.com>
* src/emulate.cxx (get_hw_seconds): Modified the ticks-to-seconds
conversion in the wallclock emulator's get_hw_seconds() function.
The previous implementation would easily overflow for any
Index: io/wallclock/current/src/wallclock.cxx
===================================================================
RCS file: /misc/cvsfiles/ecos/packages/io/wallclock/current/src/wallclock.cxx,v
retrieving revision 1.6
diff -u -5 -p -r1.6 wallclock.cxx
--- io/wallclock/current/src/wallclock.cxx 23 May 2002 23:06:38 -0000 1.6
+++ io/wallclock/current/src/wallclock.cxx 12 Jan 2007 12:46:41 -0000
@@ -85,20 +85,25 @@ static Cyg_WallClock wallclock_instance
#ifndef CYGSEM_WALLCLOCK_SET_GET_MODE
static cyg_uint32 epoch_ticks;
static cyg_uint32 epoch_time_stamp;
#endif
+static cyg_drv_mutex_t wallclock_lock;
+
Cyg_WallClock *Cyg_WallClock::wallclock;
//-----------------------------------------------------------------------------
// Constructor
Cyg_WallClock::Cyg_WallClock()
{
// install instance pointer
wallclock = &wallclock_instance;
+ // Initialize lock used for mutually exclusive access to hardware
+ cyg_drv_mutex_init(&wallclock_lock);
+
// Always allow low-level driver to initialize clock, even though it
// may not be necessary for set-get mode.
init_hw_seconds();
}
@@ -109,38 +114,38 @@ Cyg_WallClock::Cyg_WallClock()
cyg_uint32 Cyg_WallClock::get_current_time()
{
cyg_uint32 res;
- cyg_drv_dsr_lock();
+ while (!cyg_drv_mutex_lock(&wallclock_lock));
#ifdef CYGSEM_WALLCLOCK_SET_GET_MODE
res = get_hw_seconds();
#else
res = epoch_time_stamp + get_hw_seconds() - epoch_ticks;
#endif
- cyg_drv_dsr_unlock();
+ cyg_drv_mutex_unlock(&wallclock_lock);
return res;
}
//-----------------------------------------------------------------------------
// Sets the clock. Argument is seconds elapsed since 1970-01-01 00:00:00.
// This may involve reading or writing to the hardware, so it may take
// anything up to a second to complete.
void Cyg_WallClock::set_current_time( cyg_uint32 time_stamp )
{
- cyg_drv_dsr_lock();
+ while (!cyg_drv_mutex_lock(&wallclock_lock));
#ifdef CYGSEM_WALLCLOCK_SET_GET_MODE
set_hw_seconds(time_stamp);
#else
epoch_time_stamp = time_stamp;
epoch_ticks = get_hw_seconds();
#endif
- cyg_drv_dsr_unlock();
+ cyg_drv_mutex_unlock(&wallclock_lock);
}
//-----------------------------------------------------------------------------
// End of devs/wallclock/wallclock.cxx