[Tinyos-2-commits] CVS: tinyos-2.x/apps/tosthreads/tinyld/SerialLoaderFlash FlashVolumeManager.h, NONE, 1.1 FlashVolumeManagerC.nc, NONE, 1.1 FlashVolumeManagerP.nc, NONE, 1.1 Makefile, NONE, 1.1 README, NONE, 1.1 SerialLoaderFlashAppC.nc, NONE, 1.1 serialloader.py, NONE, 1.1 tinyos.py, NONE, 1.1 volumes-stm25p.xml, NONE, 1.1
Chieh-Jan Mike Liang
liang_mike at users.sourceforge.net
Wed Feb 4 20:12:57 PST 2009
Update of /cvsroot/tinyos/tinyos-2.x/apps/tosthreads/tinyld/SerialLoaderFlash
In directory ddv4jf1.ch3.sourceforge.com:/tmp/cvs-serv29587/SerialLoaderFlash
Added Files:
FlashVolumeManager.h FlashVolumeManagerC.nc
FlashVolumeManagerP.nc Makefile README
SerialLoaderFlashAppC.nc serialloader.py tinyos.py
volumes-stm25p.xml
Log Message:
Add the external flash version of SerialLoader to demonstrate TinyLD
--- NEW FILE: FlashVolumeManager.h ---
/*
* Copyright (c) 2008 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 Chieh-Jan Mike Liang <cliang4 at cs.jhu.edu>
*/
#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_LEDS 5
#define SERIALMSG_RUN 7
typedef nx_struct SerialReqPacket {
nx_uint8_t msg_type;
nx_uint8_t pad;
nx_uint16_t offset;
nx_uint16_t len;
nx_uint8_t data[0];
} SerialReqPacket;
#define SERIALMSG_SUCCESS 0
#define SERIALMSG_FAIL 1
typedef nx_struct SerialReplyPacket {
nx_uint8_t error;
nx_uint8_t pad;
nx_uint8_t data[0];
} SerialReplyPacket;
#endif
--- NEW FILE: FlashVolumeManagerC.nc ---
/*
* Copyright (c) 2008 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 Chieh-Jan Mike Liang <cliang4 at cs.jhu.edu>
*/
#include "AM.h"
generic configuration FlashVolumeManagerC(am_id_t AMId)
{
uses {
interface BlockRead;
interface BlockWrite;
interface DynamicLoader;
}
}
implementation
{
components MainC,
SerialActiveMessageC,
new SerialAMSenderC(AMId),
new SerialAMReceiverC(AMId),
new FlashVolumeManagerP(),
NoLedsC, LedsC;
DynamicLoader = FlashVolumeManagerP;
BlockRead = FlashVolumeManagerP;
BlockWrite = FlashVolumeManagerP;
FlashVolumeManagerP.Boot -> MainC;
FlashVolumeManagerP.SerialSplitControl -> SerialActiveMessageC;
FlashVolumeManagerP.SerialAMSender -> SerialAMSenderC;
FlashVolumeManagerP.SerialAMReceiver -> SerialAMReceiverC;
FlashVolumeManagerP.Leds -> LedsC;
}
--- NEW FILE: FlashVolumeManagerP.nc ---
/*
* Copyright (c) 2008 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 Chieh-Jan Mike Liang <cliang4 at cs.jhu.edu>
*/
#include "FlashVolumeManager.h"
#include "StorageVolumes.h"
generic module FlashVolumeManagerP()
{
uses {
interface Boot;
interface SplitControl as SerialSplitControl;
interface BlockRead;
interface BlockWrite;
interface AMSend as SerialAMSender;
interface Receive as SerialAMReceiver;
interface Leds;
interface DynamicLoader;
}
}
implementation
{
message_t serialMsg;
storage_addr_t dumpAddr = 0;
event void Boot.booted() {
while (call SerialSplitControl.start() != SUCCESS);
}
event void SerialSplitControl.startDone(error_t error)
{
if (error != SUCCESS) {
while (call SerialSplitControl.start() != SUCCESS);
}
}
void sendReply(error_t error, storage_len_t len)
{
SerialReplyPacket *srpkt = (SerialReplyPacket *)call SerialAMSender.getPayload(&serialMsg, sizeof(SerialReplyPacket));
if (error == SUCCESS) {
srpkt->error = SERIALMSG_SUCCESS;
} else {
srpkt->error = SERIALMSG_FAIL;
}
call SerialAMSender.send(AM_BROADCAST_ADDR, &serialMsg, len);
}
event void BlockRead.readDone(storage_addr_t addr, void* buf, storage_len_t len, error_t error) {
sendReply(error, len + sizeof(SerialReplyPacket));
}
event void BlockRead.computeCrcDone(storage_addr_t addr, storage_len_t len, uint16_t crc, error_t error)
{
if (error == SUCCESS) {
SerialReplyPacket *srpkt = (SerialReplyPacket *)call SerialAMSender.getPayload(&serialMsg, sizeof(SerialReplyPacket));
srpkt->data[1] = crc & 0xFF;
srpkt->data[0] = (crc >> 8) & 0xFF;
}
sendReply(error, 2 + sizeof(SerialReplyPacket));
}
event void BlockWrite.writeDone(storage_addr_t addr, void* buf, storage_len_t len, error_t error)
{
if (error != SUCCESS) {
call Leds.led1On();
}
sendReply(error, sizeof(SerialReplyPacket));
}
event void BlockWrite.eraseDone(error_t error) {
sendReply(error, sizeof(SerialReplyPacket));
}
event message_t* SerialAMReceiver.receive(message_t* msg, void* payload, uint8_t len)
{
uint16_t i;
error_t error = SUCCESS;
SerialReqPacket *srpkt = (SerialReqPacket *)payload;
SerialReplyPacket *serialMsg_payload = (SerialReplyPacket *)call SerialAMSender.getPayload(&serialMsg, sizeof(SerialReplyPacket));
switch (srpkt->msg_type) {
case SERIALMSG_ERASE :
error = call BlockWrite.erase();
if (error != SUCCESS) {
sendReply(error, sizeof(SerialReplyPacket));
}
break;
case SERIALMSG_WRITE :
call Leds.led2On();
error = call BlockWrite.write(srpkt->offset, srpkt->data, srpkt->len);
if (error != SUCCESS) {
sendReply(error, sizeof(SerialReplyPacket));
call Leds.led0On();
}
break;
case SERIALMSG_READ :
error = call BlockRead.read(srpkt->offset, serialMsg_payload->data, srpkt->len);
if (error != SUCCESS) {
sendReply(error, sizeof(SerialReplyPacket));
}
break;
case SERIALMSG_CRC :
error = call BlockRead.computeCrc(srpkt->offset, srpkt->len, 0);
if (error != SUCCESS) {
sendReply(error, sizeof(SerialReplyPacket));
}
break;
case SERIALMSG_LEDS:
call Leds.set(7);
for (i = 0; i < 2000; i++) {}
call Leds.set(0);
break;
case SERIALMSG_RUN :
error = call DynamicLoader.loadFromFlash(VOLUME_MICROEXEIMAGE);
if (error != SUCCESS)
sendReply(error, sizeof(SerialReplyPacket));
break;
}
return msg;
}
event void DynamicLoader.loadFromFlashDone(uint8_t volumeId, tosthread_t id, error_t error) {
sendReply(error, sizeof(SerialReplyPacket));
}
event void DynamicLoader.loadFromMemoryDone(void *addr, tosthread_t id, error_t error) {}
event void BlockWrite.syncDone(error_t error) {}
event void SerialAMSender.sendDone(message_t* msg, error_t error) {}
event void SerialSplitControl.stopDone(error_t error) {}
}
--- NEW FILE: Makefile ---
COMPONENT=SerialLoaderFlashAppC
GOALS += threads
THREADS_DIR ?= $(TOSDIR)/lib/tosthreads
CFLAGS += -I$(THREADS_DIR)/lib/tinyld
CFLAGS += -I$(THREADS_DIR)/csystem
CFLAGS += -I$(THREADS_DIR)/sensorboards/tmote_onboard
CFLAGS += -I$(THREADS_DIR)/sensorboards/universal
CFLAGS += -I$(THREADS_DIR)/lib/net/ctp
CFLAGS += -I$(THREADS_DIR)/lib/net
CFLAGS += -I$(TOSDIR)/lib/net
CFLAGS += -I$(TOSDIR)/lib/net/ctp
CFLAGS += -I$(TOSDIR)/lib/net/4bitle
CFLAGS += -I$(THREADS_DIR)/lib/printf
# Creates VolumeMapC.nc
VOLUME_ALLOCATOR_FLAGS += -t
CLEAN_EXTRA += *.pyc
include $(MAKERULES)
--- NEW FILE: README ---
README for SerialLoaderFlash
Author/Contact: Chieh-Jan Mike Liang <cliang4 at cs.jhu.edu>
Description:
SerialLoaderFlash is similar to SerialLoader in that it receives
loadable programs from the serial port. However, SerialLoaderFlash
stores them on the external flash. Then, when it receives the command to
load the code, it makes the call to the dynamic loader.
Here are the steps:
1.) Load SerialLoader:
make telosb install bsl,<device_port>
2.) Create the loadable code, Blink.tos:
tosthreads-gen-dynamic-app ../../capps/Blink/Blink.c
3.) Erase the external flash:
./serialloader.py <device_port> 0
4.) Upload the binary:
./serialloader.py <device_port> 1 Blink.tos
5.) Run the binary:
./serialloader.py <device_port> 7
--- NEW FILE: SerialLoaderFlashAppC.nc ---
/*
* Copyright (c) 2008 Stanford University.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
* - Neither the name of the Stanford University nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* 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 STANFORD
* UNIVERSITY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* 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 Kevin Klues (klueska at cs.stanford.edu)
* @author Chieh-Jan Mike Liang <cliang4 at cs.jhu.edu>
*/
#include "StorageVolumes.h"
configuration SerialLoaderFlashAppC {}
implementation {
components DynamicLoaderC,
new FlashVolumeManagerC(0xAB),
new BlockStorageC(VOLUME_MICROEXEIMAGE) as ImageVolume;
FlashVolumeManagerC.BlockRead -> ImageVolume;
FlashVolumeManagerC.BlockWrite -> ImageVolume;
FlashVolumeManagerC.DynamicLoader -> DynamicLoaderC;
}
--- NEW FILE: serialloader.py ---
#!/usr/bin/env python
# Copyright (c) 2008 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 Chieh-Jan Mike Liang <cliang4 at cs.jhu.edu>
import sys, os, stat, struct
import tinyos
SERIALMSG_AMGROUP = 0
SERIALMSG_AMID = 0xAB
SERIALMSG_ERASE = 0
SERIALMSG_WRITE = 1
SERIALMSG_READ = 2
SERIALMSG_CRC = 3
SERIALMSG_LEDS = 5
SERIALMSG_RUN = 7
SERIALMSG_SUCCESS = 0
SERIALMSG_FAIL = 1
SERIALMSG_DATA_PAYLOAD_SIZE = 20
DELUGE_VOLUME_SIZE = 262144
HEX_OUTPUT_LINE_SIZE = 16
class SerialReqPacket(tinyos.GenericPacket):
def __init__(self, packet = None):
tinyos.GenericPacket.__init__(self,
[('msg_type', 'int', 1),
('pad', 'int', 1),
('offset', 'int', 2),
('len', 'int', 2),
('data', 'blob', None)],
packet)
class SerialReplyPacket(tinyos.GenericPacket):
def __init__(self, packet = None):
tinyos.GenericPacket.__init__(self,
[('error', 'int', 1),
('pad', 'int', 1),
('data', 'blob', None)],
packet)
# Display an integer representation of byte stream to hex representation
def print_hex(start_addr, byte_stream):
byte_stream = ["%02x" % one_byte for one_byte in byte_stream] # Converts to each byte to hex
num_iterations = int( (len(byte_stream) - 1) / HEX_OUTPUT_LINE_SIZE )
num_iterations += 1
for i in range(num_iterations):
line = "%07x" % start_addr + " " # Prints memory address
for j in range(HEX_OUTPUT_LINE_SIZE):
if (i * HEX_OUTPUT_LINE_SIZE + j) < len(byte_stream):
line += byte_stream[i * HEX_OUTPUT_LINE_SIZE + j] + " "
print line
start_addr += HEX_OUTPUT_LINE_SIZE
def op_run(s, sreqpkt):
success = s.write_packet(SERIALMSG_AMGROUP, SERIALMSG_AMID, sreqpkt.payload())
if success == True:
packet = s.read_packet()
sreplypkt = SerialReplyPacket(packet[1])
return (sreplypkt.error == SERIALMSG_SUCCESS)
def op_erase(s, sreqpkt):
success = s.write_packet(SERIALMSG_AMGROUP, SERIALMSG_AMID, sreqpkt.payload())
if success == True:
packet = s.read_packet()
sreplypkt = SerialReplyPacket(packet[1])
return (sreplypkt.error == SERIALMSG_SUCCESS)
def op_print(s, sreqpkt, offset, length):
if (offset + length) <= DELUGE_VOLUME_SIZE:
while length > 0:
sreqpkt.offset = offset
# Calculates the payload size for the reply packet
if length >= HEX_OUTPUT_LINE_SIZE:
sreqpkt.len = HEX_OUTPUT_LINE_SIZE
else:
sreqpkt.len = length
success = s.write_packet(SERIALMSG_AMGROUP, SERIALMSG_AMID, sreqpkt.payload())
if success == True:
packet = s.read_packet()
sreplypkt = SerialReplyPacket(packet[1])
if sreplypkt.error != SERIALMSG_SUCCESS:
return False
print_hex(offset, sreplypkt.data)
length -= sreqpkt.len
offset += sreqpkt.len
else:
print "ERROR: Specified offset and length are too large for the flash volume"
return False
return True
def op_write(s, sreqpkt, input_file, length):
local_crc = 0
input_file_size = length
sreqpkt.offset = 0
while length > 0:
# Calculates the payload size for the current packet
if length >= SERIALMSG_DATA_PAYLOAD_SIZE:
sreqpkt.len = SERIALMSG_DATA_PAYLOAD_SIZE
else:
sreqpkt.len = length
sreqpkt.data = []
# Reads in the file we want to transmit
for i in range(sreqpkt.len):
sreqpkt.data.append(struct.unpack("B", input_file.read(1))[0])
# Sends over serial to the mote
if s.write_packet(SERIALMSG_AMGROUP, SERIALMSG_AMID, sreqpkt.payload()) == True:
# Waiting for confirmation
packet = s.read_packet()
sreplypkt = SerialReplyPacket(packet[1])
if sreplypkt.error != SERIALMSG_SUCCESS:
return False
local_crc = s.crc16(local_crc, sreqpkt.data) # Computes running CRC
else:
print "ERROR: Unable to write to flash"
return False
length -= sreqpkt.len
sreqpkt.offset += sreqpkt.len
# Check local and remote CRC
sreqpkt.msg_type = SERIALMSG_CRC
remote_crc = op_crc(s, sreqpkt, 0, input_file_size)
if remote_crc != None:
local_crc = [(local_crc >> 8) & 0xFF, local_crc & 0xFF]
print "Local CRC: " + ("%02x" % local_crc[0]) + " " + ("%02x" % local_crc[1])
print "Remote CRC: " + ("%02x" % remote_crc[0]) + " " + ("%02x" % remote_crc[1])
if remote_crc != local_crc:
print "ERROR: Remote CRC doesn't match local CRC"
return False
else:
print "ERROR: Unable to verify CRC"
return False
return True
def op_crc(s, sreqpkt, offset, length):
sreqpkt.offset = offset
sreqpkt.len = length
success = s.write_packet(SERIALMSG_AMGROUP, SERIALMSG_AMID, sreqpkt.payload())
if success == True:
packet = s.read_packet()
sreplypkt = SerialReplyPacket(packet[1])
if sreplypkt.error == SERIALMSG_SUCCESS:
return sreplypkt.data
else:
return None
def op_leds(s, sreqpkt):
success = s.write_packet(SERIALMSG_AMGROUP, SERIALMSG_AMID, sreqpkt.payload())
# ======== MAIN ======== #
if len(sys.argv) >= 3:
sys.argv[2] = int(sys.argv[2])
s = tinyos.Serial(sys.argv[1], 57600)
s.set_debug(False) # Disables debug msg
sreqpkt = SerialReqPacket((sys.argv[2], 0, 0, 0, [])) # msg_type, pad, offset, length, data
if sys.argv[2] == SERIALMSG_RUN:
if op_run(s, sreqpkt) == True:
print "Loaded image should be running now!"
else:
print "ERROR: Unable to run loaded image"
elif sys.argv[2] == SERIALMSG_ERASE:
if op_erase(s, sreqpkt) == True:
print "Flash volume has been erased"
else:
print "ERROR: Unable to erase flash volume"
elif sys.argv[2] == SERIALMSG_WRITE:
input_file = file(sys.argv[3], 'rb')
fileStats = os.stat(sys.argv[3])
if fileStats[stat.ST_SIZE] <= DELUGE_VOLUME_SIZE:
#sreqpkt = SerialReqPacket((SERIALMSG_LEDS, 0, 0, 0, []))
#op_leds(s, sreqpkt)
sreqpkt = SerialReqPacket((sys.argv[2], 0, 0, 0, []))
if op_write(s, sreqpkt, input_file, fileStats[stat.ST_SIZE]) == True:
print "File has been successfully transmitted (" + str(fileStats[stat.ST_SIZE]) + " bytes)"
else:
print "ERROR: Unable to transmit file"
sreqpkt = SerialReqPacket((SERIALMSG_LEDS, 0, 0, 0, []))
op_leds(s, sreqpkt)
else:
print "ERROR: File is larger than flash volume (" + DELUGE_VOLUME_SIZE + ")"
elif sys.argv[2] == SERIALMSG_READ:
data = op_print(s, sreqpkt, int(sys.argv[3]), int(sys.argv[4]))
if data != True:
print "ERROR: Unable to read the specified range"
elif sys.argv[2] == SERIALMSG_CRC:
remote_crc = op_crc(s, sreqpkt, int(sys.argv[3]), int(sys.argv[4]))
if remote_crc != None:
print_hex(0, remote_crc)
else:
print "ERROR: Unable to compute remote CRC"
--- NEW FILE: tinyos.py ---
import struct, time, serial
class Serial:
HDLC_FLAG_BYTE = 0x7e
HDLC_CTLESC_BYTE = 0x7d
TOS_SERIAL_ACTIVE_MESSAGE_ID = 0
TOS_SERIAL_CC1000_ID = 1
TOS_SERIAL_802_15_4_ID = 2
TOS_SERIAL_UNKNOWN_ID = 255
SERIAL_PROTO_ACK = 67
SERIAL_PROTO_PACKET_ACK = 68
SERIAL_PROTO_PACKET_NOACK = 69
SERIAL_PROTO_PACKET_UNKNOWN = 255
__s = None; # An instance of serial.Serial object
__debug = True # Debug mode
def __init__(self, port, baudrate):
self.__s = serial.Serial(port, baudrate, rtscts=0)
def __format_packet(self, packet):
return " ".join(["%02x" % p for p in packet]) + " | " + \
" ".join(["%d" % p for p in packet])
def crc16(self, base_crc, frame_data):
crc = base_crc
for b in frame_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 __encode(self, val, dim):
output = []
for i in range(dim):
output.append(val & 0xFF)
val = val >> 8
return output
def __decode(self, v):
r = long(0)
for i in v[::-1]:
r = (r << 8) + i
return r
def __get_byte(self):
r = struct.unpack("B", self.__s.read())[0]
return r
def __put_bytes(self, data):
for b in data:
self.__s.write(struct.pack('B', b))
def __unescape(self, packet):
r = []
esc = False
for b in packet:
if esc:
r.append(b ^ 0x20)
esc = False
elif b == self.HDLC_CTLESC_BYTE:
esc = True
else:
r.append(b)
return r
def __escape(self, packet):
r = []
for b in packet:
if b == self.HDLC_FLAG_BYTE or b == self.HDLC_CTLESC_BYTE:
r.append(self.HDLC_CTLESC_BYTE)
r.append(b ^ 0x20)
else:
r.append(b)
return r
def read_packet(self):
d = self.__get_byte()
ts = time.time()
while d != self.HDLC_FLAG_BYTE:
d = self.__get_byte()
ts = time.time()
packet = [d]
d = self.__get_byte()
if d == self.HDLC_FLAG_BYTE:
d = self.__get_byte()
ts = time.time()
else:
packet.append(d)
while d != self.HDLC_FLAG_BYTE:
d = self.__get_byte()
packet.append(d)
un_packet = self.__unescape(packet)
crc = self.crc16(0, un_packet[1:-3])
packet_crc = self.__decode(un_packet[-3:-1])
if crc != packet_crc:
print "Warning: wrong CRC!"
if self.__debug == True:
print "Recv:", self.__format_packet(un_packet)
return (ts, un_packet)
def write_packet(self, am_group, am_id, data):
# The first byte after SERIAL_PROTO_PACKET_ACK is a sequence
# number that will be send back by the mote to ack the receive of
# the data.
packet = [self.SERIAL_PROTO_PACKET_ACK, 0, self.TOS_SERIAL_ACTIVE_MESSAGE_ID,
0xff, 0xff,
0, 0,
len(data), am_group, am_id] + data;
crc = self.crc16(0, packet)
packet.append(crc & 0xff)
packet.append((crc >> 8) & 0xff)
packet = [self.HDLC_FLAG_BYTE] + self.__escape(packet) + [self.HDLC_FLAG_BYTE]
if self.__debug == True:
print "Send:", self.__format_packet(packet)
self.__put_bytes(packet)
# Waiting for ACK
packet = self.read_packet()
if len(packet) > 1 and len(packet[1]) > 1:
return ((packet[1])[1] == self.SERIAL_PROTO_ACK)
return False
def set_debug(self, debug):
self.__debug = debug
class GenericPacket:
""" GenericPacket """
def __decode(self, v):
r = long(0)
for i in v:
r = (r << 8) + i
return r
def __encode(self, val, dim):
output = []
for i in range(dim):
output.append(int(val & 0xFF))
val = val >> 8
output.reverse()
return output
def __init__(self, desc, packet = None):
self.__dict__['_schema'] = [(t, s) for (n, t, s) in desc]
self.__dict__['_names'] = [n for (n, t, s) in desc]
self.__dict__['_values'] = []
offset = 10
if type(packet) == type([]):
for (t, s) in self._schema:
if t == 'int':
self._values.append(self.__decode(packet[offset:offset + s]))
offset += s
elif t == 'blob':
if s:
self._values.append(packet[offset:offset + s])
offset += s
else:
self._values.append(packet[offset:-3])
elif type(packet) == type(()):
for i in packet:
self._values.append(i)
else:
for v in self._schema:
self._values.append(None)
def __repr__(self):
return self._values.__repr__()
def __str__(self):
return self._values.__str__()
# Implement the map behavior
def __getitem__(self, key):
return self.__getattr__(key)
def __setitem__(self, key, value):
self.__setattr__(key, value)
def __len__(self):
return len(self._values)
def keys(self):
return self._names
def values(self):
return self._names
# Implement the struct behavior
def __getattr__(self, name):
if type(name) == type(0):
return self._names[name]
else:
return self._values[self._names.index(name)]
def __setattr__(self, name, value):
if type(name) == type(0):
self._values[name] = value
else:
self._values[self._names.index(name)] = value
# Custom
def names(self):
return self._names
def sizes(self):
return self._schema
def payload(self):
r = []
for i in range(len(self._schema)):
(t, s) = self._schema[i]
if t == 'int':
r += self.__encode(self._values[i], s)
else:
r += self._values[i]
return r
--- NEW FILE: volumes-stm25p.xml ---
<volume_table>
<volume name="MICROEXEIMAGE" size="262144" type="block"/>
</volume_table>
More information about the Tinyos-2-commits
mailing list