[Tinyos-2-commits] CVS: tinyos-2.x/tos/chips/at45db
At45dbBlockLog.nc, NONE, 1.1.2.1 ConfigStorageC.nc, NONE,
1.1.2.1 ConfigStorageP.nc, NONE, 1.1.2.1 WireConfigStorageP.nc,
NONE, 1.1.2.1 At45db.nc, 1.1.2.2, 1.1.2.3 At45dbP.nc, 1.1.2.3,
1.1.2.4 BlockStorageP.nc, 1.1.2.7, 1.1.2.8 Storage_chip.h,
1.1.2.4, 1.1.2.5
David Gay
idgay at users.sourceforge.net
Thu May 25 11:23:48 PDT 2006
- Previous message: [Tinyos-2-commits]
CVS: tinyos-2.x/tos/lib/serial SerialAMQueueP.nc, NONE,
1.1.2.1 SerialAMReceiverC.nc, 1.1.2.1,
1.1.2.2 SerialActiveMessageC.nc, 1.1.2.6,
1.1.2.7 SerialActiveMessageP.nc, 1.1.2.9, 1.1.2.10
- Next message: [Tinyos-2-commits] CVS: tinyos-2.x/tos/interfaces ConfigStorage.nc,
NONE, 1.1.2.1
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /cvsroot/tinyos/tinyos-2.x/tos/chips/at45db
In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv9125
Modified Files:
Tag: tinyos-2_0_devel-BRANCH
At45db.nc At45dbP.nc BlockStorageP.nc Storage_chip.h
Added Files:
Tag: tinyos-2_0_devel-BRANCH
At45dbBlockLog.nc ConfigStorageC.nc ConfigStorageP.nc
WireConfigStorageP.nc
Log Message:
config storage (untested), built by hacking block storage
copy-page functionality added to HAL layer
--- NEW FILE: At45dbBlockLog.nc ---
interface At45dbBlockLog {
command void setFlip(bool flip);
command bool flipped();
event bool writeHook();
command void writeContinue(error_t error);
command at45page_t npages();
command at45page_t remap(at45page_t page);
}
--- NEW FILE: ConfigStorageC.nc ---
// $Id: ConfigStorageC.nc,v 1.1.2.1 2006/05/25 18:23:46 idgay Exp $
/*
* Copyright (c) 2005-2006 Intel Corporation
* All rights reserved.
*
* This file is distributed under the terms in the attached INTEL-LICENSE
* file. If you do not find these files, copies can be found by writing to
* Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA,
* 94704. Attention: Intel License Inquiry.
*/
/**
* Implementation of the config storage abstraction from TEP103 for the
* Atmel AT45DB serial data flash.
*
* @author David Gay
*/
#include "Storage.h"
generic configuration ConfigStorageC(volume_id_t volid) {
provides {
interface SplitControl;
interface ConfigStorage;
}
}
implementation {
enum {
CONFIG_ID = unique(UQ_CONFIG_STORAGE),
BLOCK_ID = uniqueCount(UQ_BLOCK_STORAGE) + CONFIG_ID,
RESOURCE_ID = unique(UQ_AT45DB)
};
components ConfigStorageP, WireConfigStorageP, StorageManagerP, At45dbC;
components BlockStorageP, WireBlockStorageP;
SplitControl = ConfigStorageP.SplitControl[CONFIG_ID];
ConfigStorage = ConfigStorageP.ConfigStorage[CONFIG_ID];
ConfigStorageP.BlockRead[CONFIG_ID] -> BlockStorageP.BlockRead[BLOCK_ID];
ConfigStorageP.BlockWrite[CONFIG_ID] -> BlockStorageP.BlockWrite[BLOCK_ID];
ConfigStorageP.BLog[CONFIG_ID] -> BlockStorageP.BLog[BLOCK_ID];
BlockStorageP.At45dbVolume[BLOCK_ID] -> StorageManagerP.At45dbVolume[volid];
BlockStorageP.Resource[BLOCK_ID] -> At45dbC.Resource[RESOURCE_ID];
}
--- NEW FILE: ConfigStorageP.nc ---
// $Id: ConfigStorageP.nc,v 1.1.2.1 2006/05/25 18:23:46 idgay Exp $
/* tab:4
* Copyright (c) 2002-2006 Intel Corporation
* All rights reserved.
*
* This file is distributed under the terms in the attached INTEL-LICENSE
* file. If you do not find these files, copies can be found by writing to
* Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA,
* 94704. Attention: Intel License Inquiry.
*/
/**
* Private component of the AT45DB implementation of the config storage
* abstraction.
*
* @author: David Gay <dgay at acm.org>
*/
#include "Storage.h"
module ConfigStorageP {
provides {
interface SplitControl[configstorage_t id];
interface ConfigStorage[configstorage_t id];
}
uses {
interface At45db;
interface At45dbBlockLog as BLog[configstorage_t id];
interface BlockRead[configstorage_t id];
interface BlockWrite[configstorage_t id];
}
}
implementation
{
/* A config storage is built on top of a block storage volume, with
the block storage volume divided into two and the first 4 bytes of
each half holding a (>0) version number. The valid half with the
highest version number is the current version.
Transactional behaviour is achieved by copying the current half
into the other, then increment its version number. Writes then
proceed in that new half until a commit, which just uses the
underlying BlockStorage commit's operation.
Note: all of this depends on the ay45db's implementation of
BlockStorageP. It will not work over an arbitrary BlockStorageP
implementation (additionally, it uses hooks in BlockStorageP to
support the half-volume operation).
*/
enum {
S_STOPPED,
S_STOP,
S_MOUNT,
S_CLEAN,
S_DIRTY,
};
enum {
N = uniqueCount(UQ_LOG_STORAGE),
NO_CLIENT = 0xff,
};
uint8_t state[N];
uint32_t lowVersion[N], highVersion[N];
uint8_t client = NO_CLIENT;
at45page_t nextPage;
command error_t SplitControl.start[uint8_t id]() {
/* 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;
call BLog.setFlip(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 SplitControl.startDone(FAIL);
}
else if (!call BLog.flipped[id]())
{
call BLog.setFlip(TRUE);
call BlockRead.read[id](0, &highVersion[id], sizeof highVersion[id]);
}
else
{
call BLog.setFlip[id](highVersion[id] > lowVersion[id]);
call BlockRead.verify[id]();
}
}
void mountVerifyDone(uint8_t id, error_t error) {
if (error != SUCCESS) // try the other half?
{
bool flipped = call BLog.flipped[id]();
if ((highVersion[id] > lowVersion[id]) == flipped)
{
call BLog.setFlip[id](!flipped);
call BLog.verify[id]();
return;
}
/* both halves bad, just declare success and use the current half :-)
(we did need to verify to find the end-of-block) */
}
state[id] = S_CLEAN;
signal SplitControl.startDone(SUCCESS);
}
command error_t SplitControl.stop[uint8_t id]() {
return FAIL;
}
command error_t ConfigStorage.read[configstorage_t id](storage_addr_t addr, void* buf, storage_len_t len) {
/* Read from current half using BlockRead */
if (!(state[id] == S_CLEAN || state[id] == S_DIRTY))
return FAIL;
return call BlockRead.read[id](addr + sizeof(uint32_t), buf, len);
}
command error_t ConfigStorage.write[configstorage_t id](storage_addr_t addr, void* buf, storage_len_t len) {
/* 1: If first write:
copy to other half, increment version number, and flip.
2: Write to current half using BlockWrite */
if (!(state[id] == S_CLEAN || state[id] == S_DIRTY))
return FAIL;
return call BlockWrite.write(addr + sizeof(uint32_t), buf, len);
}
void copyCopyPageDone(error_t error);
void writeContinue(error_t error);
event bool BLog.writeHook[configstorage_t id]() {
if (state[id] == S_DIRTY) // no work if already dirty
return FALSE;
/* Time to do the copy, version update dance */
client = id;
nextPage = call BLog.npages[id]();
copyCopyPageDone(SUCCESS);
}
void copyCopyPageDone(error_t error) {
if (error != SUCCESS)
writeContinue(error);
else if (nextPage == 0) // copy done
{
uint32_t *version;
// Set version number
if (call BLog.flipped[client]())
{
lowVersion[client] = highVersion[client] + 1;
version = &lowVersion[client];
}
else
{
highVersion[client] = lowVersion[client] + 1;
version = &highVersion[client];
}
call At45db.write(call BLog.remap[client](0), 0,
version, sizeof *version);
}
else
{
at45page_t from = --nextPage, to = nextPage;
if (call BLog.flipped[client]())
from += npages();
else
to += npages();
call At45db.copyPage(from, to);
}
}
void copyWriteDone(error_t error) {
if (error == SUCCESS)
{
call BLog.setFlip[client](!call BLog.flipped[client]);
state[client] = S_DIRTY;
}
writeContinue(error);
}
void writeContinue(error_t error) {
uint8_t id = client;
client = NO_CLIENT;
signal BLog.writeContinue[id]();
}
command error_t ConfigStorage.commit[configstorage_t id]() {
/* Call BlockWrite.commit */
/* Could special-case attempt to commit clean log */
return call BlockWrite[id].commit();
}
void commitDone(configstorage_t id, error_t error) {
if (error == SUCCESS)
state[id] = S_CLEAN;
signal ConfigStorage.commitDone[id](error);
}
event void BlockRead.readDone[configstorage_t id](storage_addr_t addr, void* buf, storage_len_t len, error_t error) {
if (state[id] == S_MOUNT)
mountReadDone(id, error);
else
signal ConfigStorage.readDone[id](addr - sizeof(uint32_t), buf, len, error);
}
event void BlockRead.verifyDone[configstorage_t id]( error_t error ) {
mountVerifyDone(id, error);
}
event void BlockWrite.writeDone[configstorage_t id]( storage_addr_t addr, void* buf, storage_len_t len, error_t error ) {
signal ConfigStorage.writeDone(addr - sizeof(uint32_t), buf, len, error);
}
}
event void BlockWrite.commitDone[configstorage_t id]( error_t error ) {
commitDone(id, error);
}
event void At45db.writeDone(error_t error) {
if (client != NO_CLIENT)
copyWriteDone(error);
}
event void At45db.copyPageDone(error_t error) {
if (client != NO_CLIENT)
copyCopyPageDone(error);
}
event void BlockRead.computeCrcDone[configstorage_t id]( storage_addr_t addr, storage_len_t len, uint16_t crc, error_t error ) {}
event void BlockWrite.eraseDone[configstorage_t id]( error_t error ) {}
event void At45db.eraseDone(error_t error) {}
event void At45db.syncDone(error_t error) {}
event void At45db.flushDone(error_t error) {}
event void At45db.readDone(error_t error) {}
event void At45db.computeCrcDone(error_t error, uint16_t crc) {}
}
--- NEW FILE: WireConfigStorageP.nc ---
/*
* Copyright (c) 2005-2006 Intel Corporation
* All rights reserved.
*
* This file is distributed under the terms in the attached INTEL-LICENSE
* file. If you do not find these files, copies can be found by writing to
* Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA,
* 94704. Attention: Intel License Inquiry.
*/
/**
* Private component of the AT45DB implementation of the config storage
* abstraction.
*
* @author: David Gay <dgay at acm.org>
*/
configuration WireConfigStorageP { }
implementation {
components ConfigStorageP, At45dbC;
ConfigStorageP.At45db -> At45dbC;
}
Index: At45db.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/chips/at45db/Attic/At45db.nc,v
retrieving revision 1.1.2.2
retrieving revision 1.1.2.3
diff -C2 -d -r1.1.2.2 -r1.1.2.3
*** At45db.nc 26 Jan 2006 21:11:40 -0000 1.1.2.2
--- At45db.nc 25 May 2006 18:23:45 -0000 1.1.2.3
***************
*** 70,73 ****
--- 70,89 ----
/**
+ * Copy one flash page to another. copyDone will be signaled. If page
+ * from had been modified, it is first flushed to flash. Page
+ * <code>to</code> will only actually be written when the buffer holding
+ * it is flushed (see flush, flushAll, sync, syncAll).
+ *
+ * @param from Flash page to copy. Must be less than AT45_MAX_PAGES.
+ * @param to Flash page to overwrite. Must be less than AT45_MAX_PAGES.
+ */
+ command void copyPage(at45page_t from, at45page_t to);
+ /**
+ * Signal completion of a copyPage operation.
+ * @param error SUCCESS if the copy was successful, FAIL otherwise
+ */
+ event void copyPageDone(error_t error);
+
+ /**
* Erase an AT45DB page. eraseDone will be signaled.
* @param page Flash page to erase. Must be less than AT45_MAX_PAGES.
Index: At45dbP.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/chips/at45db/Attic/At45dbP.nc,v
retrieving revision 1.1.2.3
retrieving revision 1.1.2.4
diff -C2 -d -r1.1.2.3 -r1.1.2.4
*** At45dbP.nc 17 Feb 2006 22:05:06 -0000 1.1.2.3
--- At45dbP.nc 25 May 2006 18:23:46 -0000 1.1.2.4
***************
*** 73,76 ****
--- 73,77 ----
R_WRITE,
R_ERASE,
+ R_COPY,
R_SYNC,
R_SYNCALL,
***************
*** 268,271 ****
--- 269,285 ----
break;
+ case R_COPY:
+ if (!buffer[selected].clean) // flush any modifications
+ flushBuffer();
+ else
+ {
+ // Just redesignate as destination page, and mark it dirty.
+ // It will eventually be flushed, completing the copy.
+ buffer[selected].page = reqOffset;
+ buffer[selected].clean = FALSE;
+ post taskSuccess();
+ }
+ break;
+
case R_SYNC: case R_SYNCALL:
if (buffer[selected].clean && buffer[selected].unchecked)
***************
*** 349,355 ****
}
! void newRequest(uint8_t req, at45page_t page,
! at45pageoffset_t offset,
! void *reqdata, at45pageoffset_t n) {
request = req;
--- 363,368 ----
}
! void newRequest(uint8_t req, at45page_t page, at45pageoffset_t offset,
! void *reqdata, at45pageoffset_t n) {
request = req;
***************
*** 399,402 ****
--- 412,420 ----
}
+ command void At45db.copyPage(at45page_t from, at45page_t to) {
+ /* Assumes at45pageoffset_t can hold an at45page_t. A little icky */
+ newRequest(R_COPY, from, to, NULL, 0);
+ }
+
void syncOrFlush(at45page_t page, uint8_t newReq) {
request = newReq;
Index: BlockStorageP.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/chips/at45db/Attic/BlockStorageP.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
*** BlockStorageP.nc 16 Feb 2006 22:21:32 -0000 1.1.2.7
--- BlockStorageP.nc 25 May 2006 18:23:46 -0000 1.1.2.8
***************
*** 44,47 ****
--- 44,48 ----
interface BlockWrite[blockstorage_t blockId];
interface BlockRead[blockstorage_t blockId];
+ interface At45dbBlockLog as BLog[blockstorage_t blockId];
}
uses {
***************
*** 64,68 ****
enum {
! N = uniqueCount(UQ_BLOCK_STORAGE),
NO_CLIENT = 0xff
};
--- 65,69 ----
enum {
! N = uniqueCount(UQ_BLOCK_STORAGE) + uniqueCount(UQ_LOG_STORAGE),
NO_CLIENT = 0xff
};
***************
*** 74,77 ****
--- 75,79 ----
/* The requests */
uint8_t state[N]; /* automatically initialised to S_IDLE */
+ uint8_t flipped[N / 8];
uint8_t *bufPtr[N];
storage_addr_t curAddr[N];
***************
*** 81,84 ****
--- 83,115 ----
uint8_t sig[8];
+ inline int logClient(blockstorage_t id) {
+ return id >= uniqueCount(UQ_BLOCK_STORAGE);
+ }
+
+ at45page_t pageRemap(at45page_t p) {
+ return call BLog.remap[client](p);
+ }
+
+ command at45page_t BLog.npages[blockstorage_t id]() {
+ return call At45dbVolume.volumeSize[id]() >> (AT45_PAGE_SIZE_LOG2 + 1);
+ }
+
+ command at45page_t BLog.remap[blockstorage_t id](at45page_t page) {
+ if (logClient(id) && call BLog.flipped[id]())
+ page += call At45dbVolume.volumeSize[id]() >> (AT45_PAGE_SIZE_LOG2 + 1);
+ return call At45dbVolume.remap[id](page);
+ }
+
+ command void BLog.setFlip[blockstorage_t blockId](bool flip) {
+ if (flip)
+ flipped[blockId >> 3] |= 1 << (blockId & 7);
+ else
+ flipped[blockId >> 3] &= ~(1 << (blockId & 7));
+ }
+
+ inline command bool BLog.flipped[blockstorage_t blockId]() {
+ return (flipped[blockId >> 3] & (1 << (blockId & 7))) != 0;
+ }
+
void verifySignature();
void commitSignature();
***************
*** 110,114 ****
bytesRemaining = requestedLength[client];
crc = 0;
! continueRequest();
}
--- 141,166 ----
bytesRemaining = requestedLength[client];
crc = 0;
!
! if (logClient(blockId) && state[blockId] == S_WRITE &&
! signal BLog.writeHook[blockId]())
! /* Log write intercept. We'll get a writeContinue when it's
! time to resume. */
! client = NO_CLIENT;
! else
! continueRequest();
! }
!
! default event bool BLog.writeHook[blockstorage_t blockId]() {
! return FALSE;
! }
!
! void signalDone(error_t result);
!
! command void BLog.writeContinue[blockstorage_t blockId](error_t error) {
! client = blockId;
! if (error == SUCCESS)
! continueRequest();
! else
! signalDone(error);
}
***************
*** 172,176 ****
void calcRequest(storage_addr_t addr, at45page_t *page,
at45pageoffset_t *offset, at45pageoffset_t *count) {
! *page = call At45dbVolume.remap[client](addr >> AT45_PAGE_SIZE_LOG2);
*offset = addr & ((1 << AT45_PAGE_SIZE_LOG2) - 1);
if (bytesRemaining < (1 << AT45_PAGE_SIZE_LOG2) - *offset)
--- 224,228 ----
void calcRequest(storage_addr_t addr, at45page_t *page,
at45pageoffset_t *offset, at45pageoffset_t *count) {
! *page = pageRemap(addr >> AT45_PAGE_SIZE_LOG2);
*offset = addr & ((1 << AT45_PAGE_SIZE_LOG2) - 1);
if (bytesRemaining < (1 << AT45_PAGE_SIZE_LOG2) - *offset)
***************
*** 178,181 ****
--- 230,234 ----
else
*count = (1 << AT45_PAGE_SIZE_LOG2) - *offset;
+
}
***************
*** 240,245 ****
/* Note: bytesRemaining is 0, so multipageDone will go straight to
signalDone */
! call At45db.write(call At45dbVolume.remap[client](0),
! 1 << AT45_PAGE_SIZE_LOG2, sig, sizeof sig);
}
--- 293,297 ----
/* Note: bytesRemaining is 0, so multipageDone will go straight to
signalDone */
! call At45db.write(pageRemap(0), 1 << AT45_PAGE_SIZE_LOG2, sig, sizeof sig);
}
***************
*** 310,315 ****
}
! event void At45db.flushDone(error_t result) {
! }
default event void BlockWrite.writeDone[uint8_t id](storage_addr_t addr, void* buf, storage_len_t len, error_t result) { }
--- 362,368 ----
}
! event void At45db.flushDone(error_t result) { }
!
! event void At45db.copyPageDone(error_t error) { }
default event void BlockWrite.writeDone[uint8_t id](storage_addr_t addr, void* buf, storage_len_t len, error_t result) { }
Index: Storage_chip.h
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/chips/at45db/Attic/Storage_chip.h,v
retrieving revision 1.1.2.4
retrieving revision 1.1.2.5
diff -C2 -d -r1.1.2.4 -r1.1.2.5
*** Storage_chip.h 23 May 2006 21:57:04 -0000 1.1.2.4
--- Storage_chip.h 25 May 2006 18:23:46 -0000 1.1.2.5
***************
*** 12,14 ****
--- 12,17 ----
typedef uint8_t logstorage_t;
+ #define UQ_CONFIG_STORAGE "ConfigStorageP.ConfigRead"
+ typedef uint8_t configstorage_t;
+
#endif
- Previous message: [Tinyos-2-commits]
CVS: tinyos-2.x/tos/lib/serial SerialAMQueueP.nc, NONE,
1.1.2.1 SerialAMReceiverC.nc, 1.1.2.1,
1.1.2.2 SerialActiveMessageC.nc, 1.1.2.6,
1.1.2.7 SerialActiveMessageP.nc, 1.1.2.9, 1.1.2.10
- Next message: [Tinyos-2-commits] CVS: tinyos-2.x/tos/interfaces ConfigStorage.nc,
NONE, 1.1.2.1
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the Tinyos-2-commits
mailing list