[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