[Tinyos-2-commits] CVS: tinyos-2.x/tos/chips/msp430/adc12
Msp430RefVoltArbiterImplP.nc, 1.4, 1.5
Jan-Hinrich Hauer
janhauer at users.sourceforge.net
Thu Apr 5 06:42:40 PDT 2007
Update of /cvsroot/tinyos/tinyos-2.x/tos/chips/msp430/adc12
In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv25780
Modified Files:
Msp430RefVoltArbiterImplP.nc
Log Message:
Fixed a bug found by Maxime Muller:
> during event void AdcResource.granted[uint8_t client]()
> If your sref is not REFERENCE_VREFplus_AVss ||
> REFERENCE_VREFplus_VREFnegterm
> then you will never call Refvolt_1/2_5V.start()
> Now while releasing the resource, imho, we should do the same check
> else we end up with a post switchOff() loop
> as call RefVolt_1_5V.stop() will fail.
Fix: changed the "owner" variable to "syncOwner", which is now only modified in sync (task) context and have the async path "parallel" and unaffecting the "syncOwner" variable (hard to explain, have a look at the diff) - there's a test app in tinyos-2.x/apps/tests/msp430/Adc12.
Index: Msp430RefVoltArbiterImplP.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/chips/msp430/adc12/Msp430RefVoltArbiterImplP.nc,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -d -r1.4 -r1.5
*** Msp430RefVoltArbiterImplP.nc 12 Dec 2006 18:23:07 -0000 1.4
--- Msp430RefVoltArbiterImplP.nc 5 Apr 2007 13:42:36 -0000 1.5
***************
*** 47,51 ****
NO_OWNER = 0xFF,
};
! norace uint8_t owner = NO_OWNER;
task void switchOff();
--- 47,51 ----
NO_OWNER = 0xFF,
};
! norace uint8_t syncOwner = NO_OWNER;
task void switchOff();
***************
*** 64,71 ****
return FAIL;
else {
! error_t request = call AdcResource.immediateRequest[client]();
! if (request == SUCCESS)
! owner = client;
! return request;
}
}
--- 64,68 ----
return FAIL;
else {
! return call AdcResource.immediateRequest[client]();
}
}
***************
*** 74,81 ****
{
const msp430adc12_channel_config_t* settings = call Config.getConfiguration[client]();
- owner = client;
if (settings->sref == REFERENCE_VREFplus_AVss ||
settings->sref == REFERENCE_VREFplus_VREFnegterm){
error_t started;
if (settings->ref2_5v == REFVOLT_LEVEL_1_5)
started = call RefVolt_1_5V.start();
--- 71,86 ----
{
const msp430adc12_channel_config_t* settings = call Config.getConfiguration[client]();
if (settings->sref == REFERENCE_VREFplus_AVss ||
settings->sref == REFERENCE_VREFplus_VREFnegterm){
error_t started;
+ if (syncOwner != NO_OWNER){
+ // very rare case, which can only occur
+ // if no FIFO task scheduler
+ // is used (see comment below)
+ call AdcResource.release[client]();
+ call AdcResource.request[client]();
+ return;
+ }
+ syncOwner = client;
if (settings->ref2_5v == REFVOLT_LEVEL_1_5)
started = call RefVolt_1_5V.start();
***************
*** 83,87 ****
started = call RefVolt_2_5V.start();
if (started != SUCCESS){
! owner = NO_OWNER;
call AdcResource.release[client]();
call AdcResource.request[client]();
--- 88,92 ----
started = call RefVolt_2_5V.start();
if (started != SUCCESS){
! syncOwner = NO_OWNER;
call AdcResource.release[client]();
call AdcResource.request[client]();
***************
*** 93,100 ****
event void RefVolt_1_5V.startDone(error_t error)
{
! if (owner != NO_OWNER){
! // Note that it can still not be guaranteed that ClientResource.granted()
! // is not signalled after ClientResource.release() has been called.
! signal ClientResource.granted[owner]();
}
}
--- 98,105 ----
event void RefVolt_1_5V.startDone(error_t error)
{
! if (syncOwner != NO_OWNER){
! // assumption: a client which has called request() must
! // not call release() before it gets the granted()
! signal ClientResource.granted[syncOwner]();
}
}
***************
*** 102,109 ****
event void RefVolt_2_5V.startDone(error_t error)
{
! if (owner != NO_OWNER){
! // Note that it can still not be guaranteed that ClientResource.granted()
! // is not signalled after ClientResource.release() has been called.
! signal ClientResource.granted[owner]();
}
}
--- 107,114 ----
event void RefVolt_2_5V.startDone(error_t error)
{
! if (syncOwner != NO_OWNER){
! // assumption: a client which has called request() must
! // not call release() before it gets the granted()
! signal ClientResource.granted[syncOwner]();
}
}
***************
*** 111,128 ****
async command error_t ClientResource.release[uint8_t client]()
{
! atomic {
! if (owner == client){
! owner = NO_OWNER;
! post switchOff();
! }
! }
! return call AdcResource.release[client]();
}
task void switchOff()
{
! if (owner == NO_OWNER)
! if (call RefVolt_1_5V.stop() != SUCCESS)
post switchOff();
}
--- 116,146 ----
async command error_t ClientResource.release[uint8_t client]()
{
! error_t error;
! if (syncOwner == client)
! post switchOff();
! error = call AdcResource.release[client]();
! // If syncOwner == client then now there is an inconsistency between
! // the state of syncOwner and the actual owner of the Resource
! // (which is not owned by anyone, because it was just released).
! // The switchOff() task will resolve this incosistency, but a
! // client can call ClientResource.request() before this task is
! // posted. However, since Resource.granted is signalled in task context,
! // with a FIFO task scheduler we can be sure that switchOff() will
! // always be executed before the next Resource.granted event is
! // signalled. Unfortunately "TinyOS components MUST NOT assume a
! // FIFO policy" (TEP106), that's why there is some additional check
! // in AdcResource.granted above.
! return error;
}
task void switchOff()
{
! // update internal state
! if (syncOwner != NO_OWNER){
! if (call RefVolt_1_5V.stop() == SUCCESS){
! syncOwner = NO_OWNER;
! } else
post switchOff();
+ }
}
More information about the Tinyos-2-commits
mailing list