X-Git-Url: https://oss.titaniummirror.com/gitweb/?a=blobdiff_plain;f=tools%2Ftinyos%2Fmisc%2Ftos-deluge;h=78b0f6625d78ad2a80602f595fc29c382c4bcad2;hb=7195b80d9bdc58ede68198716c5a619c6486278e;hp=88e6dccbcbcf6e2ee116e7c11f99bbef2479e848;hpb=e014c5d251e1706ee383c01597ed49173c00c8f3;p=tinyos-2.x.git diff --git a/tools/tinyos/misc/tos-deluge b/tools/tinyos/misc/tos-deluge index 88e6dccb..78b0f662 100755 --- a/tools/tinyos/misc/tos-deluge +++ b/tools/tinyos/misc/tos-deluge @@ -1,19 +1,44 @@ #!/usr/bin/env python -import sys, stat, struct, subprocess, time -import tinyos +# Copyright (c) 2007 Johns Hopkins University. +# 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 (updated) modification history and the author appear in +# all copies of this source code. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, LOSS OF USE, DATA, +# OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +# THE POSSIBILITY OF SUCH DAMAGE. + +# @author Razvan Musaloiu-E. +# @author Chieh-Jan Mike Liang + +import sys, stat, struct, subprocess, time, os.path +try: + import tos +except ImportError: + import posix + sys.path = [os.path.join(posix.environ['TOSROOT'], 'support', 'sdk', 'python')] + sys.path + import tos from datetime import datetime -import os.path # Path to the python script that builds Deluge image from XML -PATH_PY_BUILD_IMAGE = './tos-build-deluge-image' +PATH_PY_BUILD_IMAGE = os.path.join(os.path.dirname(sys.argv[0]), 'tos-build-deluge-image') # TinyOS serial communication parameters -FM_AMID = 0xAB -DM_AMID = 0xAC +FM_AMID = 0x53 +DM_AMID = 0x54 SERIAL_DATA_LENGTH = 28 - 1 - 1 - 2 - 2 -BAUDRATES = {'micaz': 57600, - 'telosb': 115200} # Commands for FlashManager FM_CMD_ERASE = 0 @@ -40,54 +65,54 @@ DELUGE_MAX_PAGES = 128 DELUGE_IDENT_OFFSET = 0 DELUGE_IDENT_SIZE = 128 -class FMReqPacket(tinyos.GenericPacket): +class FMReqPacket(tos.Packet): def __init__(self, packet = None): - tinyos.GenericPacket.__init__(self, - [('cmd', 'int', 1), - ('imgNum', 'int', 1), - ('offset', 'int', 2), - ('length', 'int', 2), - ('data', 'blob', None)], - packet) - -class DMReqPacket(tinyos.GenericPacket): + tos.Packet.__init__(self, + [('cmd', 'int', 1), + ('imgNum', 'int', 1), + ('offset', 'int', 4), + ('length', 'int', 2), + ('data', 'blob', None)], + packet) + +class DMReqPacket(tos.Packet): def __init__(self, packet = None): - tinyos.GenericPacket.__init__(self, - [('cmd', 'int', 1), - ('imgNum', 'int', 1)], - packet) + tos.Packet.__init__(self, + [('cmd', 'int', 1), + ('imgNum', 'int', 1)], + packet) -class SerialReplyPacket(tinyos.GenericPacket): +class SerialReplyPacket(tos.Packet): def __init__(self, packet = None): - tinyos.GenericPacket.__init__(self, - [('error', 'int', 1), - ('data', 'blob', None)], - packet) + tos.Packet.__init__(self, + [('error', 'int', 1), + ('data', 'blob', None)], + packet) -class Ident(tinyos.GenericPacket): +class Ident(tos.Packet): def __init__(self, packet = None): - tinyos.GenericPacket.__init__(self, - [('uidhash', 'int', 4), - ('size', 'int', 4), - ('pages', 'int', 1), - ('reserved', 'int', 1), - ('crc', 'int', 2), - ('appname', 'string', 16), - ('username', 'string', 16), - ('hostname', 'string', 16), - ('platform', 'string', 16), - ('timestamp','int', 4), - ('userhash', 'int', 4)], - packet) - -class ShortIdent(tinyos.GenericPacket): + tos.Packet.__init__(self, + [('uidhash', 'int', 4), + ('size', 'int', 4), + ('pages', 'int', 1), + ('reserved', 'int', 1), + ('crc', 'int', 2), + ('appname', 'string', 16), + ('username', 'string', 16), + ('hostname', 'string', 16), + ('platform', 'string', 16), + ('timestamp','int', 4), + ('userhash', 'int', 4)], + packet) + +class ShortIdent(tos.Packet): def __init__(self, packet = None): - tinyos.GenericPacket.__init__(self, - [('appname', 'string', 16), - ('timestamp','int', 4), - ('uidhash', 'int', 4), - ('nodeid', 'int', 2)], - packet) + tos.Packet.__init__(self, + [('appname', 'string', 16), + ('timestamp','int', 4), + ('uidhash', 'int', 4), + ('nodeid', 'int', 2)], + packet) # Computes 16-bit CRC @@ -101,30 +126,32 @@ def crc16(data): else: crc = crc << 1 crc = crc & 0xffff - + return crc def handleResponse(success, msg): if success == True: - packet = s.sniff_am() + packet = am.read(timeout=2) while packet and packet.type == 100: - print "".join([chr(i) for i in p.data]) - packet = s.sniff_am() + print "".join([chr(i) for i in packet.data]) + packet = am.read() + if not packet: + print "No response" + return False reply = SerialReplyPacket(packet.data) if reply.error == ERROR_SUCCESS: - print reply return True else: print msg, reply return False - + print "ERROR: Unable to send the command" return False -def ident(): +def ident(timeout=None): sreqpkt = FMReqPacket((FM_CMD_IDENT, 0, 0, 0, [])) - if s.write(tinyos.ActiveMessage(sreqpkt, am_id=FM_AMID)): - packet = s.sniff_am() + if am.write(sreqpkt, FM_AMID, timeout=timeout): + packet = am.read(timeout=timeout) reply = SerialReplyPacket(packet.data) if reply.error == ERROR_SUCCESS: return ShortIdent(reply.data) @@ -132,14 +159,14 @@ def ident(): def read(imgNum, offset, length): r = [] - + sreqpkt = FMReqPacket((FM_CMD_READ, imgNum, offset, length, [])) while True: if sreqpkt.length > SERIAL_DATA_LENGTH: sreqpkt.length = SERIAL_DATA_LENGTH - - if s.write(tinyos.ActiveMessage(sreqpkt, am_id=FM_AMID)): - packet = s.sniff_am() + + if am.write(sreqpkt, FM_AMID): + packet = am.read() reply = SerialReplyPacket(packet.data) if reply.error == ERROR_SUCCESS: r.extend(reply.data) @@ -149,7 +176,7 @@ def read(imgNum, offset, length): else: r = None break - + sreqpkt.offset += sreqpkt.length if sreqpkt.offset >= (offset + length): break @@ -158,13 +185,27 @@ def read(imgNum, offset, length): return r def erase(imgNum): + # Note: the normal erase doesn't work properly on AT45DB. A + # workaround is to do the normal erase (to make happy STM25P) + # and then overwrite the metadata (to make happy AT45DB). + sreqpkt = FMReqPacket((FM_CMD_ERASE, imgNum, 0, 0, [])) - success = s.write(tinyos.ActiveMessage(sreqpkt, am_id=FM_AMID)) - return handleResponse(success, "ERROR: Unable to erase the flash volume") + success = am.write(sreqpkt, FM_AMID) + result = handleResponse(success, "ERROR: Unable to erase the flash volume") + if result: return True; + + print 'Attempt the workaround for AT45DB...' + sreqpkt = FMReqPacket((FM_CMD_WRITE, imgNum, 0, 0, [])) + sreqpkt.data = [0xFF] * DELUGE_IDENT_SIZE + sreqpkt.length = DELUGE_IDENT_SIZE + success = am.write(sreqpkt, FM_AMID) + result = handleResponse(success, "ERROR: Unable to erase the flash volume") + if not result: return False; + return sync(imgNum) def sync(imgNum): sreqpkt = FMReqPacket((FM_CMD_SYNC, imgNum, 0, 0, [])) - success = s.write(tinyos.ActiveMessage(sreqpkt, am_id=FM_AMID)) + success = am.write(sreqpkt, FM_AMID) return handleResponse(success, "ERROR: Unable to sync the flash volume") def write(imgNum, data): @@ -173,37 +214,37 @@ def write(imgNum, data): total_length = length # For progress bar next_tick = 100 # For progress bar start_time = time.time() - + print "[0% 25% 50% 75% 100%]\r[", - + sreqpkt.offset = 0 while length > 0: if ((length * 100) / total_length) < next_tick: next_tick = next_tick - 2 sys.stdout.write('-') sys.stdout.flush() - + # Calculates the payload size for the current packet if length >= SERIAL_DATA_LENGTH: sreqpkt.length = SERIAL_DATA_LENGTH else: sreqpkt.length = length sreqpkt.data = data[sreqpkt.offset:sreqpkt.offset+sreqpkt.length] - + # Sends over serial to the mote - if not s.write(tinyos.ActiveMessage(sreqpkt, am_id=FM_AMID)): + if not am.write(sreqpkt, FM_AMID): print print "ERROR: Unable to send the last serial packet (file offset: %d)" % sreqpkt.offset return False - + # Waiting for confirmation - packet = s.sniff_am() + packet = am.read() reply = SerialReplyPacket(packet.data) if reply.error != ERROR_SUCCESS: print print "ERROR: Unable to write to the flash volume (file offset: %d)" % sreqpkt.offset return False - + length -= sreqpkt.length sreqpkt.offset += sreqpkt.length @@ -211,7 +252,7 @@ def write(imgNum, data): elasped_time = time.time() - start_time print "\r%s bytes in %.2f seconds (%.4f bytes/s)" % (total_length, elasped_time, int(total_length) / (elasped_time)) return True - + # Checks for valid CRC and timestamp def verifyIdent(i): if i != None: @@ -260,7 +301,7 @@ def inject(imgNum, tos_image_xml): except: print "ERROR: Unable to find the image building utility, \"%s\"" % PATH_PY_BUILD_IMAGE return False - + # Gets status information of stored image i = getIdent(imgNum) if ident: @@ -277,11 +318,12 @@ def inject(imgNum, tos_image_xml): cmd = [PATH_PY_BUILD_IMAGE, "-i", str(imgNum), tos_image_xml] print "Create image:", ' '.join(cmd) p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - print p.stderr.read(), + (out, err) = p.communicate(None) + print err, print "--------------------------------------------------" - + # Writes the new binary image - image = [struct.unpack("B", c)[0] for c in p.stdout.read()] + image = [struct.unpack("B", c)[0] for c in out] if len(image) > 0 and erase(imgNum): if write(imgNum, image): if sync(imgNum): @@ -289,7 +331,7 @@ def inject(imgNum, tos_image_xml): print "Replace image with:" print formatIdent(getIdent(imgNum)) print "--------------------------------------------------" - + return False def ping(imgNum): @@ -304,43 +346,45 @@ def ping(imgNum): print formatIdent(i) print "--------------------------------------------------" return True - + print "--------------------------------------------------" return False def boot(): sreqpkt = DMReqPacket((DM_CMD_BOOT, 0)) - success = s.write(tinyos.ActiveMessage(sreqpkt, am_id=DM_AMID)) + success = am.write(sreqpkt, DM_AMID) return handleResponse(success, "ERROR: Unable to boot the mote") def reprogram(imgNum): sreqpkt = DMReqPacket((DM_CMD_REPROGRAM, imgNum)) - success = s.write(tinyos.ActiveMessage(sreqpkt, am_id=DM_AMID)) + success = am.write(sreqpkt, DM_AMID) return handleResponse(success, "ERROR: Unable to reprogram the mote") def disseminate(imgNum): sreqpkt = DMReqPacket((DM_CMD_ONLY_DISSEMINATE, imgNum)) - success = s.write(tinyos.ActiveMessage(sreqpkt, am_id=DM_AMID)) + success = am.write(sreqpkt, DM_AMID) return handleResponse(success, "ERROR: Unable to disseminate") def disseminateAndReboot(imgNum): sreqpkt = DMReqPacket((DM_CMD_DISSEMINATE_AND_REPROGRAM, imgNum)) - success = s.write(tinyos.ActiveMessage(sreqpkt, am_id=DM_AMID)) + success = am.write(sreqpkt, DM_AMID) return handleResponse(success, "ERROR: Unable to disseminate-and-reboot") def stop(): sreqpkt = DMReqPacket((DM_CMD_STOP, 0)) - success = s.write(tinyos.ActiveMessage(sreqpkt, am_id=DM_AMID)) + success = am.write(sreqpkt, DM_AMID) return handleResponse(success, "ERROR: Unable to initiate the stop") def localstop(): sreqpkt = DMReqPacket((DM_CMD_LOCAL_STOP, 0)) - success = s.write(tinyos.ActiveMessage(sreqpkt, am_id=DM_AMID)) + success = am.write(sreqpkt, DM_AMID) return handleResponse(success, "ERROR: Unable to initiate the local stop") def print_usage(): - print "Usage: %s <-p|-i|-r|-d|-e|-s> image_number [options]" % sys.argv[0] - print " Either the platform name (micaz or telosv) or a baudrate value" + print "Usage: %s <-p|-i|-r|-d|-e|-s> image_number [options]" % sys.argv[0] + print " can be:" + print " serial@PORT:SPEED Serial ports" + print " network@HOST:PORT MIB600" print " -p --ping Provide status of the image in the external flash" print " -i --inject Inject a compiled TinyOS application" print " [options]: tos_image.xml file path" @@ -359,72 +403,57 @@ def checkImgNum(): global imgNum # Checks for valid image number format try: - imgNum = int(sys.argv[4]) + imgNum = int(sys.argv[3]) except: print "ERROR: Image number is not valid" sys.exit(-1) return imgNum # ======== MAIN ======== # -if len(sys.argv) >= 4: +if len(sys.argv) >= 3: + + am = tos.AM() - if sys.argv[2] in BAUDRATES: - baudrate = BAUDRATES[sys.argv[2]] - else: - try: - baudrate = int(sys.argv[2]) - except: - print "ERROR: Wrong baudrate" - sys.exit(-1) - - # Initializes serial port communication try: - s = tinyos.Serial(sys.argv[1], baudrate, flush=False) - except: - print "ERROR: Unable to initialize serial port connection to", sys.argv[1] + print "Checking if node is a Deluge T2 base station ..." + ident(timeout=5) + except tos.Timeout: + print "ERROR: Timeout. Is the node a Deluge T2 base station?" sys.exit(-1) - if sys.argv[3] in ["-p", "--ping"]: + if sys.argv[2] in ["-p", "--ping"]: checkImgNum() print "Pinging node ..." - ping(imgNum) - elif sys.argv[3] in ["-i", "--inject"] and len(sys.argv) == 6: + ping(imgNum) + elif sys.argv[2] in ["-i", "--inject"] and len(sys.argv) == 5: checkImgNum() print "Pinging node ..." - inject(imgNum, sys.argv[5]) - elif sys.argv[3] in ["-e", "--erase"]: + inject(imgNum, sys.argv[4]) + elif sys.argv[2] in ["-e", "--erase"]: checkImgNum() if erase(imgNum): print "Image number %d erased" % imgNum - elif sys.argv[3] in ["-b", "--boot"]: + elif sys.argv[2] in ["-b", "--boot"]: if boot(): print "Command sent" - elif sys.argv[3] in ["-r", "--reprogram"]: + elif sys.argv[2] in ["-r", "--reprogram"]: checkImgNum() if reprogram(imgNum): print "Command sent" - elif sys.argv[3] in ["-d", "--disseminate"]: + elif sys.argv[2] in ["-d", "--disseminate"]: checkImgNum() if disseminate(imgNum): print "Command sent" - elif sys.argv[3] in ["-dr", "--disseminate-and-reboot"]: + elif sys.argv[2] in ["-dr", "--disseminate-and-reboot"]: checkImgNum() if disseminateAndReboot(imgNum): print "Command sent" - elif sys.argv[3] in ["-s", "--stop"]: + elif sys.argv[2] in ["-s", "--stop"]: if stop(): print "Command sent" - elif sys.argv[3] in ["-ls", "--local-stop"]: + elif sys.argv[2] in ["-ls", "--local-stop"]: if localstop(): print "Command sent" - - -# elif sys.argv[3] in ["-b", "--reprogram_bs"]: -# if op_reprog_bs(imgNum): -# print "Command sent" -# elif sys.argv[3] in ["-s", "--reset"]: -# if op_reset(imgNum): -# print "Successfully reset image versioning information" else: print_usage() @@ -433,32 +462,3 @@ else: sys.exit() -# Testing ------------------------------------------------------------ - -s = tinyos.Serial('/dev/ttyUSB0', 115200, flush=False) -# print "ident: 0x%x" % ident() -# r = read(0, 0, 10) -# print "read:", len(r), r - -# erase(0) -# write(0, [i % 256 for i in range(20*1024)]) -# r = read(0, 0, 10) -# print "read:", len(r), r - -# inject(0, 'build/telosb/tos_image.xml') -ping(0) - -# print formatDescription(getMetadata(0), getIdent(0)) -# print getMetadata(0) -# print getIdent(0) - -# print verifyDescription(getMetadata(0), getIdent(0)) - -# print formatShortIdent(ident()) - -# def encode(val, dim): -# output = [] -# for i in range(dim): -# output.append(val & 0xFF) -# val = val >> 8 -# return output