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

📄 p30logp.nc

📁 tinyos2.0版本驱动
💻 NC
📖 第 1 页 / 共 2 页
字号:
  }  /*   * Invariant should be that everytime after an append completes,   * nextFreeRecord should point to a valid free record slot. Uses   * nextFreeRecord to append.   */  command error_t Write.append[ storage_volume_t block ](void* buf, storage_len_t len) {    record_meta_t recordMeta;    myMount(block);        // error check    if(len > L_RECORD_DATA_SIZE)      return EINVAL;    // if non circular log, fail    if((!call Circular.get[block]()) &&       (lastBlock[block] == (L_PARTITIONS(block) - 1)) &&       (nextFreeRecord[block] == (L_MAX_RECORDS_PER_BLOCK - 1)))      return FAIL;    m_state = S_APPEND;    clientId = block;    clientBuf = buf;    clientLen = len;    // if you try to log 0, just immediately succeed, this really shouldn't happen    if(len == 0) {      clientResult = SUCCESS;      post signalDoneTask();      return SUCCESS;    }    // if readCookie was on SEEK_EOL, adjust it back to here    if(readCookieOffset[block] == SEEK_EOL)      readCookieOffset[block] = L_RAW_OFFSET(block, lastBlock[block], nextFreeRecord[block]) + sizeof(record_meta_t);          // use next free record, write the INVALID, write the data, write the VALID    recordMeta.status = RECORD_INVALID;    recordMeta.length = len;    call Flash.write(L_RAW_OFFSET(block, lastBlock[block], nextFreeRecord[block]),		     (uint8_t*) &recordMeta,		     sizeof(record_meta_t));    call Flash.write(L_RAW_OFFSET(block, lastBlock[block], nextFreeRecord[block]) +		     sizeof(record_meta_t),		     (uint8_t*) buf, len);    recordMeta.status = RECORD_VALID;    call Flash.write(L_RAW_OFFSET(block, lastBlock[block], nextFreeRecord[block]),		     (uint8_t*) &recordMeta,		     sizeof(record_meta_t));    nextFreeRecord[block]++;    // see if you need to adjust blocks or shuffle    if(nextFreeRecord[block] == L_MAX_RECORDS_PER_BLOCK)      shuffleBlocks(block);    clientResult = SUCCESS;    post signalDoneTask();        return SUCCESS;  }  /*   * We use nextFreeRecord to get the cookie   */  command storage_cookie_t Write.currentOffset[ storage_volume_t block ]() {    myMount(block);    return L_RAW_OFFSET(block, lastBlock[block], nextFreeRecord[block]) +      sizeof(record_meta_t);  }  /*   * First we erase all the log data blocks so that they can be   * reused. Then we zero the cookies and then write them to our   * partitions like the append operation. If we crash in the middle,   * you may have to erase again. However, if an erase does fail, at   * least all your data will still be there, so that you can try   * again.   */  command error_t Write.erase[storage_volume_t block]() {    uint32_t i;    for(i = 0; i < L_PARTITIONS(block); i++) {      call Flash.erase(L_BASE_BLOCK(block) + (i * P30_BLOCK_SIZE));    }    mountBits[block] = 0;    myMount(block);    // ... starting block implicitly written by mount    m_state = S_ERASE;    clientId = block;    clientResult = SUCCESS;    post signalDoneTask();    return SUCCESS;  }  /*   * Sync does nothing really because unlike the AT45DB, Intel P30   * writes directly through.   */  command error_t Write.sync[storage_volume_t block]() {    myMount(block);    m_state = S_SYNC;        clientId = block;    clientResult = SUCCESS;        post signalDoneTask();    return SUCCESS;  }  /*   * Sanity check the read cookie and adjust for any other special   * cookies. Because you can seek to the byte, must it is saved in   * flash as records, you have to do a lot of tricky seeking, but   * it's done here. Also has to handle any pages that are spilled   * over.   */  command error_t Read.read[ storage_volume_t block ](void* buf, storage_len_t len) {    record_meta_t recordMeta;    uint32_t recordCounter;    uint32_t pageCounter;    uint32_t offset;    clientId = block;    clientBuf = buf;    clientResult = SUCCESS;    myMount(block);    m_state = S_READ;        if(len == 0 || readCookieOffset[block] == SEEK_EOL) {      clientResult = SUCCESS;      clientLen = 0;      post signalDoneTask();      return SUCCESS;    }        // adjust SEEK_BEGINNING to a real offset    if(readCookieOffset[block] == SEEK_BEGINNING) {      readCookieOffset[block] = L_RAW_OFFSET(block, firstBlock[block], 1) +	sizeof(record_meta_t);    }        // convert the cookie to something useful    cookieToTuple(readCookieOffset[block], block, &pageCounter, &recordCounter, &offset);    // sanity check readCookie    call Flash.read(L_RAW_OFFSET(block, pageCounter, recordCounter),		    (uint8_t*) &recordMeta,		    sizeof(record_meta_t));    if((recordMeta.status == RECORD_VALID) && (offset > len)) {      readCookieOffset[block] = L_RAW_OFFSET(block, firstBlock[block], 0) + sizeof(record_meta_t);      cookieToTuple(readCookieOffset[block], block, &pageCounter, &recordCounter, &offset);    }    clientLen = 0; // reset how much actually read and count up        while(len != 0) {      call Flash.read(L_RAW_OFFSET(block, pageCounter, recordCounter),		      (uint8_t*) &recordMeta,		      sizeof(record_meta_t));      if(recordMeta.status == RECORD_INVALID) {	goto advance_counter;      }      if(recordMeta.status == RECORD_EMPTY) {	readCookieOffset[block] = SEEK_EOL;	post signalDoneTask();	return SUCCESS;      }      // read partial block and finish      if(len < recordMeta.length + offset) {	call Flash.read(L_RAW_OFFSET(block, pageCounter, recordCounter) +			offset + sizeof(record_meta_t),			buf,			len);	offset = len;	buf = buf + len;	len = 0;      }      else {	call Flash.read(L_RAW_OFFSET(block, pageCounter, recordCounter) + 			offset + sizeof(record_meta_t),			buf,			recordMeta.length - offset);	clientLen = clientLen + recordMeta.length - offset;	len -= recordMeta.length - offset;	buf = buf + recordMeta.length - offset;	offset = 0;            advance_counter:	recordCounter++;	if((recordCounter >= L_MAX_RECORDS_PER_BLOCK) && (pageCounter == lastBlock[block])) {	  readCookieOffset[block] = SEEK_EOL;	  post signalDoneTask();	  return SUCCESS;	}	// need to adjust page possibly if spills	// also need to check if reached end of log (lastBlock[block] or RECORD_AVAILABLE)	if(recordCounter >= L_MAX_RECORDS_PER_BLOCK) {	  pageCounter = (pageCounter + 1) % L_PARTITIONS(block);	  recordCounter = 1;	}      }    }    readCookieOffset[block] = L_RAW_OFFSET(block, pageCounter, recordCounter) +      sizeof(record_meta_t) + offset;    post signalDoneTask();    return SUCCESS;  }      command storage_cookie_t Read.currentOffset[ storage_volume_t block ]() {    myMount(block);    return readCookieOffset[block];  }  /*   * Just set the cookie. If you seek into an invalid area, just set   * it at SEEK_BEGINNING.   */  command error_t Read.seek[ storage_volume_t block ](storage_cookie_t offset) {    uint32_t page;    uint32_t record;    uint32_t recordOffset;    record_meta_t recordMeta;    myMount(block);    clientId = block;    clientResult = SUCCESS;    m_state = S_SEEK;    readCookieOffset[block] = offset;    post signalDoneTask();              return SUCCESS;  }  /*   * Go through all the pages, if it's a free page, count whatever is   * available left. Add them all up.   */  command storage_len_t Read.getSize[ storage_volume_t block ]() {    storage_len_t len = 0;    uint32_t i;    uint32_t j;    page_meta_t pageMeta;    record_meta_t recordMeta;        myMount(block);        for(i = 0; i < L_PARTITIONS(block); i++) {      call Flash.read(L_RAW_OFFSET(block, i, j),		      (uint8_t*) &pageMeta,		      sizeof(page_meta_t));      if(pageMeta.header != PAGE_AVAILABLE) {	len = len + (sizeof(record_data_t) * L_MAX_RECORDS_PER_BLOCK);	continue;      }      for(j = 1; j < L_MAX_RECORDS_PER_BLOCK; j++) {	call Flash.read(L_RAW_OFFSET(block, i, j),			(uint8_t*) &recordMeta,			sizeof(record_meta_t));	if(recordMeta.status == RECORD_EMPTY) {	  len = len + ((L_MAX_RECORDS_PER_BLOCK - j) * sizeof(record_meta_t));	  break;	}      }    }        return len;  }  default event void Read.readDone[ storage_volume_t block ](void* buf, storage_len_t len, error_t error) {}  default event void Read.seekDone[ storage_volume_t block ](error_t error) {}  default event void Write.appendDone[ storage_volume_t block ](void* buf, storage_len_t len, bool recordsLost, error_t error) {}  default event void Write.eraseDone[ storage_volume_t block ](error_t error) {}  default event void Write.syncDone[ storage_volume_t block ](error_t error) {}  default command bool Circular.get[ uint8_t id ]() { return FALSE; }}

⌨️ 快捷键说明

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