[Tinyos-2-commits] CVS: tinyos-2.x/tos/chips/at45db ConfigStorageP.nc, 1.1.2.7, 1.1.2.8

David Gay idgay at users.sourceforge.net
Thu Sep 21 15:51:41 PDT 2006


Update of /cvsroot/tinyos/tinyos-2.x/tos/chips/at45db
In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv5738

Modified Files:
      Tag: tinyos-2_0_devel-BRANCH
	ConfigStorageP.nc 
Log Message:
update to not use verify/commit


Index: ConfigStorageP.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/chips/at45db/ConfigStorageP.nc,v
retrieving revision 1.1.2.7
retrieving revision 1.1.2.8
diff -C2 -d -r1.1.2.7 -r1.1.2.8
*** ConfigStorageP.nc	7 Jun 2006 23:11:27 -0000	1.1.2.7
--- ConfigStorageP.nc	21 Sep 2006 22:51:39 -0000	1.1.2.8
***************
*** 19,22 ****
--- 19,23 ----
  
  #include "Storage.h"
+ #include "crc.h"
  
  module ConfigStorageP {
***************
*** 54,57 ****
--- 55,59 ----
      S_STOPPED,
      S_MOUNT,
+     S_COMMIT,
      S_CLEAN,
      S_DIRTY,
***************
*** 64,72 ****
    };
  
!   /* Per-client state */
!   uint8_t state[N];
  
-   /* Version numbers for lower and upper half */
-   uint32_t lowVersion[N], highVersion[N];
  
    /* Bit n is true if client n is using upper block */
--- 66,82 ----
    };
  
!   /* Per-client state. We could keep just the state and current version
!      in an array, but this requires more complex arbitration (don't
!      release block storage during mount or commit). As I don't expect
!      many config volumes, this doesn't seem worth the trouble. */
!   struct {
!     uint8_t state : 3;
!     uint8_t committing : 1;
!   } s[N];
!   nx_struct {
!     nx_uint16_t crc;
!     nx_uint32_t version;
!   } low[N], high[N];
  
  
    /* Bit n is true if client n is using upper block */
***************
*** 91,94 ****
--- 101,108 ----
    }
  
+   storage_len_t volumeSize(uint8_t id) {
+     return call BlockRead.getSize[id]();
+   }
+ 
    /* ------------------------------------------------------------------ */
    /* Mounting								*/
***************
*** 98,115 ****
      /* Read version on both halves. Validate higher. Validate lower if
         higher invalid. Use lower if both invalid. */
!     if (state[id] != S_STOPPED)
        return FAIL;
  
!     state[id] = S_MOUNT;
      setFlip(id, FALSE);
!     call BlockRead.read[id](0, &lowVersion[id], sizeof lowVersion[id]);
  
      return SUCCESS;
    }
  
    void mountReadDone(uint8_t id, error_t error) {
      if (error != SUCCESS)
        {
! 	state[id] = S_STOPPED;
  	signal Mount.mountDone[id](FAIL);
        }
--- 112,135 ----
      /* Read version on both halves. Validate higher. Validate lower if
         higher invalid. Use lower if both invalid. */
!     if (s[id].state != S_STOPPED)
        return FAIL;
  
!     s[id].state = S_MOUNT;
      setFlip(id, FALSE);
!     call BlockRead.read[id](0, &low[id], sizeof low[id]);
  
      return SUCCESS;
    }
  
+   void computeCrc(uint8_t id) {
+     call BlockRead.computeCrc[id](sizeof(nx_uint16_t),
+ 				  volumeSize(id) - sizeof(nx_uint16_t),
+ 				  0);
+   }
+ 
    void mountReadDone(uint8_t id, error_t error) {
      if (error != SUCCESS)
        {
! 	s[id].state = S_STOPPED;
  	signal Mount.mountDone[id](FAIL);
        }
***************
*** 118,150 ****
  	/* Just read low-half version. Read high-half version */
  	setFlip(id, TRUE);
! 	call BlockRead.read[id](0, &highVersion[id], sizeof highVersion[id]);
        }
      else
        {
  	/* Verify the half with the largest version */
! 	setFlip(id, highVersion[id] > lowVersion[id]);
! 	call BlockRead.verify[id]();
        }
    }
  
!   void mountVerifyDone(uint8_t id, error_t error) {
!     if (error == SUCCESS) 
!       state[id] = S_CLEAN;
      else
        {
  	// try the other half?
! 	bool isflipped = call BConfig.flipped[id]();
! 
! 	if ((highVersion[id] > lowVersion[id]) == isflipped)
  	  {
  	    /* Verification of the half with the highest version failed. Try
  	       the other half. */
  	    setFlip(id, !isflipped);
! 	    call BlockRead.verify[id]();
  	    return;
  	  }
! 	/* both halves bad, just declare success and use the current half... */
! 	state[id] = S_INVALID;
! 	lowVersion[id] = highVersion[id] = 0;
        }
      signal Mount.mountDone[id](SUCCESS);
--- 138,176 ----
  	/* Just read low-half version. Read high-half version */
  	setFlip(id, TRUE);
! 	call BlockRead.read[id](0, &high[id], sizeof high[id]);
        }
      else
        {
  	/* Verify the half with the largest version */
! 	setFlip(id, high[id].version > low[id].version);
! 	computeCrc(id);
        }
    }
  
!   void mountCrcDone(uint8_t id, uint16_t crc, error_t error) {
!     bool isflipped = call BConfig.flipped[id]();
! 
!     if (error == SUCCESS &&
! 	crc == (isflipped ? high[id].crc : low[id].crc))
!       {
! 	/* We just use the low data once mounted */
! 	if (isflipped)
! 	  low[id].version = high[id].version;
! 	s[id].state = S_CLEAN;
!       }
      else
        {
  	// try the other half?
! 	if ((high[id].version > low[id].version) == isflipped)
  	  {
  	    /* Verification of the half with the highest version failed. Try
  	       the other half. */
  	    setFlip(id, !isflipped);
! 	    computeCrc(id);
  	    return;
  	  }
! 	/* Both halves bad, terminate. Reads will fail. */
! 	s[id].state = S_INVALID;
! 	low[id].version = 0;
        }
      signal Mount.mountDone[id](SUCCESS);
***************
*** 157,170 ****
    command error_t ConfigStorage.read[uint8_t id](storage_addr_t addr, void* buf, storage_len_t len) {
      /* Read from current half using BlockRead */
!     if (state[id] < S_CLEAN)
        return EOFF;
!     if (state[id] == S_INVALID) // nothing to read
        return FAIL;
  
!     return call BlockRead.read[id](addr + sizeof(uint32_t), buf, len);
    }
  
    void readReadDone(uint8_t id, storage_addr_t addr, void* buf, storage_len_t len, error_t error) {
!     signal ConfigStorage.readDone[id](addr - sizeof(uint32_t), buf, len, error);
    }
  
--- 183,196 ----
    command error_t ConfigStorage.read[uint8_t id](storage_addr_t addr, void* buf, storage_len_t len) {
      /* Read from current half using BlockRead */
!     if (s[id].state < S_CLEAN)
        return EOFF;
!     if (s[id].state == S_INVALID) // nothing to read
        return FAIL;
  
!     return call BlockRead.read[id](addr + sizeof low[0], buf, len);
    }
  
    void readReadDone(uint8_t id, storage_addr_t addr, void* buf, storage_len_t len, error_t error) {
!     signal ConfigStorage.readDone[id](addr - sizeof low[0], buf, len, error);
    }
  
***************
*** 178,184 ****
         2: Write to other half using BlockWrite */
  
!     if (state[id] < S_CLEAN)
        return EOFF;
!     return call BlockWrite.write[id](addr + sizeof(uint32_t), buf, len);
    }
  
--- 204,210 ----
         2: Write to other half using BlockWrite */
  
!     if (s[id].state < S_CLEAN)
        return EOFF;
!     return call BlockWrite.write[id](addr + sizeof low[0], buf, len);
    }
  
***************
*** 187,195 ****
  
    command int BConfig.writeHook[uint8_t id]() {
      flip(id); /* We write to the non-current half... */
!     if (state[id] != S_CLEAN) // no copy if dirty or invalid
        return FALSE;
  
!     /* Time to do the copy, version update dance */
      client = id;
      nextPage = signal BConfig.npages[id]();
--- 213,224 ----
  
    command int BConfig.writeHook[uint8_t id]() {
+     if (s[id].committing)
+       return FALSE;
+ 
      flip(id); /* We write to the non-current half... */
!     if (s[id].state != S_CLEAN) // no copy if dirty or invalid
        return FALSE;
  
!     /* Time to do the copy dance */
      client = id;
      nextPage = signal BConfig.npages[id]();
***************
*** 204,222 ****
      else if (nextPage == 0) // copy done
        {
! 	uint32_t *version;
! 
! 	// Update the version number of the half indicated by flipped()
! 	if (!flipped(client))
! 	  {
! 	    lowVersion[client] = highVersion[client] + 1;
! 	    version = &lowVersion[client];
! 	  }
! 	else
! 	  {
! 	    highVersion[client] = lowVersion[client] + 1;
! 	    version = &highVersion[client];
! 	  }
! 	call At45db.write(signal BConfig.remap[client](0), 0,
! 			  version, sizeof *version);
        }
      else
--- 233,238 ----
      else if (nextPage == 0) // copy done
        {
! 	s[client].state = S_DIRTY;
! 	writeContinue(SUCCESS);
        }
      else
***************
*** 235,244 ****
    }
  
-   void copyWriteDone(error_t error) {
-     if (error == SUCCESS)
-       state[client] = S_DIRTY;
-     writeContinue(error);
-   }
- 
    void writeContinue(error_t error) {
      uint8_t id = client;
--- 251,254 ----
***************
*** 250,254 ****
    void writeWriteDone(uint8_t id, storage_addr_t addr, void* buf, storage_len_t len, error_t error) {
      flip(id); // flip back to current half
!     signal ConfigStorage.writeDone[id](addr - sizeof(uint32_t), buf, len, error);
    }
  
--- 260,264 ----
    void writeWriteDone(uint8_t id, storage_addr_t addr, void* buf, storage_len_t len, error_t error) {
      flip(id); // flip back to current half
!     signal ConfigStorage.writeDone[id](addr - sizeof low[0], buf, len, error);
    }
  
***************
*** 257,276 ****
    /* ------------------------------------------------------------------ */
  
    command error_t ConfigStorage.commit[uint8_t id]() {
      /* Call BlockWrite.commit */
-     /* Could special-case attempt to commit clean block */
      error_t ok;
  
!     if (state[id] < S_CLEAN)
        return EOFF;
!     ok = call BlockWrite.commit[id]();
      if (ok == SUCCESS)
!       flip(id); // switch to new block for commit
      return ok;
    }
  
    void commitDone(uint8_t id, error_t error) {
      if (error == SUCCESS)
!       state[id] = S_CLEAN;
      else
        flip(id); // revert to old block
--- 267,327 ----
    /* ------------------------------------------------------------------ */
  
+   void commitDone(uint8_t id, error_t error);
+ 
    command error_t ConfigStorage.commit[uint8_t id]() {
      /* Call BlockWrite.commit */
      error_t ok;
+     uint16_t crc;
+     uint8_t i;
  
!     if (s[id].state < S_CLEAN)
        return EOFF;
! 
!     if (s[id].state == S_CLEAN)
!       /* A dummy CRC call to avoid signaling a completion event from here */
!       return call BlockRead.computeCrc[id](0, 1, 0);
! 
!     /* Compute CRC for new version and current contents */
!     flip(id);
!     low[id].version++;
!     for (crc = 0, i = 0; i < sizeof low[id].version; i++)
!       crc = crcByte(crc, ((uint8_t *)&low[id] + sizeof(nx_uint16_t))[i]);
!     ok = call BlockRead.computeCrc[id](sizeof low[id],
! 				       volumeSize(id) - sizeof low[id],
! 				       crc);
      if (ok == SUCCESS)
!       s[id].committing = TRUE;
! 
      return ok;
    }
  
+   void commitCrcDone(uint8_t id, uint16_t crc, error_t error) {
+     /* Weird commit of clean volume hack: we just complete now, w/o
+        really doing anything. Ideally we should short-circuit out in the
+        commit call, but that would break the "no-signal-from-command"
+        rule. So we just waste the CRC computation effort instead - the
+        assumption is people don't regularly commit clean volumes. */
+     if (s[id].state == S_CLEAN)
+       signal ConfigStorage.commitDone[id](error);
+     else if (error != SUCCESS)
+       commitDone(id, error);
+     else
+       {
+ 	low[id].crc = crc;
+ 	call BlockWrite.write[id](0, &low[id], sizeof low[id]);
+       }
+   }
+ 
+   void commitWriteDone(uint8_t id, error_t error) {
+     if (error != SUCCESS)
+       commitDone(id, error);
+     else
+       call BlockWrite.commit[id]();
+   }
+ 
    void commitDone(uint8_t id, error_t error) {
+     s[id].committing = FALSE;
      if (error == SUCCESS)
!       s[id].state = S_CLEAN;
      else
        flip(id); // revert to old block
***************
*** 283,287 ****
  
    command storage_len_t ConfigStorage.getSize[uint8_t id]() {
!     return call BlockRead.getSize[id]();
    }
  
--- 334,338 ----
  
    command storage_len_t ConfigStorage.getSize[uint8_t id]() {
!     return volumeSize(id) - sizeof low[0];
    }
  
***************
*** 291,295 ****
  
    command bool ConfigStorage.valid[uint8_t id]() {
!     return state[id] != S_INVALID;
    }
  
--- 342,346 ----
  
    command bool ConfigStorage.valid[uint8_t id]() {
!     return s[id].state != S_INVALID;
    }
  
***************
*** 311,315 ****
    event void BlockRead.readDone[uint8_t id](storage_addr_t addr, void* buf, storage_len_t len, error_t error) {
      if (id < N)
!       if (state[id] == S_MOUNT)
  	mountReadDone(id, error);
        else
--- 362,366 ----
    event void BlockRead.readDone[uint8_t id](storage_addr_t addr, void* buf, storage_len_t len, error_t error) {
      if (id < N)
!       if (s[id].state == S_MOUNT)
  	mountReadDone(id, error);
        else
***************
*** 317,328 ****
    }
  
-   event void BlockRead.verifyDone[uint8_t id]( error_t error ) {
-     if (id < N)
-       mountVerifyDone(id, error);
-   }
- 
    event void BlockWrite.writeDone[uint8_t id]( storage_addr_t addr, void* buf, storage_len_t len, error_t error ) {
      if (id < N)
!       writeWriteDone(id, addr, buf, len, error);
    }
  
--- 368,377 ----
    }
  
    event void BlockWrite.writeDone[uint8_t id]( storage_addr_t addr, void* buf, storage_len_t len, error_t error ) {
      if (id < N)
!       if (s[id].committing)
! 	commitWriteDone(id, error);
!       else
! 	writeWriteDone(id, addr, buf, len, error);
    }
  
***************
*** 332,338 ****
    }
  
!   event void At45db.writeDone(error_t error) {
!     if (client != NO_CLIENT)
!       copyWriteDone(error);
    }
  
--- 381,390 ----
    }
  
!   event void BlockRead.computeCrcDone[uint8_t id]( storage_addr_t addr, storage_len_t len, uint16_t crc, error_t error ) {
!     if (id < N)
!       if (s[id].state == S_MOUNT)
! 	mountCrcDone(id, crc, error);
!       else
! 	commitCrcDone(id, crc, error);
    }
  
***************
*** 342,347 ****
    }
  
!   event void BlockRead.computeCrcDone[uint8_t id]( storage_addr_t addr, storage_len_t len, uint16_t crc, error_t error ) {}
!   event void BlockWrite.eraseDone[uint8_t id]( error_t error ) {}
    event void At45db.eraseDone(error_t error) {}
    event void At45db.syncDone(error_t error) {}
--- 394,399 ----
    }
  
!   event void BlockRead.verifyDone[uint8_t id](error_t error) {}
!   event void BlockWrite.eraseDone[uint8_t id](error_t error) {}
    event void At45db.eraseDone(error_t error) {}
    event void At45db.syncDone(error_t error) {}
***************
*** 349,352 ****
--- 401,405 ----
    event void At45db.readDone(error_t error) {}
    event void At45db.computeCrcDone(error_t error, uint16_t crc) {}
+   event void At45db.writeDone(error_t error) {}
  
    default event void Mount.mountDone[uint8_t id](error_t error) { }



More information about the Tinyos-2-commits mailing list