📄 tos-deluge
字号:
#!/usr/bin/env python
# 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. <razvanm@cs.jhu.edu>
# @author Chieh-Jan Mike Liang <cliang4@cs.jhu.edu>
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
# Path to the python script that builds Deluge image from XML
PATH_PY_BUILD_IMAGE = os.path.join(os.path.dirname(sys.argv[0]), 'tos-build-deluge-image')
# TinyOS serial communication parameters
FM_AMID = 0x53
DM_AMID = 0x54
SERIAL_DATA_LENGTH = 28 - 1 - 1 - 2 - 2
# Commands for FlashManager
FM_CMD_ERASE = 0
FM_CMD_WRITE = 1
FM_CMD_READ = 2
FM_CMD_CRC = 3
FM_CMD_ADDR = 4
FM_CMD_SYNC = 5
FM_CMD_IDENT = 6
# Commands for DelugeManager
DM_CMD_STOP = 1
DM_CMD_LOCAL_STOP = 2
DM_CMD_ONLY_DISSEMINATE = 3
DM_CMD_DISSEMINATE_AND_REPROGRAM = 4
DM_CMD_REPROGRAM = 5
DM_CMD_BOOT = 6
ERROR_SUCCESS = 0 # T2-compatible
ERROR_FAIL = 1 # T2-compatible
# Deluge parameters
DELUGE_MAX_PAGES = 128
DELUGE_IDENT_OFFSET = 0
DELUGE_IDENT_SIZE = 128
class FMReqPacket(tos.Packet):
def __init__(self, packet = None):
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):
tos.Packet.__init__(self,
[('cmd', 'int', 1),
('imgNum', 'int', 1)],
packet)
class SerialReplyPacket(tos.Packet):
def __init__(self, packet = None):
tos.Packet.__init__(self,
[('error', 'int', 1),
('data', 'blob', None)],
packet)
class Ident(tos.Packet):
def __init__(self, packet = None):
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):
tos.Packet.__init__(self,
[('appname', 'string', 16),
('timestamp','int', 4),
('uidhash', 'int', 4),
('nodeid', 'int', 2)],
packet)
# Computes 16-bit CRC
def crc16(data):
crc = 0
for b in data:
crc = crc ^ (b << 8)
for i in range(0, 8):
if crc & 0x8000 == 0x8000:
crc = (crc << 1) ^ 0x1021
else:
crc = crc << 1
crc = crc & 0xffff
return crc
def handleResponse(success, msg):
if success == True:
packet = am.read(timeout=2)
while packet and packet.type == 100:
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:
return True
else:
print msg, reply
return False
print "ERROR: Unable to send the command"
return False
def ident(timeout=None):
sreqpkt = FMReqPacket((FM_CMD_IDENT, 0, 0, 0, []))
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)
return 0
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 am.write(sreqpkt, FM_AMID):
packet = am.read()
reply = SerialReplyPacket(packet.data)
if reply.error == ERROR_SUCCESS:
r.extend(reply.data)
else:
r = None
break
else:
r = None
break
sreqpkt.offset += sreqpkt.length
if sreqpkt.offset >= (offset + length):
break
sreqpkt.length = (offset + length) - sreqpkt.offset
return r
def erase(imgNum):
sreqpkt = FMReqPacket((FM_CMD_ERASE, imgNum, 0, 0, []))
success = am.write(sreqpkt, FM_AMID)
return handleResponse(success, "ERROR: Unable to erase the flash volume")
def sync(imgNum):
sreqpkt = FMReqPacket((FM_CMD_SYNC, imgNum, 0, 0, []))
success = am.write(sreqpkt, FM_AMID)
return handleResponse(success, "ERROR: Unable to sync the flash volume")
def write(imgNum, data):
sreqpkt = FMReqPacket((FM_CMD_WRITE, imgNum, 0, 0, []))
length = len(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 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -