[Tinyos-beta-commits] CVS: tinyos-1.x/beta/Deluge/Deluge
BitVecUtils.h, NONE, 1.1 BitVecUtils.nc, NONE,
1.1 BitVecUtilsC.nc, NONE, 1.1 Deluge.h, NONE, 1.1 DelugeC.nc,
NONE, 1.1 DelugeDataRead.nc, NONE, 1.1 DelugeDataWrite.nc,
NONE, 1.1 DelugeImgDescStorage.nc, NONE, 1.1 DelugeM.nc, NONE,
1.1 DelugeMetadata.h, NONE, 1.1 DelugeMetadata.nc, NONE,
1.1 DelugeMetadataC.nc, NONE, 1.1 DelugeMetadataM.nc, NONE,
1.1 DelugeMetadataRead.nc, NONE, 1.1 DelugeMetadataWrite.nc,
NONE, 1.1 DelugeMsgs.h, NONE, 1.1 DelugePageTransfer.h, NONE,
1.1 DelugePageTransfer.nc, NONE, 1.1 DelugePageTransferC.nc,
NONE, 1.1 DelugePageTransferM.nc, NONE, 1.1 DelugeStorage.nc,
NONE, 1.1 DelugeStorageC.nc, NONE, 1.1 DelugeStorageM.nc, NONE,
1.1 NetProg.h, NONE, 1.1 NetProg.nc, NONE, 1.1 NetProgC.nc,
NONE, 1.1 NetProgM.nc, NONE, 1.1 SharedMsgBuf.nc, NONE,
1.1 SharedMsgBufM.nc, NONE, 1.1
Jonathan Hui
jwhui at users.sourceforge.net
Sun Nov 21 21:31:00 PST 2004
- Previous message: [Tinyos-beta-commits]
CVS: tinyos-1.x/beta/Deluge/Deluge/TOSBoot/build/telosb
app.c, NONE, 1.1 ident_flags.txt, NONE, 1.1 main.exe, NONE,
1.1 main.ihex, NONE, 1.1
- Next message: [Tinyos-beta-commits]
CVS: tinyos-1.x/beta/Deluge/TestDeluge/DelugeBasic
DelugeBasic.nc, NONE, 1.1 Makefile, NONE, 1.1
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /cvsroot/tinyos/tinyos-1.x/beta/Deluge/Deluge
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv13752/Deluge
Added Files:
BitVecUtils.h BitVecUtils.nc BitVecUtilsC.nc Deluge.h
DelugeC.nc DelugeDataRead.nc DelugeDataWrite.nc
DelugeImgDescStorage.nc DelugeM.nc DelugeMetadata.h
DelugeMetadata.nc DelugeMetadataC.nc DelugeMetadataM.nc
DelugeMetadataRead.nc DelugeMetadataWrite.nc DelugeMsgs.h
DelugePageTransfer.h DelugePageTransfer.nc
DelugePageTransferC.nc DelugePageTransferM.nc DelugeStorage.nc
DelugeStorageC.nc DelugeStorageM.nc NetProg.h NetProg.nc
NetProgC.nc NetProgM.nc SharedMsgBuf.nc SharedMsgBufM.nc
Log Message:
- Initial checkin of Deluge v2.0.
- New features:
- Support for hardware write protect of external flash chip.
- Ping results include information obtained from Ident.h.
- CRCs are no longer inlined with program data, thus allowing for
DMA transfers from external flash to program flash.
- Version number information included in Deluge packets to prevent
nodes with different versions of Deluge from conflicts.
- Support for TinyOS 2.x hardware independent storage abstraction.
- Metadata data-structures include CRCs generated by the host PC
to help guard against corruption.
- TOSBoot bootloader now written in nesC.
- Reduced RAM and ROM requirements.
- Other minor enhancements that I can't think of right now.
- Major user differences:
- Golden image is now slot 0. While it cannot be written to, the user
can retrieve Ident.h information about the golden image.
- When specifying an image for download, the user specifies the
build/<platform> directory rather than just the ihex file. The issue
is that it is very difficult to pull out the Ident.h information
without compile-time output.
- Known issues:
- Does not support more than 1 downloadable image (actually, it might,
but I haven't tested it yet).
- To setup the Deluge tools, create the directory net/tinyos/deluge
and copy all files in 'delugetools' into it.
- Operation is very similar to Deluge v1.0.
Ping:
$ java net.tinyos.deluge.Deluge -p
Download:
$ java net.tinyos.deluge.Deluge -i -if <builddir> -in <imagenum>
Reboot:
$ java net.tinyos.deluge.Deluge -r -in <imagenum>
--- NEW FILE: BitVecUtils.h ---
// $Id: BitVecUtils.h,v 1.1 2004/11/22 05:30:57 jwhui Exp $
/* tab:4
*
*
* "Copyright (c) 2000-2004 The Regents of the University of California.
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
* CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
*
*/
/**
* Provides generic methods for manipulating bit vectors.
*
* @author Jonathan Hui <jwhui at cs.berkeley.edu>
*/
#ifndef __BITVEC_UTILS_H__
#define __BITVEC_UTILS_H__
#define BIT_GET(x, i) ((x) & (1 << (i)))
#define BIT_SET(x, i) ((x) | (1 << (i)))
#define BIT_CLEAR(x, i) ((x) & ~(1 << (i)))
#define BITVEC_GET(x, i) (BIT_GET((x)[(i)/8], (i)%8))
#define BITVEC_SET(x, i) ((x)[(i)/8] = BIT_SET((x)[(i)/8], (i)%8))
#define BITVEC_CLEAR(x, i) ((x)[(i)/8] = BIT_CLEAR((x)[(i)/8], (i)%8))
#endif
--- NEW FILE: BitVecUtils.nc ---
// $Id: BitVecUtils.nc,v 1.1 2004/11/22 05:30:57 jwhui Exp $
/* tab:4
*
*
* "Copyright (c) 2000-2004 The Regents of the University of California.
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
* CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
*
*/
/**
* Provides generic methods for manipulating bit vectors.
*
* @author Jonathan Hui <jwhui at cs.berkeley.edu>
*/
interface BitVecUtils {
/**
* Locates the index of the first '1' bit in a bit vector.
*
* @param result the location of the '1' bit
* @param fromIndex the index to start search for '1' bit
* @param bitVec the bit vector
* @param length the length of the bit vector in bits
* @return <code>SUCCESS</code> if a '1' bit was found;
* <code>FAIL</code> otherwise.
*/
command result_t indexOf(uint16_t* pResult, uint16_t fromIndex,
uint8_t* bitVec, uint16_t length);
/**
* Counts the number of '1' bits in a bit vector.
*
* @param result the number of '1' bits
* @param bitVec the bit vector
* @param length the length of the bit vector in bits
* @return <code>SUCCESS</code> if the operation completed successfully;
* <code>FAIL</code> otherwise.
*/
command result_t countOnes(uint16_t* pResult, uint8_t* bitVec,
uint16_t length);
/**
* Generates an ASCII representation of the bit vector.
*
* @param buf the character array to place the ASCII string
* @param bitVec the bit vector
* @param length the length of the bit vector in bits
*/
command void printBitVec(char* buf, uint8_t* bitVec, uint16_t length);
}
--- NEW FILE: BitVecUtilsC.nc ---
// $Id: BitVecUtilsC.nc,v 1.1 2004/11/22 05:30:57 jwhui Exp $
/* tab:4
*
*
* "Copyright (c) 2000-2004 The Regents of the University of California.
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
* CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
*
*/
/**
* Provides generic methods for manipulating bit vectors.
*
* @author Jonathan Hui <jwhui at cs.berkeley.edu>
*/
includes BitVecUtils;
module BitVecUtilsC {
provides interface BitVecUtils;
}
implementation {
command result_t BitVecUtils.indexOf(uint16_t* pResult, uint16_t fromIndex,
uint8_t* bitVec, uint16_t length) {
uint16_t i = fromIndex;
if (length == 0)
return FAIL;
do {
if (BITVEC_GET(bitVec, i)) {
*pResult = i;
return SUCCESS;
}
i = (i+1) % length;
} while (i != fromIndex);
return FAIL;
}
command result_t BitVecUtils.countOnes(uint16_t* pResult, uint8_t* bitVec, uint16_t length) {
int count = 0;
int i;
for ( i = 0; i < length; i++ ) {
if (BITVEC_GET(bitVec, i))
count++;
}
*pResult = count;
return SUCCESS;
}
command void BitVecUtils.printBitVec(char* buf, uint8_t* bitVec, uint16_t length) {
#ifdef PLATFORM_PC
uint16_t i;
dbg(DBG_TEMP, "");
for ( i = 0; i < length; i++ ) {
sprintf(buf++, "%d", !!BITVEC_GET(bitVec, i));
}
#endif
}
}
--- NEW FILE: Deluge.h ---
#ifndef __DELUGE_H__
#define __DELUGE_H__
#include "DelugeMetadata.h"
enum {
DELUGE_VERSION = 2,
DELUGE_NUM_IMAGES = 2,
DELUGE_MIN_ADV_PERIOD_LOG2 = 9,
DELUGE_MAX_ADV_PERIOD_LOG2 = 20,
DELUGE_NUM_NEWDATA_ADVS_REQUIRED = 2,
DELUGE_NUM_MIN_ADV_PERIODS = 2,
DELUGE_MAX_NUM_REQ_TRIES = 1,
DELUGE_REBOOT_DELAY = 4,
DELUGE_FAILED_SEND_DELAY = 16,
DELUGE_MIN_DELAY = 16,
DELUGE_MAX_REQ_DELAY = (0x1 << (DELUGE_MIN_ADV_PERIOD_LOG2-1)),
DELUGE_NACK_TIMEOUT = (DELUGE_MAX_REQ_DELAY >> 0x1),
DELUGE_MAX_IMAGE_SIZE = ((uint32_t)128*(uint32_t)1024),
DELUGE_PAGE_SIZE = 1024,
DELUGE_MAX_PAGES = DELUGE_MAX_IMAGE_SIZE/DELUGE_PAGE_SIZE,
DELUGE_CRC_SIZE = 2,
DELUGE_CRC_BLOCK_SIZE = DELUGE_MAX_PAGES*DELUGE_CRC_SIZE,
DELUGE_FACTORY_IMAGE_NUM = 0x0,
DELUGE_INVALID_VNUM = -1,
DELUGE_INVALID_IMGNUM = 0xff,
DELUGE_INVALID_PKTNUM = 0xff,
DELUGE_INVALID_PGNUM = 0xff,
DELUGE_IMAGE0_VOLUME = unique("FlashVolume"),
DELUGE_IMAGE1_VOLUME = unique("FlashVolume"),
DELUGE_DATA_OFFSET = 128,
DELUGE_IDENT_SIZE = 128,
DELUGE_INVALID_ADDR = ((uint32_t)0x7fffffff),
};
typedef struct DelugeAdvTimer {
uint32_t timer : 24;
uint32_t periodLog2 : 7;
uint32_t overheard : 1;
uint8_t newAdvs;
} DelugeAdvTimer;
typedef struct DelugeNodeDesc {
imgvnum_t vNum;
imgnum_t imgNum;
uint8_t dummy;
uint16_t crc;
} DelugeNodeDesc;
#define IFLASH_GVNUM_ADDR 0x56
#endif
--- NEW FILE: DelugeC.nc ---
includes BitVecUtils;
includes Deluge;
includes DelugeMetadata;
includes DelugePageTransfer;
includes DelugeMsgs;
configuration DelugeC {
provides {
interface StdControl;
}
}
implementation {
components
Main,
BitVecUtilsC,
DelugeM,
DelugeMetadataC as Metadata,
DelugePageTransferC as PageTransfer,
GenericComm as Comm,
LedsC as Leds,
NetProgC,
RandomLFSR,
SharedMsgBufM,
TimerC;
#ifndef PLATFORM_PC
components InternalFlashC as IFlash;
DelugeM.IFlash -> IFlash;
#endif
StdControl = DelugeM;
DelugeM.MetadataControl -> Metadata;
DelugeM.SubStdControl -> Comm;
DelugeM.SubStdControl -> NetProgC;
DelugeM.SubStdControl -> PageTransfer;
DelugeM.SubStdControl -> SharedMsgBufM;
DelugeM.SubStdControl -> TimerC;
DelugeM.Leds -> Leds;
DelugeM.Metadata -> Metadata.Metadata[unique("DelugeMetadata")];
DelugeM.NetProg -> NetProgC;
DelugeM.PageTransfer -> PageTransfer;
DelugeM.Random -> RandomLFSR;
DelugeM.ReceiveAdvMsg -> Comm.ReceiveMsg[AM_DELUGEADVMSG];
DelugeM.SendAdvMsg-> Comm.SendMsg[AM_DELUGEADVMSG];
DelugeM.SharedMsgBuf -> SharedMsgBufM.SharedMsgBuf[DELUGE_SHARED_MSG_BUF];
DelugeM.Timer -> TimerC.Timer[unique("Timer")];
PageTransfer.Leds -> Leds;
PageTransfer.ReceiveDataMsg -> Comm.ReceiveMsg[AM_DELUGEDATAMSG];
PageTransfer.ReceiveReqMsg -> Comm.ReceiveMsg[AM_DELUGEREQMSG];
PageTransfer.SendDataMsg -> Comm.SendMsg[AM_DELUGEDATAMSG];
PageTransfer.SendReqMsg -> Comm.SendMsg[AM_DELUGEREQMSG];
PageTransfer.SharedMsgBuf -> SharedMsgBufM.SharedMsgBuf[DELUGE_SHARED_MSG_BUF];
}
--- NEW FILE: DelugeDataRead.nc ---
includes BlockStorage;
includes Deluge;
interface DelugeDataRead {
command result_t read(imgnum_t imgNum, block_addr_t addr,
uint8_t* buf, block_addr_t len);
event result_t readDone(result_t result);
}
--- NEW FILE: DelugeDataWrite.nc ---
interface DelugeDataWrite {
command result_t write(imgnum_t imgNum, block_addr_t addr,
uint8_t* source, block_addr_t len);
event result_t writeDone(result_t result);
command result_t erase(imgnum_t imgNum);
event result_t eraseDone(result_t result);
}
--- NEW FILE: DelugeImgDescStorage.nc ---
interface DelugeImgDescStorage {
}
--- NEW FILE: DelugeM.nc ---
module DelugeM {
provides {
interface StdControl;
}
uses {
interface DelugeMetadata as Metadata;
interface DelugePageTransfer as PageTransfer;
interface Leds;
interface InternalFlash as IFlash;
interface NetProg;
interface Random;
interface ReceiveMsg as ReceiveAdvMsg;
interface SendMsg as SendAdvMsg;
interface SharedMsgBuf;
interface SplitControl as MetadataControl;
interface StdControl as SubStdControl;
interface Timer;
}
}
implementation {
enum {
DELUGE_NUM_TIMERS = DELUGE_NUM_IMAGES-1,
};
DelugeAdvTimer advTimers[DELUGE_NUM_TIMERS];
DelugeNodeDesc nodeDesc;
uint8_t rebootDelay;
void setupAdvTimer(DelugeAdvTimer* timer) {
timer->timer = 0x1 << (timer->periodLog2-1);
timer->timer += call Random.rand() & (timer->timer-1);
}
uint8_t findMinTimer() {
uint32_t minDelay = advTimers[0].timer;
uint8_t minTimer = 0;
uint8_t i;
for ( i = 1; i < DELUGE_NUM_TIMERS; i++ ) {
if (advTimers[i].timer < minDelay)
minTimer = i;
}
return minTimer;
}
void startTimer() {
uint8_t minTimer = findMinTimer();
if (advTimers[minTimer].timer < 2)
advTimers[minTimer].timer += 2;
call Timer.stop();
call Timer.start(TIMER_ONE_SHOT, advTimers[minTimer].timer);
}
command result_t StdControl.init() {
result_t result;
call IFlash.read((uint16_t*)IFLASH_GVNUM_ADDR, &nodeDesc.vNum, sizeof(nodeDesc.vNum));
result = call Leds.init();
result = rcombine(call SubStdControl.init(), result);
result = rcombine(call MetadataControl.init(), result);
return result;
}
command result_t StdControl.start() {
result_t result;
nodeDesc.imgNum = call NetProg.getExecutingImgNum();
result = call SubStdControl.start();
result = rcombine(call MetadataControl.start(), result);
return result;
}
command result_t StdControl.stop() {
return SUCCESS;
}
event result_t MetadataControl.initDone() {
return SUCCESS;
}
event result_t MetadataControl.startDone() {
uint8_t i;
for ( i = 0; i < DELUGE_NUM_TIMERS; i++ ) {
advTimers[i].periodLog2 = DELUGE_MIN_ADV_PERIOD_LOG2;
setupAdvTimer(&advTimers[i]);
}
rebootDelay = 0;
startTimer();
return SUCCESS;
}
event result_t MetadataControl.stopDone() {
return SUCCESS;
}
void fillAdvMsg(imgnum_t image, DelugeAdvMsg* pMsg) {
pMsg->sourceAddr = TOS_LOCAL_ADDRESS;
pMsg->version = DELUGE_VERSION;
pMsg->type = DELUGE_ADV_NORMAL;
pMsg->nodeDesc = nodeDesc;
call Metadata.getImgDesc(image, &(pMsg->imgDesc));
}
event result_t Timer.fired() {
uint8_t minTimer = findMinTimer();
uint8_t i;
if (call PageTransfer.getWorkingImage() == DELUGE_INVALID_IMGNUM)
call Leds.redOn();
else
call Leds.redOff();
if (rebootDelay == 0)
call Leds.yellowOff();
call Leds.greenToggle();
for ( i = 0; i < DELUGE_NUM_TIMERS; i++ )
advTimers[i].timer -= advTimers[minTimer].timer;
if (!advTimers[minTimer].overheard
&& !call SharedMsgBuf.isLocked()
&& !call PageTransfer.isTransferring()) {
TOS_MsgPtr pMsgBuf = call SharedMsgBuf.getMsgBuf();
fillAdvMsg(minTimer+1, (DelugeAdvMsg*)(pMsgBuf->data));
if (call SendAdvMsg.send(TOS_BCAST_ADDR, sizeof(DelugeAdvMsg), pMsgBuf) == SUCCESS)
call SharedMsgBuf.lock();
}
if (advTimers[minTimer].newAdvs > 0)
advTimers[minTimer].newAdvs--;
if (rebootDelay > 0) {
if (rebootDelay == 1) {
call IFlash.write((uint16_t*)IFLASH_GVNUM_ADDR, &nodeDesc.vNum, sizeof(nodeDesc.vNum));
call NetProg.programImgAndReboot(nodeDesc.imgNum); // SHOULD NOT RETURN!
// XXX: WHAT DO WE DO HERE?
}
rebootDelay--;
}
else if (advTimers[minTimer].newAdvs == 0
&& rebootDelay == 0
&& advTimers[minTimer].periodLog2 < DELUGE_MAX_ADV_PERIOD_LOG2) {
advTimers[minTimer].periodLog2++;
}
advTimers[minTimer].overheard = 0;
setupAdvTimer(&advTimers[minTimer]);
startTimer();
return SUCCESS;
}
event TOS_MsgPtr ReceiveAdvMsg.receive(TOS_MsgPtr pMsg) {
DelugeAdvMsg *rxAdvMsg = (DelugeAdvMsg*)(pMsg->data);
imgnum_t imgNum = rxAdvMsg->imgDesc.imgNum;
dm_cmp_t cmpResult = call Metadata.compareImgDesc(&(rxAdvMsg->imgDesc));
if (rxAdvMsg->version != DELUGE_VERSION)
return pMsg;
if (rxAdvMsg->type == DELUGE_ADV_PC) {
// adv message from PC
if ((rxAdvMsg->nodeDesc.vNum == DELUGE_INVALID_VNUM
&& rxAdvMsg->nodeDesc.imgNum == DELUGE_INVALID_IMGNUM)
|| (cmpResult == DELUGE_IMGDESC_EQUAL)) {
if (!call SharedMsgBuf.isLocked()) {
TOS_MsgPtr pMsgBuf = call SharedMsgBuf.getMsgBuf();
fillAdvMsg(imgNum, (DelugeAdvMsg*)pMsgBuf->data);
if (call SendAdvMsg.send(rxAdvMsg->sourceAddr, sizeof(DelugeAdvMsg), pMsgBuf) == SUCCESS)
call SharedMsgBuf.lock();
}
return pMsg;
}
}
// don't listen to advertisements about the factory image
if (imgNum == DELUGE_FACTORY_IMAGE_NUM)
return pMsg;
switch (cmpResult) {
case DELUGE_IMGDESC_EQUAL:
advTimers[imgNum-1].overheard = 1;
break;
case DELUGE_IMGDESC_NEWER:
call Metadata.setupNewImage(&(rxAdvMsg->imgDesc));
break;
case DELUGE_IMGDESC_LARGER:
// notify page transfer of more data
if (advTimers[imgNum-1].newAdvs == 0)
call PageTransfer.dataAvailable(rxAdvMsg->sourceAddr);
break;
}
if (cmpResult != DELUGE_IMGDESC_EQUAL) {
advTimers[imgNum-1].periodLog2 = DELUGE_MIN_ADV_PERIOD_LOG2;
setupAdvTimer(&advTimers[imgNum-1]);
startTimer();
}
if ((rxAdvMsg->nodeDesc.vNum - nodeDesc.vNum) > 0
&& rxAdvMsg->nodeDesc.vNum != DELUGE_INVALID_VNUM
&& call Metadata.isComplete(imgNum)) {
call Leds.yellowOn();
nodeDesc = rxAdvMsg->nodeDesc;
advTimers[imgNum-1].periodLog2 = DELUGE_MIN_ADV_PERIOD_LOG2;
rebootDelay = DELUGE_REBOOT_DELAY;
setupAdvTimer(&advTimers[imgNum-1]);
startTimer();
}
return pMsg;
}
void setNextPage() {
DelugeImgDesc imgDesc;
uint8_t i;
for ( i = 0; i < DELUGE_NUM_IMAGES; i++ ) {
call Metadata.getImgDesc(i, &imgDesc);
if (imgDesc.numPgs != imgDesc.numPgsComplete)
break;
}
if (i < DELUGE_NUM_IMAGES)
call PageTransfer.setWorkingPage(i, imgDesc.numPgsComplete);
}
event result_t Metadata.setupNewImageDone(result_t result) {
setNextPage();
return SUCCESS;
}
event result_t SendAdvMsg.sendDone(TOS_MsgPtr pMsg, result_t result) {
dbg(DBG_USR1, "send adv message\n");
call SharedMsgBuf.unlock();
return SUCCESS;
}
event result_t PageTransfer.receivedPage(imgnum_t imgNum, pgnum_t pgNum) {
call Metadata.receivedPage(imgNum, pgNum);
advTimers[imgNum-1].newAdvs = DELUGE_NUM_NEWDATA_ADVS_REQUIRED;
setNextPage();
return SUCCESS;
}
event result_t SharedMsgBuf.bufFree() { return SUCCESS; }
}
--- NEW FILE: DelugeMetadata.h ---
#ifndef __DELUGE_METADATA_H__
#define __DELUGE_METADATA_H__
enum {
DELUGE_IMGDESC_NEWER, // newer object
DELUGE_IMGDESC_OLDER, // older object
DELUGE_IMGDESC_LARGER, // more pages of same object
DELUGE_IMGDESC_SMALLER, // less pages of same object
DELUGE_IMGDESC_EQUAL, // identical
};
typedef int8_t dm_cmp_t;
typedef int16_t imgvnum_t;
typedef uint8_t imgnum_t;
typedef uint8_t pgnum_t;
typedef struct DelugeImgDesc {
imgvnum_t vNum; // version num of image
imgnum_t imgNum; // image number
pgnum_t numPgs; // num pages of complete image
uint16_t crc; // crc for vNum and numPgs
uint8_t numPgsComplete; // numPgsComplete in image
uint8_t dummy; // make data structure word aligned
} DelugeImgDesc;
#endif
--- NEW FILE: DelugeMetadata.nc ---
interface DelugeMetadata {
command bool isComplete(imgnum_t imgNum);
command result_t setupNewImage(DelugeImgDesc* imgDesc);
event result_t setupNewImageDone(result_t result);
command result_t getImgDesc(imgnum_t imgNum, DelugeImgDesc* imgDesc);
command dm_cmp_t compareImgDesc(DelugeImgDesc* imgDesc);
command imgvnum_t getVNum(imgnum_t imgNum);
command pgnum_t getNumPgsComplete(imgnum_t imgNum);
command result_t receivedPage(imgnum_t imgNum, pgnum_t pgNum);
}
--- NEW FILE: DelugeMetadataC.nc ---
includes BlockStorage;
configuration DelugeMetadataC {
provides {
interface DelugeMetadata as Metadata[uint8_t id];
interface SplitControl;
}
}
implementation {
components
DelugeMetadataM,
DelugeStorageC as Storage;
SplitControl = DelugeMetadataM;
Metadata = DelugeMetadataM;
DelugeMetadataM.DataWrite -> Storage.DataWrite[unique("DelugeDataWrite")];
DelugeMetadataM.MetadataRead -> Storage.MetadataRead[unique("DelugeMetadataRead")];
DelugeMetadataM.MetadataWrite -> Storage.MetadataWrite[unique("DelugeMetadataWrite")];
DelugeMetadataM.SubControl -> Storage;
}
--- NEW FILE: DelugeMetadataM.nc ---
module DelugeMetadataM {
provides {
interface SplitControl;
interface DelugeMetadata as Metadata[uint8_t id];
}
uses {
interface DelugeDataWrite as DataWrite;
interface DelugeMetadataRead as MetadataRead;
interface DelugeMetadataWrite as MetadataWrite;
interface StdControl as SubControl;
}
}
implementation {
DelugeImgDesc imgDesc[DELUGE_NUM_IMAGES];
uint8_t client;
uint8_t curImage;
uint8_t state;
enum {
S_INIT,
S_IDLE,
S_READ_IMG_DESC,
S_WRITE_IMG_DESC,
S_ERASE_IMG_DESC,
};
task void retry() {
result_t result = SUCCESS;
switch(state) {
case S_ERASE_IMG_DESC:
result = call DataWrite.erase(curImage);
break;
case S_READ_IMG_DESC:
result = call MetadataRead.read(curImage, &(imgDesc[curImage]));
break;
case S_WRITE_IMG_DESC:
result = call MetadataWrite.write(curImage, &(imgDesc[curImage]));
break;
}
if (result == FAIL)
post retry();
}
command result_t SplitControl.init() {
result_t result;
state = S_INIT;
result = call SubControl.init();
#ifdef PLATFORM_PC
if (TOS_LOCAL_ADDRESS == 0) {
imgDesc[0].vNum = 1;
imgDesc[0].imgNum = 0;
imgDesc[0].numPgs = 5;
imgDesc[0].numPgsComplete = 5;
}
#endif
return SUCCESS;
}
command result_t SplitControl.start() {
result_t result;
result = call SubControl.start();
state = S_READ_IMG_DESC;
curImage = 0;
if (call MetadataRead.read(curImage, &(imgDesc[curImage])) == FAIL)
post retry();
return SUCCESS;
}
command result_t SplitControl.stop() {
return SUCCESS;
}
command bool Metadata.isComplete[uint8_t id](imgnum_t imgNum) {
if (state == S_IDLE
&& imgNum < DELUGE_NUM_IMAGES
&& imgDesc[imgNum].numPgsComplete != 0
&& (imgDesc[imgNum].numPgs == imgDesc[imgNum].numPgsComplete))
return TRUE;
return FALSE;
}
command imgvnum_t Metadata.getVNum[uint8_t id](imgnum_t imgNum) {
return imgDesc[imgNum].vNum;
}
command pgnum_t Metadata.getNumPgsComplete[uint8_t id](imgnum_t imgNum) {
return imgDesc[imgNum].numPgsComplete;
}
command result_t Metadata.receivedPage[uint8_t id](imgnum_t imgNum, pgnum_t pgNum) {
if (imgNum >= DELUGE_NUM_IMAGES)
return FAIL;
// increment numPgsComplete
if (imgDesc[imgNum].numPgsComplete < imgDesc[imgNum].numPgs
&& imgDesc[imgNum].numPgsComplete == pgNum)
imgDesc[imgNum].numPgsComplete++;
// if image is complete, write out numPgsComplete
if (imgDesc[imgNum].numPgsComplete == imgDesc[imgNum].numPgs) {
state = S_WRITE_IMG_DESC;
curImage = imgNum;
if (call MetadataWrite.write(curImage, &(imgDesc[curImage])) == FAIL)
post retry();
}
return SUCCESS;
}
command result_t Metadata.setupNewImage[uint8_t id](DelugeImgDesc* newImgDesc) {
if (state != S_IDLE
|| newImgDesc->imgNum >= DELUGE_NUM_IMAGES)
return FALSE;
client = id;
memcpy(&(imgDesc[newImgDesc->imgNum]), newImgDesc, sizeof(DelugeImgDesc));
imgDesc[newImgDesc->imgNum].numPgsComplete = 0;
state = S_ERASE_IMG_DESC;
curImage = newImgDesc->imgNum;
if (call DataWrite.erase(curImage) == FAIL)
post retry();
return SUCCESS;
}
command result_t Metadata.getImgDesc[uint8_t id](uint8_t imgNum, DelugeImgDesc* newImgDesc) {
if (imgNum >= DELUGE_NUM_IMAGES)
return FAIL;
memcpy(newImgDesc, &(imgDesc[imgNum]), sizeof(DelugeImgDesc));
return SUCCESS;
}
command dm_cmp_t Metadata.compareImgDesc[uint8_t id](DelugeImgDesc* cmpImgDesc) {
imgnum_t image = cmpImgDesc->imgNum;
if (image >= DELUGE_NUM_IMAGES)
return DELUGE_IMGDESC_EQUAL;
if ((cmpImgDesc->vNum - imgDesc[image].vNum) > 0)
return DELUGE_IMGDESC_NEWER;
else if ((cmpImgDesc->vNum - imgDesc[image].vNum) < 0)
return DELUGE_IMGDESC_OLDER;
else if (cmpImgDesc->numPgsComplete > imgDesc[image].numPgsComplete)
return DELUGE_IMGDESC_LARGER;
else if (cmpImgDesc->numPgsComplete < imgDesc[image].numPgsComplete)
return DELUGE_IMGDESC_SMALLER;
return DELUGE_IMGDESC_EQUAL;
}
event result_t MetadataRead.readDone(result_t result) {
if (imgDesc[curImage].vNum == DELUGE_INVALID_VNUM) {
imgDesc[curImage].imgNum = curImage;
imgDesc[curImage].numPgs = 0;
imgDesc[curImage].crc = 0;
imgDesc[curImage].numPgsComplete = 0;
}
if (state == S_READ_IMG_DESC) {
curImage++;
if (curImage < DELUGE_NUM_IMAGES) {
if (call MetadataRead.read(curImage, &(imgDesc[curImage])) == FAIL)
post retry();
}
}
state = S_IDLE;
return signal SplitControl.startDone();
}
event result_t DataWrite.eraseDone(result_t result) {
state = S_IDLE;
return signal Metadata.setupNewImageDone[client](result);
}
event result_t MetadataWrite.writeDone(result_t result) {
state = S_IDLE;
return SUCCESS;
}
event result_t DataWrite.writeDone(result_t result) { return SUCCESS; }
default event result_t Metadata.setupNewImageDone[uint8_t id](result_t result) {
return SUCCESS;
}
}
--- NEW FILE: DelugeMetadataRead.nc ---
interface DelugeMetadataRead {
command result_t read(imgnum_t imgNum, DelugeImgDesc* imgDesc);
event result_t readDone(result_t result);
}
--- NEW FILE: DelugeMetadataWrite.nc ---
interface DelugeMetadataWrite {
command result_t write(imgnum_t imgNum, DelugeImgDesc* imgDesc);
event result_t writeDone(result_t result);
}
--- NEW FILE: DelugeMsgs.h ---
#ifndef __DELUGE_MSGS_H__
#define __DELUGE_MSGS_H__
#include "Deluge.h"
#include "DelugeMetadata.h"
#include "DelugePageTransfer.h"
enum {
DELUGE_SHARED_MSG_BUF = unique("SharedMsgBuf"),
};
enum {
AM_DELUGEADVMSG = 161,
AM_DELUGEREQMSG = 162,
AM_DELUGEDATAMSG = 163,
AM_DELUGEPINGREPLYMSG = 164,
};
enum {
DELUGE_ADV_NORMAL = 0,
DELUGE_ADV_PC = 1,
DELUGE_ADV_PING = 2,
DELUGE_ADV_NOT_READY = 3,
};
typedef struct DelugeAdvMsg {
uint16_t sourceAddr; // 2
uint8_t version; // 1
uint8_t type; // 1
DelugeNodeDesc nodeDesc; // 6
DelugeImgDesc imgDesc; // 8
} DelugeAdvMsg;
typedef struct DelugeReqMsg {
uint16_t dest;
uint16_t sourceAddr;
imgvnum_t vNum;
imgnum_t imgNum;
pgnum_t pgNum;
uint8_t requestedPkts[DELUGE_PKT_BITVEC_SIZE];
} DelugeReqMsg;
typedef struct DelugeDataMsg {
imgvnum_t vNum;
imgnum_t imgNum;
pgnum_t pgNum;
uint8_t pktNum;
uint8_t data[DELUGE_PKT_PAYLOAD_SIZE];
} DelugeDataMsg;
#endif
--- NEW FILE: DelugePageTransfer.h ---
#ifndef __DELUGE_PAGE_TRANSFER_H__
#define __DELUGE_PAGE_TRANSFER_H__
enum {
DELUGE_PKTS_PER_PAGE = 48,
DELUGE_PKT_PAYLOAD_SIZE = 23,
DELUGE_BYTES_PER_PAGE = (DELUGE_PKTS_PER_PAGE*DELUGE_PKT_PAYLOAD_SIZE),
DELUGE_PKT_BITVEC_SIZE = (((DELUGE_PKTS_PER_PAGE-1) / 8) + 1),
DELUGE_DATA_Q_SIZE = 2,
};
#endif
--- NEW FILE: DelugePageTransfer.nc ---
interface DelugePageTransfer {
command result_t setWorkingPage(imgnum_t imgNum, pgnum_t pgNum);
command imgnum_t getWorkingImage();
command pgnum_t getWorkingPage();
command bool isTransferring();
command result_t dataAvailable(uint16_t sourceAddr);
event result_t receivedPage(imgnum_t imgNum, pgnum_t pgNum);
}
--- NEW FILE: DelugePageTransferC.nc ---
configuration DelugePageTransferC {
provides {
interface StdControl;
interface DelugePageTransfer;
}
uses {
interface Leds;
interface SendMsg as SendReqMsg;
interface SendMsg as SendDataMsg;
interface ReceiveMsg as ReceiveReqMsg;
interface ReceiveMsg as ReceiveDataMsg;
interface SharedMsgBuf;
}
}
implementation {
components
DelugePageTransferM,
BitVecUtilsC,
DelugeMetadataC as Metadata,
DelugeStorageC as Storage,
RandomLFSR,
TimerC;
StdControl = DelugePageTransferM;
DelugePageTransfer = DelugePageTransferM;
Leds = DelugePageTransferM;
DelugePageTransferM.SubControl -> Storage;
DelugePageTransferM.SubControl -> TimerC;
DelugePageTransferM.BitVecUtils -> BitVecUtilsC;
DelugePageTransferM.DataRead -> Storage.DataRead[unique("DelugeDataRead")];
DelugePageTransferM.DataWrite -> Storage.DataWrite[unique("DelugeDataWrite")];
DelugePageTransferM.Metadata -> Metadata.Metadata[unique("DelugeMetadata")];
DelugePageTransferM.Random -> RandomLFSR;
DelugePageTransferM.ReceiveDataMsg = ReceiveDataMsg;
DelugePageTransferM.ReceiveReqMsg = ReceiveReqMsg;
DelugePageTransferM.ReqTimer -> TimerC.Timer[unique("Timer")];
DelugePageTransferM.SendDataMsg = SendDataMsg;
DelugePageTransferM.SendReqMsg = SendReqMsg;
DelugePageTransferM.SharedMsgBuf = SharedMsgBuf;
}
--- NEW FILE: DelugePageTransferM.nc ---
module DelugePageTransferM {
provides {
interface StdControl;
interface DelugePageTransfer as PageTransfer;
}
uses {
interface BitVecUtils;
interface DelugeMetadata as Metadata;
interface DelugeDataRead as DataRead;
interface DelugeDataWrite as DataWrite;
interface Leds;
interface Random;
interface ReceiveMsg as ReceiveDataMsg;
interface ReceiveMsg as ReceiveReqMsg;
interface SendMsg as SendDataMsg;
interface SendMsg as SendReqMsg;
interface SharedMsgBuf;
interface StdControl as SubControl;
interface Timer as ReqTimer;
}
}
implementation {
typedef struct {
uint16_t dataSourceAddr;
uint8_t numReqTriesLeft;
bool suppressReq;
} RxState;
typedef struct {
uint16_t dest;
uint8_t imgToSend;
uint8_t pageToSend;
} TxState;
typedef struct {
union {
RxState rx;
TxState tx;
};
} RxTxState;
// send/receive page buffers, and state variables for buffers
uint8_t pktsToSend[DELUGE_PKT_BITVEC_SIZE]; // bit vec of packets to send
uint8_t pktsToReceive[DELUGE_PKT_BITVEC_SIZE]; // bit vec of packets to receive
typedef struct {
uint8_t pktNum;
uint8_t data[DELUGE_PKT_PAYLOAD_SIZE];
} ReceivedData;
ReceivedData receivedData;
// state variables
uint8_t state;
RxTxState vars;
imgnum_t workingImgNum;
pgnum_t workingPgNum;
enum {
S_DISABLED,
S_IDLE,
S_TX_LOCKING,
S_SENDING,
S_RX_LOCKING,
S_RECEIVING,
};
void changeState(uint8_t newState) {
switch(newState) {
case S_DISABLED: case S_IDLE:
if (state == S_SENDING || state == S_RECEIVING)
call SharedMsgBuf.unlock();
break;
}
state = newState;
}
command result_t StdControl.init() {
changeState(S_DISABLED);
receivedData.pktNum = DELUGE_INVALID_PKTNUM;
workingImgNum = DELUGE_INVALID_IMGNUM;
workingPgNum = DELUGE_INVALID_PGNUM;
return call SubControl.init();
}
command result_t StdControl.start() {
changeState(S_IDLE);
return call SubControl.start();
}
command result_t StdControl.stop() {
changeState(S_DISABLED);
return SUCCESS;
}
command result_t PageTransfer.setWorkingPage(imgnum_t imgNum, pgnum_t pgNum) {
workingImgNum = imgNum;
workingPgNum = pgNum;
memset(pktsToReceive, 0xff, DELUGE_PKT_BITVEC_SIZE);
return SUCCESS;
}
command imgnum_t PageTransfer.getWorkingImage() {
return workingImgNum;
}
command pgnum_t PageTransfer.getWorkingPage() {
return workingPgNum;
}
command bool PageTransfer.isTransferring() {
return (state != S_IDLE && state != S_DISABLED);
}
command result_t PageTransfer.dataAvailable(uint16_t sourceAddr) {
if (workingImgNum == DELUGE_INVALID_IMGNUM)
return FAIL;
if (state == S_IDLE) {
// currently idle, so request data from source
changeState(S_RX_LOCKING);
vars.rx.dataSourceAddr = sourceAddr;
vars.rx.suppressReq = FALSE;
// randomize request to prevent collision
call ReqTimer.start(TIMER_ONE_SHOT, DELUGE_MIN_DELAY +
call Random.rand() % DELUGE_MAX_REQ_DELAY);
}
return SUCCESS;
}
uint32_t calcOffset(pgnum_t pgNum, uint8_t pktNum) {
return (uint32_t)pgNum*(uint32_t)DELUGE_BYTES_PER_PAGE
+ (uint32_t)pktNum*(uint32_t)DELUGE_PKT_PAYLOAD_SIZE;
}
void setupDataMsg();
task void retrySetupDataMsg() {
setupDataMsg();
}
void setupDataMsg() {
TOS_MsgPtr pMsgBuf = call SharedMsgBuf.getMsgBuf();
DelugeDataMsg* pDataMsg = (DelugeDataMsg*)(pMsgBuf->data);
uint32_t offset;
uint16_t nextPkt;
if (state != S_SENDING && state != S_TX_LOCKING)
return;
if (state == S_TX_LOCKING) {
if (call SharedMsgBuf.lock() == FAIL) {
post retrySetupDataMsg();
return;
}
changeState(S_SENDING);
pDataMsg->vNum = call Metadata.getVNum(vars.tx.imgToSend);
pDataMsg->imgNum = vars.tx.imgToSend;
pDataMsg->pgNum = vars.tx.pageToSend;
pDataMsg->pktNum = 0;
}
if (!call BitVecUtils.indexOf(&nextPkt, pDataMsg->pktNum, pktsToSend,
DELUGE_PKTS_PER_PAGE)
&& !call BitVecUtils.indexOf(&nextPkt, 0, pktsToSend,
DELUGE_PKTS_PER_PAGE)) {
// no more packets to send
dbg(DBG_USR1, "DELUGE: SEND_DONE\n");
changeState(S_IDLE);
return;
}
pDataMsg->pktNum = (uint8_t)nextPkt;
offset = calcOffset(pDataMsg->pgNum, pDataMsg->pktNum);
if (call DataRead.read(vars.tx.imgToSend, offset, pDataMsg->data,
DELUGE_PKT_PAYLOAD_SIZE) == FAIL)
post retrySetupDataMsg();
}
event result_t ReqTimer.fired() {
TOS_MsgPtr pMsgBuf = call SharedMsgBuf.getMsgBuf();
DelugeReqMsg* pReqMsg = (DelugeReqMsg*)(pMsgBuf->data);
if (state != S_RECEIVING && state != S_RX_LOCKING)
return SUCCESS;
if (state == S_RX_LOCKING) {
if (call SharedMsgBuf.lock() == FAIL) {
call ReqTimer.start(TIMER_ONE_SHOT, DELUGE_FAILED_SEND_DELAY);
return SUCCESS;
}
// update address of source node
changeState(S_RECEIVING);
pReqMsg->dest = vars.rx.dataSourceAddr;
pReqMsg->sourceAddr = TOS_LOCAL_ADDRESS;
vars.rx.numReqTriesLeft = DELUGE_MAX_NUM_REQ_TRIES;
pReqMsg->imgNum = workingImgNum;
pReqMsg->pgNum = workingPgNum;
pReqMsg->vNum = call Metadata.getVNum(workingImgNum);
memcpy(pReqMsg->requestedPkts, pktsToReceive, DELUGE_PKT_BITVEC_SIZE);
}
if (vars.rx.suppressReq) {
// suppress request
call ReqTimer.start(TIMER_ONE_SHOT, DELUGE_NACK_TIMEOUT +
call Random.rand() % DELUGE_NACK_TIMEOUT);
vars.rx.suppressReq = FALSE;
return SUCCESS;
}
if (vars.rx.numReqTriesLeft == 0) {
// tried too many times, give up
changeState(S_IDLE);
return SUCCESS;
}
{
uint16_t dest = (pReqMsg->dest == TOS_UART_ADDR) ? TOS_UART_ADDR : TOS_BCAST_ADDR;
if (call SendReqMsg.send(dest, sizeof(DelugeReqMsg), pMsgBuf) == SUCCESS) {
vars.rx.numReqTriesLeft--;
}
else {
// send failed, wait a bit and try again
call ReqTimer.start(TIMER_ONE_SHOT, DELUGE_FAILED_SEND_DELAY);
}
}
return SUCCESS;
}
event TOS_MsgPtr ReceiveReqMsg.receive(TOS_MsgPtr pMsg) {
DelugeReqMsg *rxReqMsg = (DelugeReqMsg*)(pMsg->data);
imgnum_t tmpImgNum;
pgnum_t tmpPgNum;
int i;
dbg(DBG_USR1, "DELUGE: Received REQ_MSG(dest=%d,vNum=%d,imgNum=%d,pgNum=%d,pkts=%x)\n",
rxReqMsg->dest, rxReqMsg->vNum, rxReqMsg->imgNum, rxReqMsg->pgNum, rxReqMsg->requestedPkts[0]);
if (state == S_DISABLED)
return pMsg;
if (state == S_SENDING || state == S_TX_LOCKING) {
tmpImgNum = vars.tx.imgToSend;
tmpPgNum = vars.tx.pageToSend;
}
else {
tmpImgNum = workingImgNum;
tmpPgNum = workingPgNum;
}
if (rxReqMsg->imgNum < tmpImgNum
|| (rxReqMsg->imgNum == tmpImgNum
&& (rxReqMsg->vNum - call Metadata.getVNum(tmpImgNum) > 0
|| (rxReqMsg->vNum == call Metadata.getVNum(tmpImgNum)
&& rxReqMsg->pgNum < tmpPgNum)))) {
if (state == S_SENDING || state == S_TX_LOCKING) {
changeState(S_IDLE);
memset(pktsToSend, 0x0, DELUGE_PKT_BITVEC_SIZE);
}
}
if (rxReqMsg->dest != TOS_LOCAL_ADDRESS) {
if ((state == S_RECEIVING || state == S_RX_LOCKING)
&& rxReqMsg->imgNum == workingImgNum
&& rxReqMsg->vNum == call Metadata.getVNum(workingImgNum)
&& rxReqMsg->pgNum <= workingPgNum) {
// suppress next request since similar request has been overheard
vars.rx.suppressReq = TRUE;
}
return pMsg;
}
if (rxReqMsg->pgNum >= call Metadata.getNumPgsComplete(rxReqMsg->imgNum)
|| rxReqMsg->vNum != call Metadata.getVNum(rxReqMsg->imgNum)) {
// don't have this page, ignore request
return pMsg;
}
if (state == S_IDLE
|| ((state == S_SENDING || state == S_TX_LOCKING)
&& rxReqMsg->imgNum == vars.tx.imgToSend
&& rxReqMsg->vNum == call Metadata.getVNum(vars.tx.imgToSend)
&& rxReqMsg->pgNum == vars.tx.pageToSend)) {
// take union of packet bit vectors
for ( i = 0; i < DELUGE_PKT_BITVEC_SIZE; i++ )
pktsToSend[i] |= rxReqMsg->requestedPkts[i];
}
if (state == S_IDLE) {
// not currently sending, so start sending data
changeState(S_TX_LOCKING);
vars.tx.imgToSend = rxReqMsg->imgNum;
vars.tx.pageToSend = rxReqMsg->pgNum;
vars.tx.dest = (rxReqMsg->sourceAddr != TOS_UART_ADDR) ? TOS_BCAST_ADDR : TOS_UART_ADDR;
setupDataMsg();
}
return pMsg;
}
task void writeData() {
if (call DataWrite.write(workingImgNum, calcOffset(workingPgNum, receivedData.pktNum),
receivedData.data, DELUGE_PKT_PAYLOAD_SIZE) == FAIL)
post writeData();
}
event TOS_MsgPtr ReceiveDataMsg.receive(TOS_MsgPtr pMsg) {
TOS_MsgPtr pMsgBuf = call SharedMsgBuf.getMsgBuf();
DelugeReqMsg *pReqMsg = (DelugeReqMsg*)(pMsgBuf->data);
DelugeDataMsg *rxDataMsg = (DelugeDataMsg*)(pMsg->data);
uint16_t tmp;
dbg(DBG_USR1, "DELUGE: Received DATA_MSG(vNum=%d,imgNum=%d,pgNum=%d,pktNum=%d)\n",
rxDataMsg->vNum, rxDataMsg->imgNum, rxDataMsg->pgNum, rxDataMsg->pktNum);
if (state == S_DISABLED)
return pMsg;
if (workingImgNum == DELUGE_INVALID_IMGNUM)
return pMsg;
if (rxDataMsg->vNum == call Metadata.getVNum(workingImgNum)
&& rxDataMsg->imgNum == workingImgNum
&& rxDataMsg->pgNum <= workingPgNum) {
if (state == S_RECEIVING || state == S_RX_LOCKING) {
// suppress next request since nodes are still sending
vars.rx.suppressReq = TRUE;
}
if (receivedData.pktNum == DELUGE_INVALID_PKTNUM
&& rxDataMsg->pgNum == workingPgNum
&& rxDataMsg->pktNum < DELUGE_PKTS_PER_PAGE
&& BITVEC_GET(pktsToReceive, rxDataMsg->pktNum)) {
// got a packet we need
call Leds.set(rxDataMsg->pktNum);
dbg(DBG_USR1, "DELUGE: SAVING(pgNum=%d,pktNum=%d)\n",
rxDataMsg->pgNum,rxDataMsg->pktNum);
// copy data
receivedData.pktNum = rxDataMsg->pktNum;
memcpy(receivedData.data, rxDataMsg->data, DELUGE_PKT_PAYLOAD_SIZE);
if (call DataWrite.write(workingImgNum, calcOffset(workingPgNum, receivedData.pktNum),
receivedData.data, DELUGE_PKT_PAYLOAD_SIZE) == FAIL)
post writeData();
// mark packet as received in request packet
BITVEC_CLEAR(pktsToReceive, receivedData.pktNum);
if (state == S_RECEIVING)
BITVEC_CLEAR(pReqMsg->requestedPkts, receivedData.pktNum);
// stop requests if all packets are received
if (!call BitVecUtils.indexOf(&tmp, 0, pktsToReceive, DELUGE_PKTS_PER_PAGE))
call ReqTimer.stop();
}
}
return pMsg;
}
task void retrySendDataMsg() {
if (state != S_SENDING)
return;
if (call SendDataMsg.send(vars.tx.dest, sizeof(DelugeDataMsg),
call SharedMsgBuf.getMsgBuf()) == FAIL)
post retrySendDataMsg();
}
event result_t DataRead.readDone(result_t result) {
TOS_MsgPtr pMsgBuf = call SharedMsgBuf.getMsgBuf();
if (state != S_SENDING)
return SUCCESS;
if (result == SUCCESS) {
// success, begin sending
if (call SendDataMsg.send(vars.tx.dest, sizeof(DelugeDataMsg), pMsgBuf) == FAIL)
post retrySendDataMsg();
}
else {
// fail, something bad happened forget sending
changeState(S_IDLE);
}
return SUCCESS;
}
/*
task void checkCrc() {
if (call StableStore.checkCrc(workingImgNum, workingPgNum,
receivedData.data) == FAIL)
post checkCrc();
}
*/
event result_t DataWrite.writeDone(result_t result) {
uint16_t tmp;
if (result == FAIL) {
// fail, something bad happened, try again
post writeData();
return SUCCESS;
}
receivedData.pktNum = DELUGE_INVALID_PKTNUM;
if (!call BitVecUtils.indexOf(&tmp, 0, pktsToReceive, DELUGE_PKTS_PER_PAGE)) {
imgnum_t tmpImgNum = workingImgNum;
pgnum_t tmpPgNum = workingPgNum;
workingImgNum = DELUGE_INVALID_IMGNUM;
workingPgNum = DELUGE_INVALID_PGNUM;
changeState(S_IDLE);
signal PageTransfer.receivedPage(tmpImgNum, tmpPgNum);
dbg(DBG_USR1, "DELUGE: RECEIVED_PAGE(pgNum=%d)\n", tmpPgNum);
/*
if (call StableStore.checkCrc(workingImgNum, workingPgNum, dataQ[dataQHead].data) == FAIL)
post checkCrc();
*/
}
return SUCCESS;
}
event result_t SendReqMsg.sendDone(TOS_MsgPtr pMsg, result_t success) {
DelugeReqMsg* pReqMsg = (DelugeReqMsg*)(pMsg->data);
if (state != S_RECEIVING)
return SUCCESS;
if (pReqMsg->imgNum == workingImgNum
&& pReqMsg->vNum == call Metadata.getVNum(workingImgNum)
&& pReqMsg->pgNum == workingPgNum) {
// start timeout timer in case request is not serviced
call ReqTimer.start(TIMER_ONE_SHOT,
DELUGE_NACK_TIMEOUT + call Random.rand() % DELUGE_NACK_TIMEOUT);
}
return SUCCESS;
}
event result_t SendDataMsg.sendDone(TOS_MsgPtr pMsg, result_t success) {
DelugeDataMsg* pDataMsg = (DelugeDataMsg*)(pMsg->data);
BITVEC_CLEAR(pktsToSend, pDataMsg->pktNum);
if (pDataMsg->pktNum == DELUGE_PKTS_PER_PAGE - 1)
pDataMsg->pktNum = 0;
setupDataMsg();
return SUCCESS;
}
event result_t DataWrite.eraseDone(result_t result) { return SUCCESS; }
event result_t Metadata.setupNewImageDone(result_t result) { return SUCCESS; }
event result_t SharedMsgBuf.bufFree() { return SUCCESS; }
}
--- NEW FILE: DelugeStorage.nc ---
interface DelugeStorage {
command uint32_t imgNum2Addr(imgnum_t imgNum);
command imgnum_t addr2ImgNum(uint32_t addr);
}
--- NEW FILE: DelugeStorageC.nc ---
includes FlashVolume;
configuration DelugeStorageC {
provides {
interface StdControl;
interface DelugeDataRead as DataRead[uint8_t id];
interface DelugeDataWrite as DataWrite[uint8_t id];
interface DelugeMetadataRead as MetadataRead[uint8_t id];
interface DelugeMetadataWrite as MetadataWrite[uint8_t id];
interface DelugeStorage;
}
}
implementation {
components
DelugeStorageM as Storage,
BlockStorageC,
FlashVolumeC;
StdControl = Storage;
StdControl = FlashVolumeC;
DataRead = Storage;
DataWrite = Storage;
DelugeStorage = Storage;
MetadataRead = Storage;
MetadataWrite = Storage;
Storage.SubControl -> BlockStorageC;
Storage.Image0Volume -> FlashVolumeC.FlashVolume[DELUGE_IMAGE0_VOLUME];
Storage.Image1Volume -> FlashVolumeC.FlashVolume[DELUGE_IMAGE1_VOLUME];
Storage.Image0Read -> BlockStorageC.BlockRead[DELUGE_IMAGE0_VOLUME];
Storage.Image1Read -> BlockStorageC.BlockRead[DELUGE_IMAGE1_VOLUME];
Storage.Image0Write -> BlockStorageC.BlockWrite[DELUGE_IMAGE0_VOLUME];
Storage.Image1Write -> BlockStorageC.BlockWrite[DELUGE_IMAGE1_VOLUME];
}
--- NEW FILE: DelugeStorageM.nc ---
module DelugeStorageM {
provides {
interface StdControl;
interface DelugeMetadataRead as MetadataRead[uint8_t id];
interface DelugeMetadataWrite as MetadataWrite[uint8_t id];
interface DelugeDataRead as DataRead[uint8_t id];
interface DelugeDataWrite as DataWrite[uint8_t id];
interface DelugeStorage;
}
uses {
interface BlockRead as Image0Read;
interface BlockRead as Image1Read;
interface BlockWrite as Image0Write;
interface BlockWrite as Image1Write;
interface FlashVolume as Image0Volume;
interface FlashVolume as Image1Volume;
interface StdControl as SubControl;
}
}
implementation {
enum {
S_IDLE,
S_READ_METADATA,
S_WRITE_METADATA,
S_READ_DATA,
S_WRITE_DATA,
S_ERASE_DATA,
};
uint8_t compID;
uint8_t state;
void actualSignal(result_t result) {
uint8_t tmpState = state;
state = S_IDLE;
switch(tmpState) {
case S_READ_DATA: signal DataRead.readDone[compID](result); break;
case S_WRITE_DATA: signal DataWrite.writeDone[compID](result); break;
case S_ERASE_DATA: signal DataWrite.eraseDone[compID](result); break;
case S_READ_METADATA: signal MetadataRead.readDone[compID](result); break;
case S_WRITE_METADATA: signal MetadataWrite.writeDone[compID](result); break;
}
}
task void signalSuccess() { actualSignal(SUCCESS); }
task void signalFail() { actualSignal(FAIL); }
result_t signalDone(result_t result) {
if (result == SUCCESS)
post signalSuccess();
else
post signalFail();
return SUCCESS;
}
command result_t StdControl.init() {
return call SubControl.init();
}
command result_t StdControl.start() {
call Image0Volume.mount(FV_FACTORY_IMAGE);
call Image1Volume.mount(0);
return call SubControl.start();
}
command result_t StdControl.stop() { return SUCCESS; }
command uint32_t DelugeStorage.imgNum2Addr(imgnum_t imgNum) {
uint32_t addr;
switch(imgNum) {
case 0: addr = call Image0Volume.physicalAddr(0); break;
case 1: addr = call Image1Volume.physicalAddr(0); break;
default: return DELUGE_INVALID_ADDR;
}
return addr + (uint32_t)DELUGE_DATA_OFFSET + (uint32_t)DELUGE_CRC_BLOCK_SIZE;
}
command imgnum_t DelugeStorage.addr2ImgNum(uint32_t addr) {
return 0xffff;
}
result_t read(imgnum_t imgNum, block_addr_t addr, void* buf, block_addr_t len) {
switch(imgNum) {
case 0: return call Image0Read.read(addr, buf, len);
case 1: return call Image1Read.read(addr, buf, len);
}
return FAIL;
}
result_t write(imgnum_t imgNum, block_addr_t addr, void* buf, block_addr_t len) {
switch(imgNum) {
case 0: return call Image0Write.write(addr, buf, len);
case 1: return call Image1Write.write(addr, buf, len);
}
return FAIL;
}
result_t erase(imgnum_t imgNum) {
switch(imgNum) {
case 0: return call Image0Write.erase();
case 1: return call Image1Write.erase();
}
return FAIL;
}
result_t newRequest(uint8_t newState, uint8_t id, imgnum_t imgNum,
block_addr_t addr, void* buf, block_addr_t len) {
result_t result;
if (state != S_IDLE)
return FAIL;
if (imgNum >= DELUGE_NUM_IMAGES)
return FAIL;
compID = id;
state = newState;
switch(newState) {
case S_READ_METADATA: case S_READ_DATA:
result = read(imgNum, addr, buf, len);
break;
case S_WRITE_METADATA: case S_WRITE_DATA:
result = write(imgNum, addr, buf, len);
break;
case S_ERASE_DATA:
result = erase(imgNum);
break;
default:
result = FAIL;
break;
}
if (result == FAIL) {
state = S_IDLE;
return FAIL;
}
return SUCCESS;
}
command result_t MetadataRead.read[uint8_t id](imgnum_t imgNum, DelugeImgDesc* imgDesc) {
return newRequest(S_READ_METADATA, id, imgNum, 0, imgDesc, sizeof(DelugeImgDesc));
}
command result_t MetadataWrite.write[uint8_t id](imgnum_t imgNum, DelugeImgDesc* imgDesc) {
return newRequest(S_WRITE_METADATA, id, imgNum, 0, imgDesc, sizeof(DelugeImgDesc));
}
command result_t DataRead.read[uint8_t id](imgnum_t imgNum, block_addr_t addr,
uint8_t* buf, block_addr_t length) {
return newRequest(S_READ_DATA, id, imgNum, DELUGE_DATA_OFFSET + addr, buf, length);
}
command result_t DataWrite.write[uint8_t id](imgnum_t imgNum, block_addr_t addr,
uint8_t* buf, block_addr_t length) {
return newRequest(S_WRITE_DATA, id, imgNum, DELUGE_DATA_OFFSET + addr, buf, length);
}
command result_t DataWrite.erase[uint8_t id](imgnum_t imgNum) {
return newRequest(S_ERASE_DATA, id, imgNum, 0, 0, 0);
}
event result_t Image0Read.readDone(result_t result) {
signalDone(result);
return SUCCESS;
}
event result_t Image0Write.writeDone(result_t result) {
signalDone(result);
return SUCCESS;
}
event result_t Image0Write.eraseDone(result_t result) {
signalDone(result);
return SUCCESS;
}
event result_t Image1Read.readDone(result_t result) {
signalDone(result);
return SUCCESS;
}
event result_t Image1Write.writeDone(result_t result) {
signalDone(result);
return SUCCESS;
}
event result_t Image1Write.eraseDone(result_t result) {
signalDone(result);
return SUCCESS;
}
event result_t Image0Read.verifyDone(result_t result) { return SUCCESS; }
event result_t Image0Write.commitDone(result_t result) { return SUCCESS; }
event result_t Image1Read.verifyDone(result_t result) { return SUCCESS; }
event result_t Image1Write.commitDone(result_t result) { return SUCCESS; }
default event result_t DataRead.readDone[uint8_t id](result_t result) { return SUCCESS; }
default event result_t DataWrite.writeDone[uint8_t id](result_t result) { return SUCCESS; }
default event result_t DataWrite.eraseDone[uint8_t id](result_t result) { return SUCCESS; }
default event result_t MetadataRead.readDone[uint8_t id](result_t result) { return SUCCESS; }
default event result_t MetadataWrite.writeDone[uint8_t id](result_t result) { return SUCCESS; }
}
--- NEW FILE: NetProg.h ---
// $Id: NetProg.h,v 1.1 2004/11/22 05:30:57 jwhui Exp $
/* tab:4
*
*
* "Copyright (c) 2000-2004 The Regents of the University of California.
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
* CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
*
*/
/**
* Allows rebooting of multiple images.
*
* @author Jonathan Hui <jwhui at cs.berkeley.edu>
*/
#ifndef __NETPROG_H__
#define __NETPROG_H__
#define IFLASH_LOCALID_ADDR 0x50
#define IFLASH_GROUPID_ADDR 0x52
#define IFLASH_CHECKSUM_ADDR 0x54
#define NETPROG_DISABLE_WDT() WDTCTL = WDTPW + WDTHOLD;
#define NETPROG_ACTUAL_REBOOT() WDTCTL = WDT_ARST_1_9; while(1);
#endif
--- NEW FILE: NetProg.nc ---
// $Id: NetProg.nc,v 1.1 2004/11/22 05:30:57 jwhui Exp $
/* tab:4
*
*
* "Copyright (c) 2000-2004 The Regents of the University of California.
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
* CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
*
*/
/**
* Top level interface for network programming integration with
* applications.
*
* @author Jonathan Hui <jwhui at cs.berkeley.edu>
*/
interface NetProg {
/**
* Reboot the node.
*
* @return Does not return.
*/
command result_t reboot();
/**
* Reboot into the image specified by <code>imgNum</code>. This
* assumes that an image has been downloaded into slot <code>imgNum</code>
* using Deluge.
*
* @param imgNum Number of image to boot in to.
* @return <code>FAIL</code> if the reboot command fails to
* complete due to an invalid imgNum or incomplete
* image,
* does not return, otherwise.
*/
command result_t programImgAndReboot(uint8_t imgNum);
/**
* Get the image number currently executing.
*
* @return The image number of the executing image,
* <code>DELUGE_INVALID_IMGNUM</code> otherwise.
*/
command uint8_t getExecutingImgNum();
}
--- NEW FILE: NetProgC.nc ---
includes NetProg;
includes TOSBoot;
#ifndef PLATFORM_PC
includes InternalFlash;
#endif
configuration NetProgC {
provides {
interface NetProg;
interface StdControl;
}
}
implementation {
components
DelugeMetadataC as Metadata,
DelugeStorageC as Storage,
NetProgM;
#ifndef PLATFORM_PC
components InternalFlashC as IFlash;
NetProgM.IFlash -> IFlash;
#endif
StdControl = NetProgM;
NetProg = NetProgM;
NetProgM.Metadata -> Metadata.Metadata[unique("DelugeMetadata")];
NetProgM.MetadataControl -> Metadata;
NetProgM.Storage -> Storage;
}
--- NEW FILE: NetProgM.nc ---
module NetProgM {
provides {
interface NetProg;
interface StdControl;
}
uses {
interface DelugeMetadata as Metadata;
interface DelugeStorage as Storage;
interface InternalFlash as IFlash;
interface SplitControl as MetadataControl;
}
}
implementation {
imgnum_t imgNum;
uint8_t checkSum(uint16_t _addr, uint8_t _group) {
return ~(_addr + _group);
}
void writeTOSinfo() {
uint8_t checksum = checkSum(TOS_LOCAL_ADDRESS, TOS_AM_GROUP);
call IFlash.write((uint8_t*)IFLASH_GROUPID_ADDR, &TOS_AM_GROUP, sizeof(TOS_AM_GROUP));
call IFlash.write((uint16_t*)IFLASH_LOCALID_ADDR, &TOS_LOCAL_ADDRESS, sizeof(TOS_LOCAL_ADDRESS));
call IFlash.write((uint8_t*)IFLASH_CHECKSUM_ADDR, &checksum, sizeof(checkSum));
}
command result_t StdControl.init() {
// grab addr, pid, and gid from internal flash
uint16_t addr, startPage;
uint8_t group, sum;
result_t result;
result = call MetadataControl.init();
#ifndef PLATFORM_PC
call IFlash.read((uint16_t*)TOSBOOT_CUR_IMG_START_ADDR, &startPage, sizeof(startPage));
call IFlash.read((uint16_t*)IFLASH_LOCALID_ADDR, &addr, sizeof(addr));
call IFlash.read((uint8_t*)IFLASH_GROUPID_ADDR, &group, sizeof(group));
call IFlash.read((uint8_t*)IFLASH_CHECKSUM_ADDR, &sum, sizeof(sum));
if (sum == checkSum(addr, group)) {
TOS_AM_GROUP = group;
atomic TOS_LOCAL_ADDRESS = addr;
}
else {
writeTOSinfo();
}
imgNum = (startPage == 0xffff) ? DELUGE_INVALID_IMGNUM : 0;
//call Storage.flashPage2ImgNum(startPage);
#else
imgNum = DELUGE_INVALID_IMGNUM;
#endif
return result;
}
command result_t StdControl.start() {
return call MetadataControl.start();
}
command result_t StdControl.stop() { return SUCCESS; }
void markExplicitRebootFlag() {
#ifndef PLATFORM_PC
uint8_t tmp;
call IFlash.read((uint8_t*)TOSBOOT_FLAGS_ADDR, &tmp, sizeof(tmp));
tmp |= TOSBOOT_EXPLICIT_REBOOT;
call IFlash.write((uint8_t*)TOSBOOT_FLAGS_ADDR, &tmp, sizeof(tmp));
#endif
}
event result_t MetadataControl.initDone() { return SUCCESS; }
event result_t MetadataControl.startDone() { return SUCCESS; }
event result_t MetadataControl.stopDone() { return SUCCESS; }
command result_t NetProg.reboot() {
#ifndef PLATFORM_PC
atomic {
NETPROG_DISABLE_WDT();
writeTOSinfo();
markExplicitRebootFlag();
NETPROG_ACTUAL_REBOOT();
}
#endif
return FAIL;
}
command result_t NetProg.programImgAndReboot(imgnum_t newImgNum) {
if (call Metadata.isComplete(newImgNum)) {
#ifndef PLATFORM_PC
uint32_t imageAddr;
uint8_t tmp = 0;
atomic {
NETPROG_DISABLE_WDT();
writeTOSinfo();
markExplicitRebootFlag();
imageAddr = call Storage.imgNum2Addr(newImgNum) + DELUGE_IDENT_SIZE;
call IFlash.write((uint16_t*)TOSBOOT_NEW_IMG_START_ADDR, &imageAddr, sizeof(imageAddr));
call IFlash.write((uint8_t*)TOSBOOT_LOAD_IMG_ADDR, &tmp, sizeof(tmp));
// reboot
NETPROG_ACTUAL_REBOOT();
}
#endif
}
// image is not complete or invalid, or metadata is not ready
return FAIL;
}
command uint8_t NetProg.getExecutingImgNum() { return imgNum; }
event result_t Metadata.setupNewImageDone(result_t result) { return SUCCESS; }
}
--- NEW FILE: SharedMsgBuf.nc ---
// $Id: SharedMsgBuf.nc,v 1.1 2004/11/22 05:30:57 jwhui Exp $
/* tab:4
*
*
* "Copyright (c) 2000-2004 The Regents of the University of California.
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
* CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
*
*/
/**
* Simple component that allows sharing of message buffers through a
* parameterized interface.
*
* @author Jonathan Hui <jwhui at cs.berkeley.edu>
*/
interface SharedMsgBuf {
/**
* Get the pointer to a shared message buf.
*
* @return The pointer to the shared message buf.
*/
command TOS_MsgPtr getMsgBuf();
/**
* Request a lock on the shared message buf.
*
* @return <code>SUCCESS</code> if the lock was acquired successfully;
* <code>FAIL</code> otherwise.
*/
command result_t lock();
/**
* Release lock on shared message buf.
*
* @return <code>SUCCESS</code> if the lock was released successfully;
*/
command result_t unlock();
/**
* Check if shared message buf is currently locked.
*
* @return <code>TRUE</code> if the shared message buf is locked;
* <code>FALSE</code> otherwise.
*/
command bool isLocked();
/**
* Signal that the bus is free to allow other components waiting to
* begin using it right away.
*
* @return <code>SUCCESS</code> on success,
* <code>FAIL</code> otherwise.
*/
event result_t bufFree();
}
--- NEW FILE: SharedMsgBufM.nc ---
// $Id: SharedMsgBufM.nc,v 1.1 2004/11/22 05:30:57 jwhui Exp $
/* tab:4
*
*
* "Copyright (c) 2000-2004 The Regents of the University of California.
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
* CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
*
*/
/**
* Simple component that allows sharing of message * buffers through a
* parameterized interface.
*
* @author Jonathan Hui <jwhui at cs.berkeley.edu>
*/
module SharedMsgBufM {
provides {
interface SharedMsgBuf[uint8_t id];
interface StdControl;
}
uses interface BitVecUtils;
}
implementation {
#include <BitVecUtils.h>
enum {
SMB_NUM_BUFS = uniqueCount("SharedMsgBuf"),
SMB_LOCK_BITVEC_SIZE = (((SMB_NUM_BUFS-1)/8)+1),
};
TOS_Msg msgBufs[SMB_NUM_BUFS];
uint8_t lockedMsgBufs[SMB_LOCK_BITVEC_SIZE];
command result_t StdControl.init() {
memset(lockedMsgBufs, 0x0, SMB_LOCK_BITVEC_SIZE);
return SUCCESS;
}
command result_t StdControl.start() { return SUCCESS; }
command result_t StdControl.stop() { return SUCCESS; }
command TOS_MsgPtr SharedMsgBuf.getMsgBuf[uint8_t id]() {
if (id >= SMB_NUM_BUFS)
return NULL;
return &(msgBufs[id]);
}
command result_t SharedMsgBuf.lock[uint8_t id]() {
if (id >= SMB_NUM_BUFS || BITVEC_GET(lockedMsgBufs, id))
return FAIL;
BITVEC_SET(lockedMsgBufs, id);
return SUCCESS;
}
command result_t SharedMsgBuf.unlock[uint8_t id]() {
if (id >= SMB_NUM_BUFS)
return FAIL;
BITVEC_CLEAR(lockedMsgBufs, id);
return SUCCESS;
}
command bool SharedMsgBuf.isLocked[uint8_t id]() {
if (BITVEC_GET(lockedMsgBufs, id))
return TRUE;
return FALSE;
}
default event result_t SharedMsgBuf.bufFree[uint8_t id]() { return SUCCESS; }
}
- Previous message: [Tinyos-beta-commits]
CVS: tinyos-1.x/beta/Deluge/Deluge/TOSBoot/build/telosb
app.c, NONE, 1.1 ident_flags.txt, NONE, 1.1 main.exe, NONE,
1.1 main.ihex, NONE, 1.1
- Next message: [Tinyos-beta-commits]
CVS: tinyos-1.x/beta/Deluge/TestDeluge/DelugeBasic
DelugeBasic.nc, NONE, 1.1 Makefile, NONE, 1.1
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the Tinyos-beta-commits
mailing list