From 2d422c11d7a829ca46b5440a7ba123ae2a5b94d9 Mon Sep 17 00:00:00 2001 From: razvanm Date: Tue, 10 Jul 2007 01:17:39 +0000 Subject: [PATCH] This commit from Chieh-Jan (Mike) Liang fixes the following issues: - Add a new command to reprogram the network (instead of motes automatically reprogram after they receive an image). - Update the documentation to reflect the new command. - Add README.txt files for the examples. --- apps/tests/deluge/Blink/README.txt | 38 +++++++ apps/tests/deluge/GoldenImage/README.txt | 32 ++++++ apps/tests/deluge/SerialBlink/README.txt | 32 ++++++ doc/html/deluge-t2-manual.css | 18 ++-- doc/html/deluge-t2-manual.html | 23 +++-- doc/pdf/deluge-t2-manual.pdf | Bin 45773 -> 46042 bytes tools/tinyos/misc/tos-deluge | 42 ++++++-- tos/lib/net/Deluge/Deluge.h | 4 + tos/lib/net/Deluge/DelugeC.nc | 3 +- tos/lib/net/Deluge/DelugeMsgs.h | 24 ++--- tos/lib/net/Deluge/DelugeP.nc | 96 +++++++++++------- .../FlashVolumeManager/FlashVolumeManager.h | 15 +-- .../FlashVolumeManager/FlashVolumeManagerC.nc | 6 +- .../FlashVolumeManager/FlashVolumeManagerP.nc | 19 +++- tos/lib/net/Deluge/ObjectTransferP.nc | 11 +- tos/lib/net/Deluge/extra/NetProgM.nc | 1 + 16 files changed, 269 insertions(+), 95 deletions(-) create mode 100644 apps/tests/deluge/Blink/README.txt create mode 100644 apps/tests/deluge/GoldenImage/README.txt create mode 100644 apps/tests/deluge/SerialBlink/README.txt diff --git a/apps/tests/deluge/Blink/README.txt b/apps/tests/deluge/Blink/README.txt new file mode 100644 index 00000000..4be92bc6 --- /dev/null +++ b/apps/tests/deluge/Blink/README.txt @@ -0,0 +1,38 @@ +README for apps/tests/deluge/Blink +Author/Contact: + +Chieh-Jan Mike Liang +Razvan Musaloiu-E. + +Description: + +This is a sample application referenced in the Deluge T2 manual to show +some of the basics in reprogramming. + +The burn script performs the following tasks on the basestation: + 1) Compile and load the program normally. + 2) Compile another version of blink that blinks differently. + 3) Upload the new blink to flash volume 0. + 4) Instruct the mote to reprogram with the new blink. + +Alternatively, you can reprogram the whole network (non-basestation +motes) by first uploading the image to the base station. Then, tell the +base station to disseminate the image. For example, + + tos-deluge /dev/ttyUSB0 telosb -d 0 + +Finally, after the image has been disseminated, instruct the base +station to disseminate the command to reprogram. For example, + + tos-deluge /dev/ttyUSB0 telosb -r 0 + +For a more detailed discussion on Deluge T2, please refer to the Deluge +T2 manual. + +Prerequisites: + +Python 2.4 with pySerial + +References: + +The Deluge T2 manual is available under $TOS_DIR/doc/html/. diff --git a/apps/tests/deluge/GoldenImage/README.txt b/apps/tests/deluge/GoldenImage/README.txt new file mode 100644 index 00000000..39dd3f59 --- /dev/null +++ b/apps/tests/deluge/GoldenImage/README.txt @@ -0,0 +1,32 @@ +README for apps/tests/deluge/GoldenImage +Author/Contact: + +Chieh-Jan Mike Liang +Razvan Musaloiu-E. + +Description: + +This is a sample application for Deluge T2. The application is similar +to Null, but it includes Deluge T2. + +You can reprogram the whole network (non-basestation motes) by first +uploading the image to the base station. Then, tell the base station to +disseminate the image. Example: + + tos-deluge /dev/ttyUSB0 telosb -d 0 + +Finally, after the image has been disseminated, instruct the base +station to disseminate the command to reprogram. Example: + + tos-deluge /dev/ttyUSB0 telosb -r 0 + +For a more detailed discussion on Deluge T2, please refer to the Deluge +T2 manual. + +Prerequisites: + +Python 2.4 with pySerial + +References: + +The Deluge T2 manual is available under $TOS_DIR/doc/html/. diff --git a/apps/tests/deluge/SerialBlink/README.txt b/apps/tests/deluge/SerialBlink/README.txt new file mode 100644 index 00000000..c5ea55bf --- /dev/null +++ b/apps/tests/deluge/SerialBlink/README.txt @@ -0,0 +1,32 @@ +README for apps/tests/deluge/SerialBlink +Author/Contact: + +Chieh-Jan Mike Liang +Razvan Musaloiu-E. + +Description: + +This is a sample application for Deluge T2. The program blinks and send +a serial msg every second. + +You can reprogram the whole network (non-basestation motes) by first +uploading the image to the base station. Then, tell the base station to +disseminate the image. Example: + + tos-deluge /dev/ttyUSB0 telosb -d 0 + +Finally, after the image has been disseminated, instruct the base +station to disseminate the command to reprogram. Example: + + tos-deluge /dev/ttyUSB0 telosb -r 0 + +For a more detailed discussion on Deluge T2, please refer to the Deluge +T2 manual. + +Prerequisites: + +Python 2.4 with pySerial + +References: + +The Deluge T2 manual is available under $TOS_DIR/doc/html/. diff --git a/doc/html/deluge-t2-manual.css b/doc/html/deluge-t2-manual.css index 02a6f88f..a443e35d 100644 --- a/doc/html/deluge-t2-manual.css +++ b/doc/html/deluge-t2-manual.css @@ -16,6 +16,8 @@ .title { font-size: 200%; font-weight: normal; + margin-top: 2.8em; + text-align: center; } .partheading { @@ -94,12 +96,6 @@ list-style-type: upper-alpha; } - /* - .verbatim { - color: #4d0000; - } - */ - tt i { font-family: serif; } @@ -108,9 +104,15 @@ font-family: serif; } + /* + .verbatim { + color: #4d0000; + } + */ + .scheme em { - font-family: serif; color: black; + font-family: serif; } .scheme { @@ -183,11 +185,11 @@ .colophon { color: gray; font-size: 80%; + font-style: italic; text-align: right; } .colophon a { color: gray; } - \ No newline at end of file diff --git a/doc/html/deluge-t2-manual.html b/doc/html/deluge-t2-manual.html index 2248f683..3dd87e3f 100644 --- a/doc/html/deluge-t2-manual.html +++ b/doc/html/deluge-t2-manual.html @@ -9,6 +9,8 @@ Deluge T2 - Programming Manual +
+

@@ -19,11 +21,11 @@ Deluge T2 - Programming Manual

-



Deluge T2 - Programming Manual

+

Deluge T2 - Programming Manual

Chieh-Jan Mike Liang
-Razvan Musaloiu-E.

June 21, 2007

+Razvan Musaloiu-E.

July 9, 2007

@@ -214,7 +216,7 @@ You should see something similar to the output below.

first test on the base station by issuing the reboot command. For example,

-
   % tos-deluge /dev/ttyUSB0 telosb -r 1
+
   % tos-deluge /dev/ttyUSB0 telosb -b 1
 

After a few moments, the mote will begin quickly flashing the LEDs to signify the reprogramming process.

@@ -225,10 +227,14 @@ the network. For example,
   % tos-deluge /dev/ttyUSB0 telosb -d 1
 

This command instructs the base station to notify the whole network of -the availablility of a new program image. This notification is currently +the availability of a new program image. This notification is currently done via TinyOS dissemination service, and it triggers all motes in the -network to get the new program image. Upon receiving the complete image -over-the-air, each node automatically reboots and reprograms itself.

+network to get the new program image. After all motes receive the image +over-the-air, you can instruct the base station to disseminate a command +to reprogram the network. For example, +

+
   % tos-deluge /dev/ttyUSB0 telosb -r 1
+

@@ -281,9 +287,8 @@ reprogram themselves.

directly connected mote.

-
-Last modified: Thursday, June 21st, 2007
-HTML conversion by TeX2page 2004-09-11
+

+
Last modified: Monday, July 9th, 2007 8:43:40pm
diff --git a/doc/pdf/deluge-t2-manual.pdf b/doc/pdf/deluge-t2-manual.pdf index 1dccd028c47519f871b1ef6caa01a71b006bee2e..98025dd39fd42b80389aee3f60d8ffe01859eb4d 100644 GIT binary patch delta 12618 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 NfJ99#p(Kg)e*mI;4f_B9 delta 12402 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 C(uqz0 diff --git a/tools/tinyos/misc/tos-deluge b/tools/tinyos/misc/tos-deluge index 88e132b0..5a3c1bb6 100755 --- a/tools/tinyos/misc/tos-deluge +++ b/tools/tinyos/misc/tos-deluge @@ -47,11 +47,12 @@ SERIAL_AMID = 0xAB SERIAL_DATA_LENGTH = 28 - 1 - 1 - 2 - 2 # Serial message types -MSG_ERASE = 0 -MSG_WRITE = 1 -MSG_READ = 2 -MSG_REPROG = 5 -MSG_DISS = 6 +MSG_ERASE = 0 +MSG_WRITE = 1 +MSG_READ = 2 +MSG_REPROG = 5 +MSG_DISS = 6 +MSG_REPROG_BS = 7 ERROR_SUCCESS = 0 # T2-compatible ERROR_FAIL = 1 # T2-compatible @@ -320,12 +321,12 @@ def op_inject(s, img_num, tos_image_xml): return False -# Requests the mote to reboot and reprogram itself -def op_reprog(s, img_num): +# Requests the base station to reprogram itself +def op_reprog_bs(s, img_num): if getMetaData(s, img_num) == None: print "ERROR: No proper Deluge image found!" else: - sreqpkt = SerialReqPacket((MSG_REPROG, img_num, 0, 0, [])) + sreqpkt = SerialReqPacket((MSG_REPROG_BS, img_num, 0, 0, [])) success = s.write_packet(SERIAL_AMGROUP, SERIAL_AMID, sreqpkt.payload()) if success == True: packet = s.read_packet(SERIAL_AMGROUP, SERIAL_AMID) @@ -333,12 +334,27 @@ def op_reprog(s, img_num): if sreplypkt.error == ERROR_SUCCESS: return True else: - print "ERROR: Unable to reboot the mote" + print "ERROR: Unable to reprogram the base station" return False print "ERROR: Unable to send the command" return False +# Requests the network to reprogram with the specified image number +def op_reprog(s, img_num): + sreqpkt = SerialReqPacket((MSG_REPROG, img_num, 0, 0, [])) + success = s.write_packet(SERIAL_AMGROUP, SERIAL_AMID, sreqpkt.payload()) + if success == True: + packet = s.read_packet(SERIAL_AMGROUP, SERIAL_AMID) + sreplypkt = SerialReplyPacket(packet[1]) + if sreplypkt.error == ERROR_SUCCESS: + return True + else: + print "ERROR: Unable to reprogram the network" + return False + + print "ERROR: Unable to send the command" + # Requests the mote to disseminate an image def op_diss(s, img_num): if getMetaData(s, img_num) == None: @@ -386,7 +402,8 @@ def print_usage(): print " -p --ping\n Provide status of the image in the external flash" print " -i --inject\n Inject a compiled TinyOS application" print " [options]: tos_image.xml file path" - print " -r --reboot\n Reboot and reprogram the directly-connected mote" + print " -r --reprogram\n Reprogram the network" + print " -b --reprogram_bs\n Reprogram only the directly-connected mote" print " -d --dissemination\n Disseminate the image in the external flash to the network" print " -e --erase\n Erase an image in the external flash" print " -s --reset\n Reset the versioning information for a given image" @@ -415,9 +432,12 @@ if len(sys.argv) >= num_req_arg: elif sys.argv[3] in ["-i", "--inject"] and len(sys.argv) == (num_req_arg + 1): print "Pinging node ..." op_inject(s, sys.argv[4], sys.argv[5]) - elif sys.argv[3] in ["-r", "--reboot"]: + elif sys.argv[3] in ["-r", "--reprogram"]: if op_reprog(s, sys.argv[4]): print "Command sent" + elif sys.argv[3] in ["-b", "--reprogram_bs"]: + if op_reprog_bs(s, sys.argv[4]): + print "Command sent" elif sys.argv[3] in ["-d", "--dissemination"]: if op_diss(s, sys.argv[4]): print "Command sent" diff --git a/tos/lib/net/Deluge/Deluge.h b/tos/lib/net/Deluge/Deluge.h index c9ec9cbe..8a9f504f 100644 --- a/tos/lib/net/Deluge/Deluge.h +++ b/tos/lib/net/Deluge/Deluge.h @@ -29,12 +29,16 @@ #include "DelugeMetadata.h" +#define DISSMSG_DISS 0 +#define DISSMSG_REPROG 1 + enum { DELUGE_INVALID_UID = 0xffffffff, DELUGE_NUM_VOLUMES = 2, }; typedef nx_struct DelugeDissemination { + nx_uint8_t msg_type; nx_uint32_t uid; // unique id of image nx_uint16_t vNum; // version num of image nx_uint8_t imgNum; // image number diff --git a/tos/lib/net/Deluge/DelugeC.nc b/tos/lib/net/Deluge/DelugeC.nc index caea5305..4759e4da 100644 --- a/tos/lib/net/Deluge/DelugeC.nc +++ b/tos/lib/net/Deluge/DelugeC.nc @@ -37,7 +37,8 @@ implementation components SerialStarterC; components new FlashVolumeManagerC(0xAB); - DelugeP.ReprogNotify -> FlashVolumeManagerC; + DelugeP.DissNotify -> FlashVolumeManagerC.DissNotify; + DelugeP.ReprogNotify -> FlashVolumeManagerC.ReprogNotify; FlashVolumeManagerC.BlockRead[VOLUME_DELUGE0] -> DelugeStorageC.BlockRead[VOLUME_DELUGE0]; FlashVolumeManagerC.BlockWrite[VOLUME_DELUGE0] -> DelugeStorageC.BlockWrite[VOLUME_DELUGE0]; FlashVolumeManagerC.DelugeStorage[VOLUME_DELUGE0] -> DelugeStorageC.DelugeStorage[VOLUME_DELUGE0]; diff --git a/tos/lib/net/Deluge/DelugeMsgs.h b/tos/lib/net/Deluge/DelugeMsgs.h index 82b0b91e..449bcf1d 100644 --- a/tos/lib/net/Deluge/DelugeMsgs.h +++ b/tos/lib/net/Deluge/DelugeMsgs.h @@ -42,26 +42,26 @@ enum { }; typedef nx_struct DelugeAdvMsg { - nx_uint16_t sourceAddr; - nx_uint8_t version; // Deluge Version - nx_uint8_t type; + nx_uint16_t sourceAddr; + nx_uint8_t version; // Deluge Version + nx_uint8_t type; DelugeObjDesc objDesc; - nx_uint8_t reserved; + nx_uint8_t reserved; } DelugeAdvMsg; typedef nx_struct DelugeReqMsg { - nx_uint16_t dest; - nx_uint16_t sourceAddr; - nx_object_id_t objid; - nx_page_num_t pgNum; - nx_uint8_t requestedPkts[DELUGE_PKT_BITVEC_SIZE]; + nx_uint16_t dest; + nx_uint16_t sourceAddr; + nx_object_id_t objid; + nx_page_num_t pgNum; + nx_uint8_t requestedPkts[DELUGE_PKT_BITVEC_SIZE]; } DelugeReqMsg; typedef nx_struct DelugeDataMsg { nx_object_id_t objid; - nx_page_num_t pgNum; - nx_uint8_t pktNum; - nx_uint8_t data[DELUGE_PKT_PAYLOAD_SIZE]; + nx_page_num_t pgNum; + nx_uint8_t pktNum; + nx_uint8_t data[DELUGE_PKT_PAYLOAD_SIZE]; } DelugeDataMsg; #endif diff --git a/tos/lib/net/Deluge/DelugeP.nc b/tos/lib/net/Deluge/DelugeP.nc index d49bac41..8adcf1d6 100644 --- a/tos/lib/net/Deluge/DelugeP.nc +++ b/tos/lib/net/Deluge/DelugeP.nc @@ -39,6 +39,7 @@ module DelugeP interface SplitControl as RadioSplitControl; #ifdef DELUGE_BASESTATION + interface Notify as DissNotify; interface Notify as ReprogNotify; #endif } @@ -46,7 +47,7 @@ module DelugeP implementation { - uint8_t img_num; + //uint8_t img_num; /** * Starts the radio @@ -60,28 +61,42 @@ implementation /** * Starts disseminating image information */ - event void ReprogNotify.notify(uint8_t new_img_num) + event void DissNotify.notify(uint8_t new_img_num) { - DelugeDissemination delugeDis; - DelugeImgDesc *imgDesc; - - imgDesc = call DelugeMetadata.getImgDesc(new_img_num); + DelugeImgDesc* imgDesc = call DelugeMetadata.getImgDesc(new_img_num); if (imgDesc->uid != DELUGE_INVALID_UID) { + DelugeDissemination delugeDis; + call ObjectTransfer.stop(); call Leds.led0Toggle(); - img_num = new_img_num; delugeDis.uid = imgDesc->uid; delugeDis.vNum = imgDesc->vNum; - delugeDis.imgNum = img_num; + delugeDis.imgNum = new_img_num; delugeDis.size = imgDesc->size; + delugeDis.msg_type = DISSMSG_DISS; - call DisseminationUpdate.change(&delugeDis); // Disseminates image information + call DisseminationUpdate.change(&delugeDis); // Disseminates command call ObjectTransfer.publish(delugeDis.uid, delugeDis.size, delugeDis.imgNum); // Prepares to publish image data } } + + event void ReprogNotify.notify(uint8_t new_img_num) + { + DelugeDissemination delugeDis; + + call Leds.led2Toggle(); + + delugeDis.uid = 0; + delugeDis.vNum = 0; + delugeDis.imgNum = new_img_num; + delugeDis.size = 0; + delugeDis.msg_type = DISSMSG_REPROG; + + call DisseminationUpdate.change(&delugeDis); // Disseminates command + } #endif /** @@ -93,26 +108,39 @@ implementation const DelugeDissemination *delugeDis = call DisseminationValue.get(); DelugeImgDesc *imgDesc = call DelugeMetadata.getImgDesc(delugeDis->imgNum); - if (imgDesc->uid == delugeDis->uid) { - if (imgDesc->vNum < delugeDis->vNum) { - img_num = delugeDis->imgNum; // Note which image number to boot - call ObjectTransfer.receive(delugeDis->uid, delugeDis->size, delugeDis->imgNum); - } - } else { - img_num = delugeDis->imgNum; // Note which image number to boot - call ObjectTransfer.receive(delugeDis->uid, delugeDis->size, delugeDis->imgNum); + switch (delugeDis->msg_type) { + case DISSMSG_DISS: + if (imgDesc->uid == delugeDis->uid && imgDesc->uid != DELUGE_INVALID_UID) { + if (imgDesc->vNum < delugeDis->vNum) { + call ObjectTransfer.receive(delugeDis->uid, delugeDis->size, delugeDis->imgNum); + } + } else { + call ObjectTransfer.receive(delugeDis->uid, delugeDis->size, delugeDis->imgNum); + } + + break; + case DISSMSG_REPROG: + if (imgDesc->uid != DELUGE_INVALID_UID) { + DelugeNodeDesc nodeDesc; + call IFlash.read((uint8_t*)IFLASH_NODE_DESC_ADDR, + &nodeDesc, + sizeof(DelugeNodeDesc)); // Reads which image was just reprogrammed + if (nodeDesc.uid != imgDesc->uid || nodeDesc.vNum != imgDesc->vNum) { + call NetProg.programImgAndReboot(delugeDis->imgNum); + } + } + + break; } } - - /** - * Reboots and reprograms with the newly received image - */ + event void ObjectTransfer.receiveDone(error_t error) { + //call ObjectTransfer.publish(imgDesc->uid, imgDesc->size, imgDesc->imgNum); call ObjectTransfer.stop(); - if (error == SUCCESS) { - call NetProg.programImgAndReboot(img_num); - } +// if (error == SUCCESS) { +// call NetProg.programImgAndReboot(img_num); +// } } /** @@ -121,16 +149,16 @@ implementation event void RadioSplitControl.startDone(error_t error) { if (error == SUCCESS) { - // Start publishing the current image - DelugeImgDesc *imgDesc; - DelugeNodeDesc nodeDesc; - call IFlash.read((uint8_t*)IFLASH_NODE_DESC_ADDR, - &nodeDesc, - sizeof(DelugeNodeDesc)); // Reads which image was just reprogrammed - imgDesc = call DelugeMetadata.getImgDesc(nodeDesc.imgNum); - if (nodeDesc.uid == imgDesc->uid && imgDesc->uid != DELUGE_INVALID_UID) { - call ObjectTransfer.publish(imgDesc->uid, imgDesc->size, imgDesc->imgNum); - } +// // Start publishing the current image +// DelugeImgDesc *imgDesc; +// DelugeNodeDesc nodeDesc; +// call IFlash.read((uint8_t*)IFLASH_NODE_DESC_ADDR, +// &nodeDesc, +// sizeof(DelugeNodeDesc)); // Reads which image was just reprogrammed +// imgDesc = call DelugeMetadata.getImgDesc(nodeDesc.imgNum); +// if (nodeDesc.uid == imgDesc->uid && imgDesc->uid != DELUGE_INVALID_UID) { +// call ObjectTransfer.publish(imgDesc->uid, imgDesc->size, imgDesc->imgNum); +// } call StdControlDissemination.start(); } diff --git a/tos/lib/net/Deluge/FlashVolumeManager/FlashVolumeManager.h b/tos/lib/net/Deluge/FlashVolumeManager/FlashVolumeManager.h index 5c0a597c..9ca55a45 100644 --- a/tos/lib/net/Deluge/FlashVolumeManager/FlashVolumeManager.h +++ b/tos/lib/net/Deluge/FlashVolumeManager/FlashVolumeManager.h @@ -27,13 +27,14 @@ #ifndef FLASHVOLUMEMANAGER_H #define FLASHVOLUMEMANAGER_H -#define SERIALMSG_ERASE 0 -#define SERIALMSG_WRITE 1 -#define SERIALMSG_READ 2 -#define SERIALMSG_CRC 3 -#define SERIALMSG_ADDR 4 -#define SERIALMSG_REPROG 5 -#define SERIALMSG_DISS 6 +#define SERIALMSG_ERASE 0 +#define SERIALMSG_WRITE 1 +#define SERIALMSG_READ 2 +#define SERIALMSG_CRC 3 +#define SERIALMSG_ADDR 4 +#define SERIALMSG_REPROG 5 +#define SERIALMSG_DISS 6 +#define SERIALMSG_REPROG_BS 7 typedef nx_struct SerialReqPacket { nx_uint8_t msg_type; diff --git a/tos/lib/net/Deluge/FlashVolumeManager/FlashVolumeManagerC.nc b/tos/lib/net/Deluge/FlashVolumeManager/FlashVolumeManagerC.nc index 12e7779e..d1f9fbe7 100644 --- a/tos/lib/net/Deluge/FlashVolumeManager/FlashVolumeManagerC.nc +++ b/tos/lib/net/Deluge/FlashVolumeManager/FlashVolumeManagerC.nc @@ -30,7 +30,8 @@ generic configuration FlashVolumeManagerC(am_id_t AMId) { #ifdef DELUGE - provides interface Notify; + provides interface Notify as DissNotify; + provides interface Notify as ReprogNotify; #endif uses { interface BlockRead[uint8_t img_num]; @@ -63,6 +64,7 @@ implementation FlashVolumeManagerP.Timer -> TimerMilliC; FlashVolumeManagerP.DelugeStorage[VOLUME_DELUGE0] = DelugeStorage[VOLUME_DELUGE0]; FlashVolumeManagerP.DelugeStorage[VOLUME_DELUGE1] = DelugeStorage[VOLUME_DELUGE1]; - Notify = FlashVolumeManagerP.Notify; + DissNotify = FlashVolumeManagerP.DissNotify; + ReprogNotify = FlashVolumeManagerP.ReprogNotify; #endif } diff --git a/tos/lib/net/Deluge/FlashVolumeManager/FlashVolumeManagerP.nc b/tos/lib/net/Deluge/FlashVolumeManager/FlashVolumeManagerP.nc index 78cda769..216c00d2 100644 --- a/tos/lib/net/Deluge/FlashVolumeManager/FlashVolumeManagerP.nc +++ b/tos/lib/net/Deluge/FlashVolumeManager/FlashVolumeManagerP.nc @@ -29,7 +29,10 @@ generic module FlashVolumeManagerP() { #ifdef DELUGE - provides interface Notify; + provides { + interface Notify as DissNotify; + interface Notify as ReprogNotify; + } #endif uses { interface BlockRead[uint8_t img_num]; @@ -183,14 +186,18 @@ implementation (uint32_t)call DelugeStorage.getPhysicalAddress[img_num](0); sendReply(SUCCESS, sizeof(SerialReplyPacket) + 4); break; - case SERIALMSG_REPROG: // === Reboots and reprograms === + case SERIALMSG_REPROG_BS: // === Reprograms only the base station === state = S_REPROG; sendReply(SUCCESS, sizeof(SerialReplyPacket)); img_num_reboot = img_num; call Timer.startOneShot(1024); break; case SERIALMSG_DISS: // === Starts disseminating a volume === - signal Notify.notify(img_num); // Notifies Deluge to start disseminate + signal DissNotify.notify(img_num); // Notifies Deluge to start disseminate + sendReply(SUCCESS, sizeof(SerialReplyPacket)); + break; + case SERIALMSG_REPROG: // === Reprograms the network (except the base station) === + signal ReprogNotify.notify(img_num); sendReply(SUCCESS, sizeof(SerialReplyPacket)); break; #endif @@ -215,8 +222,10 @@ implementation call NetProg.programImgAndReboot(img_num_reboot); } - command error_t Notify.enable() { return SUCCESS; } - command error_t Notify.disable() { return SUCCESS; } + command error_t DissNotify.enable() { return SUCCESS; } + command error_t DissNotify.disable() { return SUCCESS; } + command error_t ReprogNotify.enable() { return SUCCESS; } + command error_t ReprogNotify.disable() { return SUCCESS; } default command storage_addr_t DelugeStorage.getPhysicalAddress[uint8_t img_num](storage_addr_t addr) { return 0; } #endif diff --git a/tos/lib/net/Deluge/ObjectTransferP.nc b/tos/lib/net/Deluge/ObjectTransferP.nc index ed9da3de..777a6cfa 100644 --- a/tos/lib/net/Deluge/ObjectTransferP.nc +++ b/tos/lib/net/Deluge/ObjectTransferP.nc @@ -112,6 +112,7 @@ implementation } else { call DelugePageTransfer.setWorkingPage(DELUGE_INVALID_OBJID, DELUGE_INVALID_PGNUM); state = S_SYNC; + call ObjectTransfer.stop(); call BlockWrite.sync[cont_receive_img_num](); } } @@ -209,7 +210,6 @@ implementation error_t error; call ObjectTransfer.stop(); - state = S_STOPPED; //call StatsCollector.startStatsCollector(); cont_receive_new_objid = new_objid; @@ -228,12 +228,13 @@ implementation { call Timer.stop(); call DelugePageTransfer.stop(); + state = S_STOPPED; //call StatsCollector.stopStatsCollector(); - state = S_STOPPED; curObjDesc.objid = DELUGE_INVALID_OBJID; curObjDesc.numPgs = DELUGE_INVALID_PGNUM; curObjDesc.numPgsComplete = DELUGE_INVALID_PGNUM; + advTimers.periodLog2 = 0; return SUCCESS; } @@ -248,6 +249,7 @@ implementation } else { call DelugePageTransfer.setWorkingPage(curObjDesc.objid, curObjDesc.numPgsComplete); state = S_SYNC; + call ObjectTransfer.stop(); call BlockWrite.sync[cont_receive_img_num](); } } @@ -256,9 +258,6 @@ implementation event void BlockWrite.syncDone[uint8_t img_num](error_t error) { if (state == S_SYNC) { - if (error != SUCCESS) { - call Leds.led2On(); - } post signalObjRecvDone(); } } @@ -317,7 +316,7 @@ implementation } event void Timer.fired() - { + { updateTimers(); if (advTimers.overheard == 0) { diff --git a/tos/lib/net/Deluge/extra/NetProgM.nc b/tos/lib/net/Deluge/extra/NetProgM.nc index ab122f4d..413abc00 100644 --- a/tos/lib/net/Deluge/extra/NetProgM.nc +++ b/tos/lib/net/Deluge/extra/NetProgM.nc @@ -122,6 +122,7 @@ implementation { imgDesc = call DelugeMetadata.getImgDesc(img_num); nodeDesc.uid = imgDesc->uid; nodeDesc.imgNum = img_num; + nodeDesc.vNum = imgDesc->vNum; call IFlash.write((uint8_t*)IFLASH_NODE_DESC_ADDR, &nodeDesc, sizeof(nodeDesc)); // reboot -- 2.39.2