[Tinyos-2-commits] CVS: tinyos-2.x/apps/tosthreads/tinyld/SerialLoader Blink.tos, NONE, 1.1 Makefile, NONE, 1.1 README, NONE, 1.1 SerialLoader.h, NONE, 1.1 SerialLoaderAppC.nc, NONE, 1.1 SerialLoaderP.nc, NONE, 1.1 serialloader.py, NONE, 1.1 tinyos.py, NONE, 1.1
Chieh-Jan Mike Liang
liang_mike at users.sourceforge.net
Tue Feb 3 23:41:37 PST 2009
- Previous message: [Tinyos-2-commits] CVS: tinyos-2.x/apps/tosthreads/tinyld/LoadFromRAM LoadFromRAMAppC.nc, NONE, 1.1 LoadFromRAMP.nc, NONE, 1.1 Makefile, NONE, 1.1 README, NONE, 1.1 volumes-stm25p.xml, NONE, 1.1
- Next message: [Tinyos-2-commits] CVS: tinyos-2.x/tools/tinyos/tosthreads tosthreads-gen-dynamic-app, NONE, 1.1 tosthreads-gen-dynamic-app.1, NONE, 1.1 Makefile.am, 1.1, 1.2
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /cvsroot/tinyos/tinyos-2.x/apps/tosthreads/tinyld/SerialLoader
In directory ddv4jf1.ch3.sourceforge.com:/tmp/cvs-serv8269/apps/tosthreads/tinyld/SerialLoader
Added Files:
Blink.tos Makefile README SerialLoader.h SerialLoaderAppC.nc
SerialLoaderP.nc serialloader.py tinyos.py
Log Message:
Initial commit of TinyLD (TOSThreads' dynamic loader)
--- NEW FILE: Blink.tos ---
--- NEW FILE: Makefile ---
COMPONENT=SerialLoaderAppC
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
ifdef TENET
CFLAGS += -DTOSTHREAD_TENET=1
endif
CFLAGS += -DDISABLE_LOADER_FLASH=1
CFLAGS += -DDISABLE_LOADER_USERBUTTON=1
CLEAN_EXTRA += *.pyc
include $(MAKERULES)
--- NEW FILE: README ---
README for SerialLoader
Author/Contact: Chieh-Jan Mike Liang <cliang4 at cs.jhu.edu>
Description:
SerialLoader receives loadable programs from the serial port and stores
it in a byte array. 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:
tosthread-gen-dynamic-app ../../capps/Blink/Blink.c
3.) Clear the byte array in the mote RAM buffer:
./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: SerialLoader.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 SERIALLOADER_H
#define SERIALLOADER_H
#define MAX_BIN_SIZE 2000
#define SERIALMSG_ERASE 0
#define SERIALMSG_WRITE 1
#define SERIALMSG_READ 2
#define SERIALMSG_CRC 3
#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: SerialLoaderAppC.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>
* @author Jeongyeup Paek <jpaek at enl.usc.edu>
*/
#include "AM.h"
#include "SerialLoader.h"
configuration SerialLoaderAppC {}
implementation
{
components MainC,
SerialActiveMessageC,
new SerialAMSenderC(0xAB),
new SerialAMReceiverC(0xAB),
SerialLoaderP,
BigCrcC,
LedsC;
SerialLoaderP.Boot -> MainC;
SerialLoaderP.SerialSplitControl -> SerialActiveMessageC;
SerialLoaderP.SerialAMSender -> SerialAMSenderC;
SerialLoaderP.SerialAMReceiver -> SerialAMReceiverC;
SerialLoaderP.Leds -> LedsC;
SerialLoaderP.BigCrc -> BigCrcC;
components DynamicLoaderC;
SerialLoaderP.DynamicLoader -> DynamicLoaderC;
}
--- NEW FILE: SerialLoaderP.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>
* @author Jeongyeup Paek <jpaek at enl.usc.edu>
**/
#include "SerialLoader.h"
module SerialLoaderP
{
uses {
interface Boot;
interface SplitControl as SerialSplitControl;
interface AMSend as SerialAMSender;
interface Receive as SerialAMReceiver;
interface Leds;
interface DynamicLoader;
interface BigCrc;
}
}
implementation
{
message_t serialMsg;
uint32_t dumpAddr = 0;
uint8_t image[MAX_BIN_SIZE];
event void Boot.booted()
{
call SerialSplitControl.start();
}
event void SerialSplitControl.startDone(error_t error)
{
if (error != SUCCESS) {
call SerialSplitControl.start();
}
}
event void SerialSplitControl.stopDone(error_t error) {}
void sendReply(error_t error, uint8_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 SerialAMSender.sendDone(message_t* msg, error_t error) {}
error_t write_image(uint16_t offset, void *data, uint16_t len) {
if ((offset + len > MAX_BIN_SIZE) || (data == NULL))
return FAIL;
memcpy(&image[offset], data, len);
return SUCCESS;
}
error_t read_image(uint16_t offset, void *readbuf, uint16_t len) {
if ((offset + len > MAX_BIN_SIZE) || (readbuf == NULL))
return FAIL;
memcpy(readbuf, &image[offset], len);
return SUCCESS;
}
event void DynamicLoader.loadFromFlashDone(uint8_t volumeId, tosthread_t id, error_t error) {}
event void DynamicLoader.loadFromMemoryDone(void *addr, tosthread_t id, error_t error) {
sendReply(error, sizeof(SerialReplyPacket));
}
event void BigCrc.computeCrcDone(void* buf, uint16_t len, uint16_t crc, error_t error)
{
SerialReplyPacket *srpkt = (SerialReplyPacket *)call SerialAMSender.getPayload(&serialMsg, sizeof(SerialReplyPacket));
srpkt->data[1] = crc & 0xFF;
srpkt->data[0] = (crc >> 8) & 0xFF;
sendReply(SUCCESS, 2 + sizeof(SerialReplyPacket));
}
void sendCrcReply(uint16_t offset, uint16_t len)
{
call BigCrc.computeCrc(&(image[offset]), len);
}
event message_t* SerialAMReceiver.receive(message_t* msg, void* payload, uint8_t len)
{
uint16_t i;
error_t error = FAIL;
SerialReqPacket *srpkt = (SerialReqPacket *)payload;
SerialReplyPacket *serialMsg_payload = (SerialReplyPacket *)call SerialAMSender.getPayload(&serialMsg, sizeof(SerialReplyPacket));
switch (srpkt->msg_type) {
case SERIALMSG_ERASE :
for (i = 0; i < MAX_BIN_SIZE; i++) { image[i] = 0; }
call Leds.set(7);
for (i = 0; i < 2000; i++) {}
call Leds.set(0);
sendReply(SUCCESS, sizeof(SerialReplyPacket));
break;
case SERIALMSG_RUN :
error = call DynamicLoader.loadFromMemory(image);
if (error != SUCCESS)
sendReply(error, sizeof(SerialReplyPacket));
break;
case SERIALMSG_WRITE :
error = write_image(srpkt->offset, srpkt->data, srpkt->len);
if (error != SUCCESS)
call Leds.led0On();
sendReply(error, sizeof(SerialReplyPacket));
break;
case SERIALMSG_READ :
error = read_image(srpkt->offset, serialMsg_payload->data, srpkt->len);
if (error != SUCCESS)
sendReply(error, sizeof(SerialReplyPacket));
else
sendReply(error, len + sizeof(SerialReplyPacket));
break;
case SERIALMSG_LEDS:
call Leds.set(7);
for (i = 0; i < 2000; i++) {}
call Leds.set(0);
break;
case SERIALMSG_CRC :
sendCrcReply(srpkt->offset, srpkt->len);
break;
}
return msg;
}
}
--- 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
SERIAL_BAUDRATE = 57600
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
MAX_BIN_SIZE = 2000
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:
print "ERROR: !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], SERIAL_BAUDRATE)
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] <= MAX_BIN_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 max buffer size (" + str(MAX_BIN_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
- Previous message: [Tinyos-2-commits] CVS: tinyos-2.x/apps/tosthreads/tinyld/LoadFromRAM LoadFromRAMAppC.nc, NONE, 1.1 LoadFromRAMP.nc, NONE, 1.1 Makefile, NONE, 1.1 README, NONE, 1.1 volumes-stm25p.xml, NONE, 1.1
- Next message: [Tinyos-2-commits] CVS: tinyos-2.x/tools/tinyos/tosthreads tosthreads-gen-dynamic-app, NONE, 1.1 tosthreads-gen-dynamic-app.1, NONE, 1.1 Makefile.am, 1.1, 1.2
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the Tinyos-2-commits
mailing list