⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 logstoragep.nc

📁 tinyos2.0版本驱动
💻 NC
📖 第 1 页 / 共 2 页
字号:
    readMetadata(firstPage);  }  void located() {    metaState = META_LOCATELAST;    /* firstPage is one after last valid page, but the last page with       a record end may be some pages earlier. Search for it. */    lastPage = lastVolumePage() - 1;    locateLastRecord();  }  at45page_t locateCurrentPage() {    return firstPage + ((lastPage - firstPage) >> 1);  }  void locateBinarySearch() {    if (lastPage <= firstPage)      located();    else      readMetadata(locateCurrentPage());  }  void locateGreaterThan() {    firstPage = locateCurrentPage() + 1;    locateBinarySearch();  }  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)      crcPage(locateCurrentPage());    else      locateLessThan();  }  void locateFirstCrcDone(uint16_t crc) {    if (metadata.magic == PERSISTENT_MAGIC && crc == metadata.crc)      s[client].wpos = metadata.pos;    else      s[client].wpos = 0;    metaState = META_LOCATE;    locateBinarySearch();  }  void locateFirstReadDone() {    crcPage(lastPage);  }  /* Locate log beginning and ending. See description at top of file. */  void locateStart() {    metaState = META_LOCATEFIRST;    firstPage = firstVolumePage();    lastPage = lastVolumePage() - 1;    readMetadata(lastPage);  }  /* ------------------------------------------------------------------ */  /* Append								*/  /* ------------------------------------------------------------------ */  void appendContinue() {    uint8_t *buf = s[client].buf;    at45pageoffset_t offset = s[client].woffset, count;        if (len == 0)      {	endRequest(SUCCESS);	return;      }    if (s[client].wpage == lastVolumePage())      {	/* We reached the end of a linear log */	endRequest(ESIZE);	return;      }    if (offset + len <= PAGE_SIZE)      count = len;    else      count = PAGE_SIZE - offset;    s[client].buf += count;    s[client].wpos += count;    s[client].woffset += count;    len -= count;    /* We normally lose data at the point we make the first write to a       page in a log that has circled. */    if (offset == 0 && s[client].circled)      recordsLost = TRUE;    call At45db.write(s[client].wpage, offset, buf, count);  }    void appendWriteDone() {    if (s[client].woffset == PAGE_SIZE) /* Time to write metadata */      wmetadataStart();    else      endRequest(SUCCESS);  }  void appendMetadataDone() { // metadata of previous page flushed    /* Setup metadata in case we overflow this page too */    metadata.flags = 0;    appendContinue();  }  void appendSyncDone() {    s[client].wpos = metadata.pos + PAGE_SIZE;    appendStart();  }  void appendStart() {    storage_len_t vlen = (storage_len_t)npages() * PAGE_SIZE;    recordsLost = FALSE;    /* If request would span the end of the flash, sync, to maintain the       invariant that the last flash page is synced and that either       the first or last pages are valid.       Note that >= in the if below means we won't write a record that       would end on the last byte of the last page, as this would mean that       we would not sync the last page, breaking the log volume       invariant */    if ((s[client].wpos - PAGE_SIZE) % vlen >= vlen - len)      sync();    else      {	/* Set lastRecordOffset in case we need to write metadata (see	   wmetadataStart) */	metadata.lastRecordOffset = s[client].woffset;	metadata.flags = F_LASTVALID;	appendContinue();      }  }  /* ------------------------------------------------------------------ */  /* Sync								*/  /* ------------------------------------------------------------------ */  void syncStart() {    if (s[client].woffset == 0) /* we can't lose any writes */      endRequest(SUCCESS);    else      sync();  }  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);  }  /* ------------------------------------------------------------------ */  /* Write block metadata						*/  /* ------------------------------------------------------------------ */  void wmetadataStart() {    /* The caller ensures that metadata.flags (except F_CIRCLED) and       metadata.lastRecordOffset are set correctly. */    metaState = META_WRITE;    firstPage = s[client].wpage; // remember page to commit    metadata.pos = s[client].wpos - s[client].woffset;    metadata.magic = PERSISTENT_MAGIC;    if (s[client].circled)      metadata.flags |= F_CIRCLED;    call At45db.computeCrc(firstPage, 0, PAGE_SIZE, 0);    /* We move to the next page now. If writing the metadata fails, we'll       simply leave the invalid page in place. Trying to recover seems       complicated, and of little benefit (note that in practice, At45dbC       shuts down after a failed write, so nothing is really going to       happen after that anyway). */    setWritePage(s[client].wpage + 1);    /* Invalidate read pointer if we reach it's page */    if (s[client].wpage == s[client].rpage)      invalidateReadPointer();  }  void wmetadataCrcDone(uint16_t crc) {    uint8_t i, *md;    // Include metadata in crc    md = (uint8_t *)&metadata;    for (i = 0; i < offsetof(nx_struct pageinfo, crc); i++)      crc = crcByte(crc, md[i]);    metadata.crc = crc;    // And save it    writeMetadata(firstPage);  }  void wmetadataWriteDone() {    metaState = META_IDLE;    if (metadata.flags & F_SYNC)      call At45db.sync(firstPage);    else      call At45db.flush(firstPage);  }  /* ------------------------------------------------------------------ */  /* Read 								*/  /* ------------------------------------------------------------------ */  void readContinue() {    uint8_t *buf = s[client].buf;    at45pageoffset_t offset = s[client].roffset, count;    at45pageoffset_t end = s[client].rend;        if (len == 0)      {	endRequest(SUCCESS);	return;      }    if (!s[client].rvalid)      {	if (s[client].circled)	  /* Find a valid page after wpage, skipping invalid pages */	  s[client].rpage = s[client].wpage;	else	  {	    /* resume reading at the beginning of the first page */	    s[client].rvalid = TRUE;	    s[client].rpage = lastVolumePage() - 1;	  }	rmetadataStart();	return;      }    if (s[client].rpage == s[client].wpage)      end = s[client].woffset;    if (offset == end)      {	if ((s[client].rpage + 1 == lastVolumePage() && !s[client].circular) ||	    s[client].rpage == s[client].wpage)	  endRequest(SUCCESS); // end of log	else	  rmetadataStart();	return;      }    if (offset + len <= end)      count = len;    else      count = end - offset;    s[client].buf += count;    len -= count;    s[client].rpos += count;    s[client].roffset = offset + count;    call At45db.read(s[client].rpage, offset, buf, count);  }  void readStart() {    readContinue();  }  /* ------------------------------------------------------------------ */  /* Read block metadata						*/  /* ------------------------------------------------------------------ */  void continueReadAt(at45pageoffset_t roffset) {    /* Resume reading at firstPage whose metadata is currently available       in the metadata variable */    metaState = META_IDLE;    s[client].rpos = metadata.pos + roffset;    s[client].rpage = firstPage;    s[client].roffset = roffset;    s[client].rend =      metadata.flags & F_SYNC ? metadata.lastRecordOffset : PAGE_SIZE;    s[client].rvalid = TRUE;    readContinue();  }  void rmetadataContinue() {    if (++firstPage == lastVolumePage())      firstPage = firstVolumePage();    if (firstPage == s[client].wpage)      if (!s[client].rvalid)	/* We cannot find a record boundary to start at (we've just	   walked through the whole log...). Give up. */	endRequest(SUCCESS);      else	{	  /* The current write page has no metadata yet, so we fake it */	  metadata.flags = 0;	  metadata.pos = s[client].wpos - s[client].woffset;	  continueReadAt(0);	}    else      readMetadata(firstPage);  }  void rmetadataReadDone() {    if (metadata.magic == PERSISTENT_MAGIC)      crcPage(firstPage);    else      endRequest(SUCCESS);  }  void rmetadataCrcDone(uint16_t crc) {    if (!s[client].rvalid)      if (crc == metadata.crc && metadata.flags & F_LASTVALID)	continueReadAt(metadata.lastRecordOffset);      else	rmetadataContinue();    else       if (crc == metadata.crc)	continueReadAt(0);      else	endRequest(SUCCESS);  }  void rmetadataStart() {    metaState = META_READ;    firstPage = s[client].rpage;    rmetadataContinue();  }  /* ------------------------------------------------------------------ */  /* 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    /* The write positions are offset by PAGE_SIZE (see emptyLog) */    if (offset == SEEK_BEGINNING)      offset = PAGE_SIZE;    if (offset > s[client].wpos || offset < PAGE_SIZE)      {	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) % PAGE_SIZE;    s[client].rpage = firstVolumePage() + ((offset - PAGE_SIZE) / 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);      }    else      {	metaState = META_SEEK;	readMetadata(s[client].rpage);      }  }  /* ------------------------------------------------------------------ */  /* Dispatch HAL operations to current user op				*/  /* ------------------------------------------------------------------ */  event void At45db.eraseDone(error_t error) {    if (client != NO_CLIENT)      if (error != SUCCESS)	endRequest(FAIL);      else	eraseEraseDone();  }  event void At45db.writeDone(error_t error) {    if (client != NO_CLIENT)      if (error != SUCCESS)	endRequest(FAIL);      else	switch (metaState)	  {	  case META_WRITE: wmetadataWriteDone(); break;	  case META_IDLE: appendWriteDone(); break;	  }  }  event void At45db.syncDone(error_t error) {    if (client != NO_CLIENT)      if (error != SUCCESS)	endRequest(FAIL);      else switch (s[client].request)	{	case R_ERASE: eraseMetadataDone(); break;	case R_APPEND: appendSyncDone(); break;	case R_SYNC: syncMetadataDone(); break;	}  }  event void At45db.flushDone(error_t error) {    if (client != NO_CLIENT)      if (error != SUCCESS)	endRequest(FAIL);      else	appendMetadataDone();  }  event void At45db.readDone(error_t error) {    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;	  case META_SEEK: seekReadDone(); break;	  case META_READ: rmetadataReadDone(); break;	  case META_IDLE: readContinue(); break;	  }					      }  event void At45db.computeCrcDone(error_t error, uint16_t crc) {    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;	  case META_SEEK: seekCrcDone(crc); break;	  case META_WRITE: wmetadataCrcDone(crc); break;	  case META_READ: rmetadataCrcDone(crc); break;	  }  }  event void At45db.copyPageDone(error_t error) { }  default event void LogWrite.appendDone[uint8_t logId](void* buf, storage_len_t l, bool rLost, error_t error) { }  default event void LogWrite.eraseDone[uint8_t logId](error_t error) { }  default event void LogWrite.syncDone[uint8_t logId](error_t error) { }  default event void LogRead.readDone[uint8_t logId](void* buf, storage_len_t l, error_t error) { }  default event void LogRead.seekDone[uint8_t logId](error_t error) {}  default command at45page_t At45dbVolume.remap[uint8_t logId](at45page_t volumePage) {return 0;}  default command at45page_t At45dbVolume.volumeSize[uint8_t logId]() {return 0;}  default async command error_t Resource.request[uint8_t logId]() {return SUCCESS;}  default async command error_t Resource.release[uint8_t logId]() { return FAIL; }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -