[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