def main(): dict_filename, data_filename = sys.argv[1:] dictionary = read_dictionary(dict_filename) mp = msgproto.MessageParser() mp.process_identify(dictionary, decompress=False) f = open(data_filename, 'rb') fd = f.fileno() data = "" while 1: newdata = os.read(fd, 4096) if not newdata: break data += newdata while 1: l = mp.check_packet(data) if l == 0: break if l < 0: logging.error("Invalid data") data = data[-l:] continue msgs = mp.dump(bytearray(data[:l])) sys.stdout.write('\n'.join(msgs[1:]) + '\n') data = data[l:]
def __init__(self, reactor, serialport, baud): self.reactor = reactor self.serialport = serialport self.baud = baud # Serial port self.ser = None self.msgparser = msgproto.MessageParser() # C interface self.ffi_main, self.ffi_lib = chelper.get_ffi() self.serialqueue = None self.default_cmd_queue = self.alloc_command_queue() self.stats_buf = self.ffi_main.new('char[4096]') # MCU time/clock tracking self.last_ack_time = self.last_ack_rtt_time = 0. self.last_ack_clock = self.last_ack_rtt_clock = 0 self.est_clock = 0. # Threading self.lock = threading.Lock() self.background_thread = None # Message handlers self.status_timer = self.reactor.register_timer(self._status_event) self.status_cmd = None handlers = { '#unknown': self.handle_unknown, '#output': self.handle_output, 'status': self.handle_status, 'shutdown': self.handle_output, 'is_shutdown': self.handle_output } self.handlers = dict(((k, None), v) for k, v in handlers.items())
def _start_session(self, serial_dev, serial_fd_type='u', client_id=0): self.serial_dev = serial_dev if sys.version_info.major > 2: if isinstance(serial_fd_type, str): serial_fd_type = serial_fd_type.encode() self.serialqueue = self.ffi_main.gc( self.ffi_lib.serialqueue_alloc(serial_dev.fileno(), serial_fd_type, client_id), self.ffi_lib.serialqueue_free) self.background_thread = threading.Thread(target=self._bg_thread) self.background_thread.start() # Obtain and load the data dictionary from the firmware completion = self.reactor.register_callback(self._get_identify_data) identify_data = completion.wait(self.reactor.monotonic() + 5.) if identify_data is None: logging.info("Timeout on connect") self.disconnect() return False msgparser = msgproto.MessageParser() msgparser.process_identify(identify_data) self.msgparser = msgparser self.register_response(self.handle_unknown, '#unknown') # Setup baud adjust mcu_baud = msgparser.get_constant_float('SERIAL_BAUD', None) if mcu_baud is not None: baud_adjust = self.BITS_PER_BYTE / mcu_baud self.ffi_lib.serialqueue_set_baud_adjust(self.serialqueue, baud_adjust) receive_window = msgparser.get_constant_int('RECEIVE_WINDOW', None) if receive_window is not None: self.ffi_lib.serialqueue_set_receive_window( self.serialqueue, receive_window) return True
def __init__(self, reactor, serialport, baud, logger=None): if logger is not None: self.logger = logger else: self.logger = logging.getLogger('serial') self.reactor = reactor self.serialport = serialport self.baud = baud # Serial port self.ser = None self.msgparser = msgproto.MessageParser() # C interface self.ffi_main, self.ffi_lib = chelper.get_ffi() self.serialqueue = None self.default_cmd_queue = self.alloc_command_queue() self.stats_buf = self.ffi_main.new('char[4096]') # Threading self.lock = threading.Lock() self.background_thread = None # Message handlers handlers = { '#unknown': self.handle_unknown, '#output': self.handle_output, 'shutdown': self.handle_output, 'is_shutdown': self.handle_output } self.handlers = {(k, None): v for k, v in handlers.items()}
def connect(self): # Initial connection logging.info("Starting serial connect") while 1: starttime = self.reactor.monotonic() try: if self.baud: self.ser = serial.Serial(self.serialport, self.baud, timeout=0) else: self.ser = open(self.serialport, 'rb+') except (OSError, IOError, serial.SerialException) as e: logging.warn("Unable to open port: %s" % (e, )) self.reactor.pause(starttime + 5.) continue if self.baud: stk500v2_leave(self.ser, self.reactor) self.serialqueue = self.ffi_lib.serialqueue_alloc( self.ser.fileno(), 0) self.background_thread = threading.Thread(target=self._bg_thread) self.background_thread.start() # Obtain and load the data dictionary from the firmware sbs = SerialBootStrap(self) identify_data = sbs.get_identify_data(starttime + 5.) if identify_data is None: logging.warn("Timeout on serial connect") self.disconnect() continue break msgparser = msgproto.MessageParser() msgparser.process_identify(identify_data) self.msgparser = msgparser self.register_callback(self.handle_unknown, '#unknown') logging.info("Loaded %d commands (%s)" % (len(msgparser.messages_by_id), msgparser.version)) logging.info( "MCU config: %s" % (" ".join(["%s=%s" % (k, v) for k, v in msgparser.config.items()]))) # Setup baud adjust mcu_baud = float(msgparser.config.get('SERIAL_BAUD', 0.)) if mcu_baud: baud_adjust = self.BITS_PER_BYTE / mcu_baud self.ffi_lib.serialqueue_set_baud_adjust(self.serialqueue, baud_adjust) # Load initial last_clock/last_clock_time uptime_msg = msgparser.create_command('get_uptime') params = self.send_with_response(uptime_msg, 'uptime') self.last_clock = (params['high'] << 32) | params['clock'] self.last_clock_time = params['#receive_time'] self.last_clock_time_min = params['#sent_time'] clock_freq = msgparser.get_constant_float('CLOCK_FREQ') self.min_freq = clock_freq * (1. - MAX_CLOCK_DRIFT) self.max_freq = clock_freq * (1. + MAX_CLOCK_DRIFT) # Enable periodic get_status timer self.status_cmd = msgparser.create_command('get_status') self.reactor.update_timer(self.status_timer, self.reactor.NOW)
def connect(self): # Initial connection logger.debug("- Starting serial connect to '%s' at '%s' baud.", self.serialport, self.baud) start_time = self.hal.get_reactor().monotonic() while 1: connect_time = self.hal.get_reactor().monotonic() if connect_time > start_time + 150.: raise error("Unable to connect") try: if self.baud: self.ser = serial.Serial(self.serialport, self.baud, timeout=0, exclusive=True) #self.ser.port = self.serialport #self.ser.rts = self.rts #self.ser.open() else: self.ser = open(self.serialport, 'rb+') except (OSError, IOError, serial.SerialException) as e: logger.warn("Unable to open port: %s", e) self.hal.get_reactor().pause(connect_time + 5.) continue if self.baud: stk500v2_leave(self.ser, self.hal.get_reactor()) self.serialqueue = self.ffi_lib.serialqueue_alloc( self.ser.fileno(), 0) print(self.serialqueue) self.background_thread = threading.Thread(name='polling:mcu at ' + self.serialport, target=self._bg_thread) self.background_thread.start() # Obtain and load the data dictionary from the firmware completion = self.hal.get_reactor().callback_async( self._get_identify_data) print("BEFORE %s" % multiprocessing.current_process()) identify_data = completion.wait(connect_time + 5.) print("AFTER") if identify_data is not None: break logger.info("Timeout on serial connect") self.disconnect() msgparser = msgproto.MessageParser() msgparser.process_identify(identify_data) self.msgparser = msgparser self.register_response(self._serial_handle_unknown, '#unknown') # Setup baud adjust mcu_baud = msgparser.get_constant_float('SERIAL_BAUD', None) if mcu_baud is not None: baud_adjust = self.BITS_PER_BYTE / mcu_baud self.ffi_lib.serialqueue_set_baud_adjust(self.serialqueue, baud_adjust) receive_window = msgparser.get_constant_int('RECEIVE_WINDOW', None) if receive_window is not None: self.ffi_lib.serialqueue_set_receive_window( self.serialqueue, receive_window)
def connect(self): # Initial connection logging.info("Starting serial connect") start_time = self.reactor.monotonic() while 1: connect_time = self.reactor.monotonic() if connect_time > start_time + 90.: raise error("Unable to connect") try: if self.baud: self.ser = serial.Serial(baudrate=self.baud, timeout=0, exclusive=True) self.ser.port = self.serialport self.ser.rts = self.rts self.ser.open() else: self.ser = open(self.serialport, 'rb+') except (OSError, IOError, serial.SerialException) as e: logging.warn("Unable to open port: %s", e) self.reactor.pause(connect_time + 5.) continue if self.baud: stk500v2_leave(self.ser, self.reactor) self.serialqueue = self.ffi_main.gc( self.ffi_lib.serialqueue_alloc(self.ser.fileno(), 0), self.ffi_lib.serialqueue_free) if self._debug_fd: self.ffi_lib.serialqueue_set_debug_fd(self.serialqueue, self._debug_fd) self.background_thread = threading.Thread(target=self._bg_thread) self.background_thread.start() # Obtain and load the data dictionary from the firmware completion = self.reactor.register_callback( self._get_identify_data) identify_data = completion.wait(connect_time + 5.) if identify_data is not None: break logging.info("Timeout on serial connect") self.disconnect() msgparser = msgproto.MessageParser() msgparser.process_identify(identify_data) self.msgparser = msgparser self.register_response(self.handle_unknown, '#unknown') # Setup baud adjust mcu_baud = msgparser.get_constant_float('SERIAL_BAUD', None) if mcu_baud is not None: baud_adjust = self.BITS_PER_BYTE / mcu_baud self.ffi_lib.serialqueue_set_baud_adjust(self.serialqueue, baud_adjust) receive_window = msgparser.get_constant_int('RECEIVE_WINDOW', None) if receive_window is not None: self.ffi_lib.serialqueue_set_receive_window( self.serialqueue, receive_window)
def map_pins(self): if not self.initial_pins: return [] mp = msgproto.MessageParser() mp._fill_enumerations(HandlerEnumerations.enumerations) pinmap = mp.enumerations.get('pin', {}) out = [] for p in self.initial_pins: flag = "IP_OUT_HIGH" if p.startswith('!'): flag = "0" p = p[1:].strip() if p not in pinmap: error("Unknown initial pin '%s'" % (p, )) out.append("\n {%d, %s}, // %s" % (pinmap[p], flag, p)) return out
def connect(self): # Initial connection logging.info("Starting serial connect") while 1: starttime = self.reactor.monotonic() try: if self.baud: self.ser = serial.Serial(self.serialport, self.baud, timeout=0) else: self.ser = open(self.serialport, 'rb+') except (OSError, IOError, serial.SerialException) as e: logging.warn("Unable to open port: %s", e) self.reactor.pause(starttime + 5.) continue if self.baud: stk500v2_leave(self.ser, self.reactor) self.serialqueue = self.ffi_lib.serialqueue_alloc( self.ser.fileno(), 0) self.background_thread = threading.Thread(target=self._bg_thread) self.background_thread.start() # Obtain and load the data dictionary from the firmware sbs = SerialBootStrap(self) identify_data = sbs.get_identify_data(starttime + 5.) if identify_data is None: logging.warn("Timeout on serial connect") self.disconnect() continue break msgparser = msgproto.MessageParser() msgparser.process_identify(identify_data) self.msgparser = msgparser self.register_callback(self.handle_unknown, '#unknown') logging.info("Loaded %d commands (%s / %s)", len(msgparser.messages_by_id), msgparser.version, msgparser.build_versions) logging.info( "MCU config: %s", " ".join(["%s=%s" % (k, v) for k, v in msgparser.config.items()])) # Setup baud adjust mcu_baud = float(msgparser.config.get('SERIAL_BAUD', 0.)) if mcu_baud: baud_adjust = self.BITS_PER_BYTE / mcu_baud self.ffi_lib.serialqueue_set_baud_adjust(self.serialqueue, baud_adjust)
def connect(self): # Initial connection self.logger.info("Connecting to %s @ %s" % (self.serialport, self.baud)) while 1: starttime = self.reactor.monotonic() try: if self.baud: self.ser = serial.Serial(self.serialport, self.baud, timeout=0) else: self.ser = open(self.serialport, 'rb+') except (OSError, IOError, serial.SerialException) as e: self.logger.warn("Unable to open port: %s", e) self.reactor.pause(starttime + 5.) continue if self.baud: stk500v2_leave(self.ser, self.reactor) self.serialqueue = self.ffi_lib.serialqueue_alloc( self.ser.fileno(), 0) self.background_thread = threading.Thread(target=self._bg_thread) self.background_thread.start() # Obtain and load the data dictionary from the firmware sbs = SerialBootStrap(self, self.logger) identify_data = sbs.get_identify_data(starttime + 5.) if identify_data is None: self.logger.warn("Timeout on serial connect [{}]".format( self.serialport, )) self.disconnect() continue break msgparser = msgproto.MessageParser() msgparser.process_identify(identify_data) self.msgparser = msgparser self.register_callback(self.handle_unknown, '#unknown') # Setup baud adjust mcu_baud = msgparser.get_constant_float('SERIAL_BAUD', None) if mcu_baud is not None: baud_adjust = self.BITS_PER_BYTE / mcu_baud self.ffi_lib.serialqueue_set_baud_adjust(self.serialqueue, baud_adjust) receive_window = msgparser.get_constant_int('RECEIVE_WINDOW', None) if receive_window is not None: self.ffi_lib.serialqueue_set_receive_window( self.serialqueue, receive_window)
def __init__(self, reactor, serialport, baud): self.reactor = reactor self.serialport = serialport self.baud = baud # Serial port self.ser = None self.msgparser = msgproto.MessageParser() # C interface self.ffi_main, self.ffi_lib = chelper.get_ffi() self.serialqueue = None self.default_cmd_queue = self.alloc_command_queue() self.stats_buf = self.ffi_main.new('char[4096]') # Threading self.lock = threading.Lock() self.background_thread = None # Message handlers self.handlers = {} self.register_response(self._handle_unknown_init, '#unknown') self.register_response(self.handle_output, '#output')
def __init__(self, reactor): self.reactor = reactor # Serial port self.serial_dev = None self.msgparser = msgproto.MessageParser() # C interface self.ffi_main, self.ffi_lib = chelper.get_ffi() self.serialqueue = None self.default_cmd_queue = self.alloc_command_queue() self.stats_buf = self.ffi_main.new('char[4096]') # Threading self.lock = threading.Lock() self.background_thread = None # Message handlers self.handlers = {} self.register_response(self._handle_unknown_init, '#unknown') self.register_response(self.handle_output, '#output') # Sent message notification tracking self.last_notify_id = 0 self.pending_notifications = {}
def main(): dict_filename, data_filename = sys.argv[1:] dictionary = read_dictionary(dict_filename) mp = msgproto.MessageParser() mp.process_identify(dictionary, decompress=False) f = open(data_filename, 'rb') fd = f.fileno() data = "" while 1: newdata = os.read(fd, 4096) if not newdata: break data += newdata while 1: l, msg, header = check_packet(data) if l == 0: break if l < 0: print("Invalid data (framing)") exit() data = data[l:] while 1: ml = mp.check_packet(msg) if ml == 0: break if ml < 0: print("Invalid data (msg)") exit() msgs = mp.dump(bytearray(msg[:ml])) phead = format_header(header) for m in msgs[1:]: a = "" #a = process(header, m) #if a is None: # continue sys.stdout.write(phead + m + ' ' + a + '\n') msg = msg[ml:]
class SerialReader: BITS_PER_BYTE = 10. def __init__(self, reactor, serialport, baud): self.reactor = reactor self.serialport = serialport self.baud = baud # Serial port self.ser = None self.msgparser = msgproto.MessageParser() # C interface self.ffi_main, self.ffi_lib = chelper.get_ffi() self.serialqueue = None self.default_cmd_queue = self.alloc_command_queue() self.stats_buf = self.ffi_main.new('char[4096]') # MCU time/clock tracking self.last_ack_time = self.last_ack_rtt_time = 0. self.last_ack_clock = self.last_ack_rtt_clock = 0 self.est_clock = 0. # Threading self.lock = threading.Lock() self.background_thread = None # Message handlers self.status_timer = self.reactor.register_timer(self._status_event) self.status_cmd = None handlers = { '#unknown': self.handle_unknown, '#output': self.handle_output, 'status': self.handle_status, 'shutdown': self.handle_output, 'is_shutdown': self.handle_output } self.handlers = dict(((k, None), v) for k, v in handlers.items()) def _bg_thread(self): response = self.ffi_main.new('struct pull_queue_message *') while 1: self.ffi_lib.serialqueue_pull(self.serialqueue, response) count = response.len if count <= 0: break params = self.msgparser.parse(response.msg[0:count]) params['#sent_time'] = response.sent_time params['#receive_time'] = response.receive_time with self.lock: hdl = (params['#name'], params.get('oid')) hdl = self.handlers.get(hdl, self.handle_default) try: hdl(params) except: logging.exception("Exception in serial callback") def connect(self): # Initial connection logging.info("Starting serial connect") while 1: starttime = self.reactor.monotonic() try: if self.baud: self.ser = serial.Serial( self.serialport, self.baud, timeout=0) else: self.ser = open(self.serialport, 'rb+') except (OSError, serial.SerialException), e: logging.warn("Unable to open port: %s" % (e,)) self.reactor.pause(starttime + 5.) continue if self.baud: stk500v2_leave(self.ser, self.reactor) self.serialqueue = self.ffi_lib.serialqueue_alloc( self.ser.fileno(), 0) self.background_thread = threading.Thread(target=self._bg_thread) self.background_thread.start() # Obtain and load the data dictionary from the firmware sbs = SerialBootStrap(self) identify_data = sbs.get_identify_data(starttime + 5.) if identify_data is None: logging.warn("Timeout on serial connect") self.disconnect() continue break msgparser = msgproto.MessageParser() msgparser.process_identify(identify_data) self.msgparser = msgparser self.register_callback(self.handle_unknown, '#unknown') logging.info("Loaded %d commands (%s)" % ( len(msgparser.messages_by_id), msgparser.version)) logging.info("MCU config: %s" % (" ".join( ["%s=%s" % (k, v) for k, v in msgparser.config.items()]))) # Setup baud adjust mcu_baud = float(msgparser.config.get('SERIAL_BAUD', 0.)) if mcu_baud: baud_adjust = self.BITS_PER_BYTE / mcu_baud self.ffi_lib.serialqueue_set_baud_adjust( self.serialqueue, baud_adjust) # Enable periodic get_status timer get_status = msgparser.lookup_command('get_status') self.status_cmd = get_status.encode() self.reactor.update_timer(self.status_timer, self.reactor.NOW) # Load initial last_ack_clock/last_ack_time uptime_msg = msgparser.create_command('get_uptime') params = self.send_with_response(uptime_msg, 'uptime') self.last_ack_clock = (params['high'] << 32) | params['clock'] self.last_ack_time = params['#receive_time'] # Make sure est_clock is calculated starttime = eventtime = self.reactor.monotonic() while not self.est_clock: if eventtime > starttime + 5.: raise error("timeout on est_clock calculation") eventtime = self.reactor.pause(eventtime + 0.010)