⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tos.py

📁 tinyos2.0版本驱动
💻 PY
📖 第 1 页 / 共 2 页
字号:
# 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 Razvan Musaloiu-E. <razvanm@cs.jhu.edu>"""A library that implements the T2 serial communication.This library has two parts: one that deals with sending and receivingpackets using the serial format from T2 (TEP113) and a second one thattries to simplifies the work with arbitrary packets."""import sys, struct, time, serial, socket, operator, threadfrom Queue import Queuefrom threading import Lock, Condition__version__ = "$Id: tos.py,v 1.1 2008/05/19 21:25:08 razvanm Exp $"__all__ = ['Serial', 'AM',           'Packet', 'RawPacket',           'AckFrame', 'DataFrame', 'NoAckDataFrame',           'ActiveMessage']def list2hex(v):    return " ".join(["%02x" % p for p in v])class Serial:    """    A Serial object offers a way to send and data using a HDLC-like    formating.    """        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      def __init__(self, port, baudrate, flush=False, debug=False, qsize=10):        self._debug = debug        self._in_queue = Queue(qsize)        self._out_lock = Lock()        self._out_ack = Condition()        self._seqno = 0        self._ack = None        self._write_counter = 0        self._write_counter_failures = 0        self._read_counter = 0        self._ts = None        self._s = serial.Serial(port, baudrate, rtscts=0, timeout=0.5)        self._s.flushInput()        start = time.time();        if flush:            print >>sys.stdout, "Flushing the serial port",            while time.time() - start < 1:                p = self._read()                sys.stdout.write(".")            if not self._debug:                sys.stdout.write("\n")        self._s.close()        self._s = serial.Serial(port, baudrate, rtscts=0, timeout=None)        thread.start_new_thread(self.run, ())    def run(self):                while True:            p = self._read()            self._read_counter += 1            if self._debug:                print "Serial:run: got a packet(%d): %s" % (self._read_counter, p)            ack = AckFrame(p.data)            if ack.protocol == self.SERIAL_PROTO_ACK:                if not self._ack:                    self._ack = ack                if self._debug:                    print "Serial:run: got an ack:", ack                self._ack = ack                # Wake up the writer                self._out_ack.acquire()                self._out_ack.notify()                self._out_ack.release()            else:                ampkt = ActiveMessage(NoAckDataFrame(p.data).data)                if ampkt.type == 100:                    for t in "".join([chr(i) for i in ampkt.data]).strip('\n\0').split('\n'):                        print "PRINTF:", t.strip('\n')                else:                    if self._in_queue.full():                        print "Warning: Buffer overflow"                        self._in_queue.get()                    self._in_queue.put(p, block=False)    # Returns the next incoming serial packet    def _read(self):        """Wait for a packet and return it as a RawPacket."""                try:            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)            if self._debug == True:                print "Serial:_read: unescaped", packet            packet = self._unescape(packet)                        crc = self._crc16(0, packet[1:-3])            packet_crc = self._decode(packet[-3:-1])                        if crc != packet_crc:                print "Warning: wrong CRC! %x != %x %s" % (crc, packet_crc, ["%2x" % i for i in packet])            if self._debug:                if self._ts == None:                    self._ts = ts                else:                    print "Serial:_read: %.4f (%.4f) Recv:" % (ts, ts - self._ts), self._format_packet(packet[1:-3])                self._ts = ts            return RawPacket(ts, packet[1:-3], crc == packet_crc)        except socket.timeout:            return None    def read(self, timeout=0):        start = time.time();        done = False        while not done:            p = None            while p == None:                if timeout == 0 or time.time() - start < timeout:                    p = self._in_queue.get()                else:                    return None            if p.crc:                done = True            else:                p = None        # In the current TinyOS the packets from the mote are always NoAckDataFrame        return NoAckDataFrame(p.data)    def write(self, payload):        """        Write a packet. If the payload argument is a list, it is        assumed to be exactly the payload. Otherwise the payload is        assume to be a Packet and the real payload is obtain by        calling the .payload().        """                if type(payload) != type([]):            # Assume this will be derived from Packet            payload = payload.payload()        self._out_lock.acquire()        self._seqno = (self._seqno + 1) % 100        packet = DataFrame();        packet.protocol = self.SERIAL_PROTO_PACKET_ACK        packet.seqno = self._seqno        packet.dispatch = 0        packet.data = payload        packet = packet.payload()        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]        while True:            self._put_bytes(packet)            self._write_counter += 1            if self._debug == True:                print "Send(%d/%d): %s" % (self._write_counter, self._write_counter_failures, packet)                print "Wait for ack %d ..." % (self._seqno)            self._out_ack.acquire()            self._out_ack.wait(0.2)            if self._debug:                print "Wait for ack %d done. Latest ack:" % (self._seqno), self._ack            self._out_ack.release()            if self._ack and self._ack.seqno == self._seqno:                if self._debug:                    print "The packet was acked."                self._out_lock.release()                if self._debug:                    print "Returning from Serial.write..."                return True            else:                self._write_counter_failures += 1                if self._debug:                    print "The packet was not acked. Try again."            # break # make only one sending attempt        self._out_lock.release()        return False    def _format_packet(self, payload):        f = NoAckDataFrame(payload)        if f.protocol == self.SERIAL_PROTO_ACK:            rpacket = AckFrame(payload)            return "Ack seqno: %d" % (rpacket.seqno)        else:            rpacket = ActiveMessage(f.data)            return "D: %04x S: %04x L: %02x G: %02x T: %02x | %s" % \                   (rpacket.destination, rpacket.source,                    rpacket.length, rpacket.group, rpacket.type,                    list2hex(rpacket.data))    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):        try:            r = struct.unpack("B", self._s.read())[0]            return r        except struct.error:            # Serial port read timeout            raise socket.timeout        def _put_bytes(self, data):        #print "DEBUG: _put_bytes:", 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:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -