[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