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

David Gay idgay at users.sourceforge.net
Wed May 31 16:34:47 PDT 2006


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

Modified Files:
      Tag: tinyos-2_0_devel-BRANCH
	LogStorageP.nc 
Log Message:
update for cookie-based seek
fix log boundary location


Index: LogStorageP.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/chips/at45db/Attic/LogStorageP.nc,v
retrieving revision 1.1.2.8
retrieving revision 1.1.2.9
diff -C2 -d -r1.1.2.8 -r1.1.2.9
*** LogStorageP.nc	30 May 2006 23:42:23 -0000	1.1.2.8
--- LogStorageP.nc	31 May 2006 23:34:45 -0000	1.1.2.9
***************
*** 86,89 ****
--- 86,90 ----
    enum {
      META_IDLE,
+     META_LOCATEFIRST,
      META_LOCATE,
      META_LOCATELAST,
***************
*** 123,128 ****
    }
  
    at45page_t lastVolumePage() {
!     return call At45dbVolume.remap[client](call At45dbVolume.volumeSize[client]() >> AT45_PAGE_SIZE_LOG2);
    }
  
--- 124,133 ----
    }
  
+   at45page_t npages() {
+     return call At45dbVolume.volumeSize[client]();
+   }
+ 
    at45page_t lastVolumePage() {
!     return call At45dbVolume.remap[client](npages());
    }
  
***************
*** 138,142 ****
  
    void readFromBeginning() {
!     /* Set position to end of previous page, to force page advance
         on next read */
      s[client].rpos = 0;
--- 143,147 ----
  
    void readFromBeginning() {
!     /* Set position to end of page before first page, to force page advance
         on next read */
      s[client].rpos = 0;
***************
*** 232,236 ****
  		     uint8_t *buf, storage_len_t length) {
      if (s[id].request != R_IDLE)
!       return FAIL;
  
      /* You can make the transition from linear->circular once. */
--- 237,241 ----
  		     uint8_t *buf, storage_len_t length) {
      if (s[id].request != R_IDLE)
!       return EBUSY;
  
      /* You can make the transition from linear->circular once. */
***************
*** 257,261 ****
    }
  
!   command uint32_t LinearWrite.currentOffset[logstorage_t id]() {
     return s[id].wpos;
    }
--- 262,266 ----
    }
  
!   command storage_cookie_t LinearWrite.currentOffset[logstorage_t id]() {
     return s[id].wpos;
    }
***************
*** 273,284 ****
    }
  
!   command uint32_t LinearRead.currentOffset[logstorage_t id]() {
!     return s[id].rpos;
    }
  
!   command error_t LinearRead.seek[logstorage_t id](uint32_t offset) {
      return newRequest(R_SEEK, id, FALSE, (void *)(offset >> 16), offset);
    }
  
    command error_t CircularWrite.append[logstorage_t id](void* buf, storage_len_t length) {
      return newRequest(R_APPEND, id, TRUE, buf, length);
--- 278,293 ----
    }
  
!   command storage_cookie_t LinearRead.currentOffset[logstorage_t id]() {
!     return s[id].rvalid ? s[id].rpos : SEEK_BEGINNING;
    }
  
!   command error_t LinearRead.seek[logstorage_t id](storage_cookie_t offset) {
      return newRequest(R_SEEK, id, FALSE, (void *)(offset >> 16), offset);
    }
  
+   command storage_cookie_t LinearRead.getSize[logstorage_t id]() {
+     return call At45dbVolume.volumeSize[id]() * PAGE_SIZE;
+   }
+ 
    command error_t CircularWrite.append[logstorage_t id](void* buf, storage_len_t length) {
      return newRequest(R_APPEND, id, TRUE, buf, length);
***************
*** 302,315 ****
  
    command uint32_t CircularRead.currentOffset[logstorage_t id]() {
!     return s[id].rpos;
    }
  
!   command error_t CircularRead.seek[logstorage_t id](uint32_t offset) {
      return newRequest(R_SEEK, id, TRUE, (void *)(offset >> 16), offset);
    }
    /* ------------------------------------------------------------------ */
    /* Erase								*/
    /* ------------------------------------------------------------------ */
  
    void eraseContinue() {
      /* We erase backwards. That leaves the first two pages in the cache */
--- 311,334 ----
  
    command uint32_t CircularRead.currentOffset[logstorage_t id]() {
!     return call LinearRead.currentOffset[id]();
    }
  
!   command error_t CircularRead.seek[logstorage_t id](storage_cookie_t offset) {
      return newRequest(R_SEEK, id, TRUE, (void *)(offset >> 16), offset);
    }
+ 
+   command storage_cookie_t CircularRead.getSize[logstorage_t id]() {
+     return call LinearRead.getSize[id]();
+   }
+ 
    /* ------------------------------------------------------------------ */
    /* Erase								*/
    /* ------------------------------------------------------------------ */
  
+   void eraseMetadataDone() {
+     emptyLog(); // reset write pointer
+     endRequest(SUCCESS);
+   }
+ 
    void eraseContinue() {
      /* We erase backwards. That leaves the first two pages in the cache */
***************
*** 317,321 ****
        {
  	emptyLog();
! 	endRequest(SUCCESS);
        }
      else
--- 336,345 ----
        {
  	emptyLog();
! 	/* If we just reboot after erasing the flash, then the next attempt
! 	   to locate log boundaries will have to scan the while flash
! 	   (looking for a valid block). To reduce the chances of this, we
! 	   write a valid header in block 0 after erase. */
! 	metadata.flags = 0;
! 	wmetadataStart();
        }
      else
***************
*** 333,356 ****
    /* ------------------------------------------------------------------ */
  
!   at45page_t locateCurrentPage() {
!     return firstPage + ((lastPage - firstPage + 1) >> 1);
!   }
! 
!   void locateLastRecord() {
!     if (firstPage == firstVolumePage())
!       {
! 	/* Nothing valid found. We're done (log is empty). */
! 	emptyLog();
! 	startRequest();
!       }
!     else
!       readMetadata(--firstPage);
!   }
  
!   void locateLastReadDone() {
!     if (metadata.magic == PERSISTENT_MAGIC && metadata.flags & F_LASTVALID)
!       crcPage(firstPage);
!     else
!       locateLastRecord();
    }
  
--- 357,364 ----
    /* ------------------------------------------------------------------ */
  
!   void locateLastRecord();
  
!   at45page_t locateCurrentPage() {
!     return firstPage + ((lastPage - firstPage) >> 1);
    }
  
***************
*** 361,371 ****
  	s[client].positionKnown = TRUE;
  	if (metadata.flags & F_SYNC) /* must start on next page */
! 	  setWritePage(firstPage + 1);
  	else
  	  {
  	    s[client].wpage = firstPage;
  	    s[client].woffset = metadata.lastRecordOffset;
  	  }
- 	s[client].wpos = metadata.pos + metadata.lastRecordOffset;
  
  	/* If we're on the first pass (no F_CIRCLED flag), the read
--- 369,382 ----
  	s[client].positionKnown = TRUE;
  	if (metadata.flags & F_SYNC) /* must start on next page */
! 	  {
! 	    setWritePage(firstPage + 1);
! 	    s[client].wpos = metadata.pos + PAGE_SIZE;
! 	  }
  	else
  	  {
  	    s[client].wpage = firstPage;
  	    s[client].woffset = metadata.lastRecordOffset;
+ 	    s[client].wpos = metadata.pos + metadata.lastRecordOffset;
  	  }
  
  	/* If we're on the first pass (no F_CIRCLED flag), the read
***************
*** 394,397 ****
--- 405,426 ----
    }
  
+   void locateLastReadDone() {
+     if (metadata.magic == PERSISTENT_MAGIC && metadata.flags & F_LASTVALID)
+       crcPage(firstPage);
+     else
+       locateLastRecord();
+   }
+ 
+   void locateLastRecord() {
+     if (firstPage == firstVolumePage())
+       {
+ 	/* There were no valid pages with a record end */
+ 	emptyLog();
+ 	startRequest();
+       }
+     else
+       readMetadata(--firstPage);
+   }
+ 
    void located() {
      metaState = META_LOCATELAST;
***************
*** 402,406 ****
  
    void locateBinarySearch() {
!     if ((int)lastPage - (int)firstPage < 0)
        located();
      else
--- 431,435 ----
  
    void locateBinarySearch() {
!     if (lastPage <= firstPage)
        located();
      else
***************
*** 414,421 ****
  
    void locateLessThan() {
!     lastPage = locateCurrentPage() - 1;
      locateBinarySearch();
    }
  
    void locateReadDone() {
      if (metadata.magic == PERSISTENT_MAGIC && s[client].wpos < metadata.pos)
--- 443,460 ----
  
    void locateLessThan() {
!     lastPage = locateCurrentPage();
      locateBinarySearch();
    }
  
+   void locateCrcDone(uint16_t crc) {
+     if (crc == metadata.crc)
+       {
+ 	s[client].wpos = metadata.pos;
+ 	locateGreaterThan();
+       }
+     else
+       locateLessThan();
+   }
+ 
    void locateReadDone() {
      if (metadata.magic == PERSISTENT_MAGIC && s[client].wpos < metadata.pos)
***************
*** 425,449 ****
    }
  
!   void locateCrcDone(uint16_t crc) {
!     if (crc == metadata.crc)
        {
! 	s[client].wpos = metadata.pos + 1;
! 	locateGreaterThan();
        }
      else
!       locateLessThan();
    }
  
    /* Locate log beginning and ending */
    void locateStart() {
!     metaState = META_LOCATE;
      firstPage = firstVolumePage();
!     lastPage = lastVolumePage() - 1;
!     /* We track the page with the largest position found. We store
!        largest-offset-found+1, so that we can use 0 as a value smaller
!        than all valid positions. Note that wpos is set correctly once
!        we find the actual last page. */
!     s[client].wpos = 0;
!     locateBinarySearch();
    }
  
--- 464,505 ----
    }
  
!   void locateFirstCrcDone(uint16_t crc) {
!     firstPage++;
!     if (metadata.magic == PERSISTENT_MAGIC && crc == metadata.crc)
        {
! 	metaState = META_LOCATE;
! 	/* We track the page with the largest position found. */
! 	s[client].wpos = metadata.pos;
! 	/* We now know that the valid pages span a contiguous sequence
! 	   starting at firstPage - 1. The binary search will look for
! 	   the page with the largest position. */
! 	locateBinarySearch();
        }
+     else if (firstPage != lastPage)
+       /* Try the next page. There can be an arbitrary number of
+ 	 consecutive bad pages (see discussion at start of this file) */
+       readMetadata(firstPage);
      else
!       {
! 	/* Found no valid page. We might want to give up after some
! 	   bounded number of pages, rather than checking the whole
! 	   log -- many bad consecutive pages is extremely unlikely and
! 	   probably indicates a major problem somewhere. */
! 	emptyLog();
! 	startRequest();
!       }
!     
!   }
! 
!   void locateFirstReadDone() {
!     crcPage(firstPage);
    }
  
    /* Locate log beginning and ending */
    void locateStart() {
!     metaState = META_LOCATEFIRST;
      firstPage = firstVolumePage();
!     lastPage = lastVolumePage();
!     readMetadata(firstPage);
    }
  
***************
*** 488,500 ****
    }
  
!   void appendMetadataDone(error_t ok) { // metadata of previous page flushed
!     if (ok != SUCCESS)
!       endRequest(FAIL);
!     else
!       {
! 	/* Setup metadata in case we overflow this page too */
! 	metadata.flags = 0;
! 	appendContinue();
!       }
    }
  
--- 544,551 ----
    }
  
!   void appendMetadataDone() { // metadata of previous page flushed
!     /* Setup metadata in case we overflow this page too */
!     metadata.flags = 0;
!     appendContinue();
    }
  
***************
*** 522,527 ****
    }
  
!   void syncMetadataDone(error_t ok) {
!     endRequest(ok);
    }
  
--- 573,581 ----
    }
  
!   void syncMetadataDone() {
!     /* Write position reflect the absolute position in the flash, not
!        user-bytes written. So update wpos to reflect sync effects. */
!     s[client].wpos = metadata.pos + PAGE_SIZE;
!     endRequest(SUCCESS);
    }
  
***************
*** 604,608 ****
  	if ((s[client].rpage + 1 == lastVolumePage() && !s[client].circular) ||
  	    s[client].rpage == s[client].wpage)
! 	  endRequest(ESIZE);
  	else
  	  rmetadataStart();
--- 658,662 ----
  	if ((s[client].rpage + 1 == lastVolumePage() && !s[client].circular) ||
  	    s[client].rpage == s[client].wpage)
! 	  endRequest(SUCCESS);
  	else
  	  rmetadataStart();
***************
*** 650,654 ****
  	  /* We cannot find a record boundary to start at (we've just
  	     walked through the whole log...). Give up. */
! 	  endRequest(ESIZE);
  	else
  	  {
--- 704,708 ----
  	  /* We cannot find a record boundary to start at (we've just
  	     walked through the whole log...). Give up. */
! 	  endRequest(SUCCESS);
  	else
  	  {
***************
*** 667,671 ****
        crcPage(firstPage);
      else
!       endRequest(ESIZE);
    }
  
--- 721,725 ----
        crcPage(firstPage);
      else
!       endRequest(SUCCESS);
    }
  
***************
*** 680,684 ****
  	continueReadAt(0);
        else
! 	endRequest(ESIZE);
    }
  
--- 734,738 ----
  	continueReadAt(0);
        else
! 	endRequest(SUCCESS);
    }
  
***************
*** 690,788 ****
  
    /* ------------------------------------------------------------------ */
!   /* Seek. UNTESTED, PROBABLY DOESN'T WORK.				*/
    /* ------------------------------------------------------------------ */
  
!   at45page_t seekCurrentPage() {
!     return firstPage + ((lastPage - firstPage + 1) >> 1);
!   }
! 
!   at45page_t seekRealPage(at45page_t cpage) {
!     if (s[client].circled)
!       {
! 	cpage += s[client].wpage + 1;
! 	if (cpage >= lastVolumePage())
! 	  cpage -= lastVolumePage() - firstVolumePage();
! 
! 	return cpage;
!       }
!     else
!       return firstVolumePage() + cpage;
!   }
! 
!   void seekBinarySearch() {
!     if ((int)lastPage - (int)firstPage < 0)
        {
! 	/* It must be before the beginning, so we must be in the circled
! 	   case. Leave it up to the next read. */
! 	invalidateReadPointer();
! 	endRequest(SUCCESS);
        }
!     else
!       readMetadata(seekRealPage(seekCurrentPage()));
    }
  
    void seekReadDone() {
!     crcPage(seekRealPage(seekCurrentPage()));
!   }
! 
!   void seekCrcDone(uint16_t crc) {
!     at45page_t cpage = seekCurrentPage();
! 
!     if (metadata.magic == PERSISTENT_MAGIC && crc == metadata.crc)
!       {
! 	uint32_t pageStart = metadata.pos, pageEnd;
! 
! 	if (metadata.flags & F_SYNC)
! 	  pageEnd = pageStart + metadata.lastRecordOffset;
! 	else
! 	  pageEnd = pageStart + PAGE_SIZE;
! 	if (s[client].rpos >= pageStart)
! 	  {
! 	    if (s[client].rpos < pageEnd)
! 	      {
! 		s[client].rpage = seekRealPage(seekCurrentPage());
! 		s[client].roffset = s[client].rpos - pageStart;
! 		s[client].rend = 
! 		  metadata.flags & F_SYNC ? metadata.lastRecordOffset : PAGE_SIZE;
! 		endRequest(SUCCESS);
! 		return;
! 	      }
! 	    firstPage = cpage + 1;
! 	  }
! 	else
! 	  lastPage = cpage - 1;
! 	seekBinarySearch();
!       }
!     else
!       /* The first page after wpage may be invalid (from an earlier
! 	 failure). Seeks that have searched all the way to there indicate
! 	 a seek before the beginning of the log. 
! 	 All other failures indicate a corrupted page in the log, in
! 	 which case we fail the seek */
!       if (cpage == 0)
! 	{
! 	  invalidateReadPointer();
! 	  endRequest(SUCCESS);
! 	}
!       else
! 	endRequest(FAIL);
    }
  
!   /* Locate a specific offset. */
    void seekStart() {
      uint32_t offset = (uint32_t)(uint16_t)s[client].buf << 16 | s[client].len;
  
      if (offset > s[client].wpos)
!       offset = s[client].wpos; // don't go beyond end
  
      s[client].rpos = offset;
!     s[client].rvalid = TRUE;
  
      // The last page's metadata isn't written to flash yet. Special case it.
!     if (offset >= s[client].wpos - s[client].woffset)
        {
! 	s[client].rpage = s[client].wpage;
! 	s[client].roffset = offset - (s[client].wpos - s[client].woffset);
! 	s[client].rend = PAGE_SIZE;
  	endRequest(SUCCESS);
        }
--- 744,794 ----
  
    /* ------------------------------------------------------------------ */
!   /* Seek.								*/
    /* ------------------------------------------------------------------ */
  
!   void seekCrcDone(uint16_t crc) {
!     if (metadata.magic == PERSISTENT_MAGIC && crc == metadata.crc &&
! 	metadata.pos == s[client].rpos - s[client].roffset)
        {
! 	s[client].rvalid = TRUE;
! 	if (metadata.flags & F_SYNC)
! 	  s[client].rend = metadata.lastRecordOffset;
        }
!     endRequest(SUCCESS);
    }
  
    void seekReadDone() {
!     crcPage(s[client].rpage);
    }
  
!   /* Move to position specified by cookie. */
    void seekStart() {
      uint32_t offset = (uint32_t)(uint16_t)s[client].buf << 16 | s[client].len;
  
+     invalidateReadPointer(); // default to beginning of log
+ 
      if (offset > s[client].wpos)
!       {
! 	endRequest(EINVAL);
! 	return;
!       }
  
+     /* Cookies are just flash positions which continue incrementing as
+        you circle around and around. So we can just check the requested
+        page's metadata.pos field matches the cookie's value */
      s[client].rpos = offset;
!     s[client].roffset = offset % PAGE_SIZE;
!     s[client].rpage = firstVolumePage() + (offset / PAGE_SIZE) % npages();
!     s[client].rend = PAGE_SIZE; // default to no sync flag
  
      // The last page's metadata isn't written to flash yet. Special case it.
!     if (s[client].rpage == s[client].wpage)
        {
! 	/* If we're seeking within the current write page, just go there.
! 	   Otherwise, we're asking for an old version of the current page
! 	   so just keep the invalidated read pointer, i.e., read from
! 	   the beginning. */
! 	if (offset >= s[client].wpos - s[client].woffset)
! 	  s[client].rvalid = TRUE;
  	endRequest(SUCCESS);
        }
***************
*** 790,804 ****
        {
  	metaState = META_SEEK;
! 
! 	/* Page numbers are relative to the beginning of the log, which is
! 	   firstVolumePage() when the log hasn't circled, and wpage+1 when
! 	   it has */
! 	firstPage = 0;
! 	if (s[client].circled)
! 	  lastPage = (call At45dbVolume.volumeSize[client]() >> AT45_PAGE_SIZE_LOG2) - 2;
! 	else
! 	  lastPage = s[client].wpage - firstVolumePage() - 1;
! 
! 	seekBinarySearch();
        }
    }
--- 796,800 ----
        {
  	metaState = META_SEEK;
! 	readMetadata(s[client].rpage);
        }
    }
***************
*** 811,815 ****
      if (client != NO_CLIENT)
        if (error != SUCCESS)
! 	endRequest(error);
        else
  	eraseContinue();
--- 807,811 ----
      if (client != NO_CLIENT)
        if (error != SUCCESS)
! 	endRequest(FAIL);
        else
  	eraseContinue();
***************
*** 819,823 ****
      if (client != NO_CLIENT)
        if (error != SUCCESS)
! 	endRequest(error);
        else
  	switch (metaState)
--- 815,819 ----
      if (client != NO_CLIENT)
        if (error != SUCCESS)
! 	endRequest(FAIL);
        else
  	switch (metaState)
***************
*** 830,839 ****
    event void At45db.syncDone(error_t error) {
      if (client != NO_CLIENT)
!       syncMetadataDone(error);
    }
  
    event void At45db.flushDone(error_t error) {
      if (client != NO_CLIENT)
!       appendMetadataDone(error);
    }
  
--- 826,843 ----
    event void At45db.syncDone(error_t error) {
      if (client != NO_CLIENT)
!       if (error != SUCCESS)
! 	endRequest(FAIL);
!       else
! 	syncMetadataDone();
    }
  
    event void At45db.flushDone(error_t error) {
      if (client != NO_CLIENT)
!       if (error != SUCCESS)
! 	endRequest(FAIL);
!       else if (s[client].request == R_ERASE)
! 	eraseMetadataDone();
!       else
! 	appendMetadataDone();
    }
  
***************
*** 841,848 ****
      if (client != NO_CLIENT)
        if (error != SUCCESS)
! 	endRequest(error);
        else
  	switch (metaState)
  	  {
  	  case META_LOCATE: locateReadDone(); break;
  	  case META_LOCATELAST: locateLastReadDone(); break;
--- 845,853 ----
      if (client != NO_CLIENT)
        if (error != SUCCESS)
! 	endRequest(FAIL);
        else
  	switch (metaState)
  	  {
+ 	  case META_LOCATEFIRST: locateFirstReadDone(); break;
  	  case META_LOCATE: locateReadDone(); break;
  	  case META_LOCATELAST: locateLastReadDone(); break;
***************
*** 856,863 ****
      if (client != NO_CLIENT)
        if (error != SUCCESS)
! 	endRequest(error);
        else
  	switch (metaState)
  	  {
  	  case META_LOCATE: locateCrcDone(crc); break;
  	  case META_LOCATELAST: locateLastCrcDone(crc); break;
--- 861,869 ----
      if (client != NO_CLIENT)
        if (error != SUCCESS)
! 	endRequest(FAIL);
        else
  	switch (metaState)
  	  {
+ 	  case META_LOCATEFIRST: locateFirstCrcDone(crc); break;
  	  case META_LOCATE: locateCrcDone(crc); break;
  	  case META_LOCATELAST: locateLastCrcDone(crc); break;
***************
*** 868,871 ****
--- 874,879 ----
    }
  
+   event void At45db.copyPageDone(error_t error) { }
+ 
    default event void LinearWrite.appendDone[logstorage_t logId](void* buf, storage_len_t l, error_t error) { }
    default event void LinearWrite.eraseDone[logstorage_t logId](error_t error) { }
***************
*** 881,885 ****
  
    default command at45page_t At45dbVolume.remap[logstorage_t logId](at45page_t volumePage) {return 0;}
!   default command storage_len_t At45dbVolume.volumeSize[logstorage_t logId]() {return 0;}
    default async command error_t Resource.request[logstorage_t logId]() {return SUCCESS;}
    default async command void Resource.release[logstorage_t logId]() { }
--- 889,893 ----
  
    default command at45page_t At45dbVolume.remap[logstorage_t logId](at45page_t volumePage) {return 0;}
!   default command at45page_t At45dbVolume.volumeSize[logstorage_t logId]() {return 0;}
    default async command error_t Resource.request[logstorage_t logId]() {return SUCCESS;}
    default async command void Resource.release[logstorage_t logId]() { }



More information about the Tinyos-2-commits mailing list