def __init__(self, link, timeout=None): self.diagnostics = {} self.diagnostics['versions'] = {} self.diagnostics['settings'] = {} self.settings_received = False self.heartbeat_received = False self.handshake_received = False self.sbp_version = (0, 0) self.link = link self.link.add_callback(self._settings_callback, SBP_MSG_SETTINGS_READ_BY_INDEX_REQ) self.link.add_callback(self._settings_callback, SBP_MSG_SETTINGS_READ_BY_INDEX_RESP) self.link.add_callback(self._settings_done_callback, SBP_MSG_SETTINGS_READ_BY_INDEX_DONE) self.link.add_callback(self._heartbeat_callback, SBP_MSG_HEARTBEAT) self.link.add_callback(self._deprecated_handshake_callback, SBP_MSG_BOOTLOADER_HANDSHAKE_DEP_A) self.link.add_callback(self._handshake_callback, SBP_MSG_BOOTLOADER_HANDSHAKE_RESP) self.link.add_callback(self._print_callback, [SBP_MSG_LOG, SBP_MSG_PRINT_DEP]) timeout = time.time() + timeout if timeout is not None else None # Wait for the heartbeat while not self.heartbeat_received: time.sleep(0.1) if timeout is not None and time.time() > timeout: print("timeout waiting for heartbeat") return # Wait for the settings print("received heartbeat") expire = time.time() + 15.0 self.link(MsgSettingsReadByIndexReq(index=0)) while not self.settings_received: time.sleep(0.1) if time.time() > expire: expire = time.time() + 15.0 self.link(MsgSettingsReadByIndexReq(index=0)) if timeout is not None and time.time() > timeout: print("timeout waiting for settings") return # Wait for the handshake print("received settings") expire = time.time() + 10.0 self.link(MsgReset(flags=0)) while not self.handshake_received: time.sleep(0.1) if time.time() > expire: expire = time.time() + 10.0 self.link(MsgReset(flags=0)) if timeout is not None and time.time() > timeout: print("timeout waiting for handshake") return print("received bootloader handshake")
def run(args, link): """Spin loop for reading from the serial link. Parameters ---------- args : object Argparse result. link : Handler Piksi serial handle """ timeout = args.timeout if args.reset: link(MsgReset(flags=0)) try: if args.timeout is not None: expire = time.time() + float(args.timeout) while True: if timeout is None or time.time() < expire: # Wait forever until the user presses Ctrl-C time.sleep(1) else: print("Timer expired!") break if not link.is_alive(): sys.stderr.write("ERROR: Thread died!") sys.exit(1) except KeyboardInterrupt: # Callbacks call thread.interrupt_main(), which throw a # KeyboardInterrupt exception. To get the proper error # condition, return exit code of 1. Note that the finally # block does get caught since exit itself throws a # SystemExit exception. sys.exit(1)
def main(): """ Get configuration, get driver, and build handler and start it. """ args = get_args() driver = serial_link.get_base_args_driver(args) # Driver with context # Handler with context with Handler(Framer(driver.read, driver.write, verbose=args.verbose)) as link: data = bytearray(open(args.firmware, 'rb').read()) def progress_cb(size, _): sys.stdout.write("\rProgress: %d%% \r" % (100 * size / len(data))) sys.stdout.flush() print('Transferring image file...') FileIO(link).write(b"upgrade.image_set.bin", data, progress_cb=progress_cb) print('Committing file to flash...') link.add_callback(serial_link.log_printer, SBP_MSG_LOG) link.add_callback(serial_link.printer, SBP_MSG_PRINT_DEP) code = shell_command(link, b"upgrade_tool upgrade.image_set.bin", 300) if code != 0: print('Failed to perform upgrade (code = %d)' % code) return print('Resetting Piksi...') link(MsgReset(flags=0))
def main(): """ Get configuration, get driver, and build handler and start it. """ args = get_args() port = args.port[0] baud = args.baud[0] use_ftdi = args.ftdi # Driver with context with serial_link.get_driver(use_ftdi, port, baud) as driver: # Handler with context with Handler(Framer(driver.read, driver.write)) as link: link.add_callback(serial_link.log_printer, SBP_MSG_LOG) link.add_callback(serial_link.printer, SBP_MSG_PRINT_DEP) data = open(args.file, 'rb').read() def progress_cb(size): sys.stdout.write("\rProgress: %d%% \r" % (100 * size / len(data))) sys.stdout.flush() print('Transferring image file...') FileIO(link).write("upgrade.image_set.bin", data, progress_cb=progress_cb) print('Committing file to flash...') code = shell_command(link, "upgrade_tool upgrade.image_set.bin", 300) if code != 0: print('Failed to perform upgrade (code = %d)' % code) return print('Resetting Piksi...') link(MsgReset(flags=0))
def main(): warnings.simplefilter(action="ignore", category=FutureWarning) logging.basicConfig() args = None parser = get_args() try: args = parser.parse_args() show_usage = args.help error_str = "" except (ArgumentParserError, argparse.ArgumentError, argparse.ArgumentTypeError) as e: print(e) show_usage = True error_str = "ERROR: " + str(e) # Make sure that SIGINT (i.e. Ctrl-C from command line) actually stops the # application event loop (otherwise Qt swallows KeyboardInterrupt exceptions) signal.signal(signal.SIGINT, signal.SIG_DFL) if show_usage: usage_str = parser.format_help() print(usage_str) usage = ShowUsage(usage_str, error_str) usage.configure_traits() sys.exit(1) # fail out if connection failed to initialize cnx_data = do_connection(args) if cnx_data is None: print('Unable to Initialize Connection. Exiting...') sys.exit(1) with cnx_data.driver as driver: with sbpc.Handler(sbpc.Framer(driver.read, driver.write, args.verbose)) as link: if args.reset: link(MsgReset(flags=0)) log_filter = DEFAULT_LOG_LEVEL_FILTER if args.initloglevel[0]: log_filter = args.initloglevel[0] with SwiftConsole(link, args.update, log_filter, cnx_desc=cnx_data.description, error=args.error, json_logging=args.log, log_dirname=args.log_dirname, override_filename=args.logfilename, log_console=args.log_console, connection_info=cnx_data.connection_info, expand_json=args.expand_json) as console: console.configure_traits() # TODO: solve this properly # Force exit, even if threads haven't joined try: os._exit(0) except: # noqa pass
def action(self): """ Stub for communicating with device. Should be overloaded in subclass. """ print "Hit interval timer after {0} seconds".format(time.time() - self.reset_time) self.log_state_trans('TIMEOUT') if self.state_dict: self.log_state_dict() self.clear_state() self.reset_time = time.time() self.handler(MsgReset(flags=0)) time.sleep(0.25)
def manage_multi_firmware_update(self): # Set up progress dialog and transfer file to Piksi using SBP FileIO progress_dialog = PulsableProgressDialog(len(self.stm_fw.blob)) progress_dialog.title = "Transferring file - stay on this window to progress" self._write( "Transferring image file - you must keep progress bar window active for the file transfer to progress" ) if not progress_dialog.open_in_gui_thread(): self._write("Failed to open progress dialog.\n") return try: FileIO(self.link).write("upgrade.image_set.bin", self.stm_fw.blob, progress_cb=progress_dialog.progress) except Exception as e: self._write("Failed to transfer image file to Piksi: %s\n" % e) progress_dialog.close() return try: progress_dialog.close() except AttributeError: pass # Setup up pulsed progress dialog and commit to flash progress_dialog = PulsableProgressDialog(100, True) progress_dialog.title = "Committing to flash" if not progress_dialog.open_in_gui_thread(): self._write("Failed to open progress dialog.\n") return def log_cb(msg, **kwargs): self._write(msg.text) self.link.add_callback(log_cb, SBP_MSG_LOG) code = shell_command(self.link, "upgrade_tool upgrade.image_set.bin", 600, progress_cb=progress_dialog.progress) self.link.remove_callback(log_cb, SBP_MSG_LOG) progress_dialog.close() if code != 0: self._write('Failed to perform upgrade (code = %d)' % code) if code == -255: self._write('Shell command timed out. Please try again.') return self._write('Resetting Piksi...') self.link(MsgReset(flags=0))
def run(args, link, stop_function=lambda: None): """Spin loop for reading from the serial link. Parameters ---------- args : object Argparse result. link : Handler Piksi serial handle """ link.start() timeout = args.timeout if args.reset: link(MsgReset(flags=0)) try: if args.timeout is not None: expire = monotonic() + float(args.timeout) while True: if timeout is None or monotonic() < expire: # Wait forever until the user presses Ctrl-C time.sleep(1) else: print("Timer expired!") stop_function() break if link.is_alive(): continue if getattr(args, 'file', None): # If reading from a file it is expected to end at some point stop_function() sys.exit(0) if args.verbose: sys.stderr.write("ERROR: link is gone!\n") stop_function() sys.exit(1) except KeyboardInterrupt: # Callbacks call thread.interrupt_main(), which throw a # KeyboardInterrupt exception. To get the proper error # condition, return exit code of 1. Note that the finally # block does get caught since exit itself throws a # SystemExit exception. stop_function() sys.exit(1)
def create_flash(self, flash_type): """ Create flash.Flash instance and set Piksi into bootloader mode, prompting user to reset if necessary. Parameter --------- flash_type : string Either "STM" or "M25". """ # Reset device if the application is running to put into bootloader mode. self.link(MsgReset()) self.pk_boot = bootload.Bootloader(self.link) self._write("Waiting for bootloader handshake message from Piksi ...") reset_prompt = None handshake_received = self.pk_boot.handshake(1) # Prompt user to reset Piksi if we don't receive the handshake message # within a reasonable amount of tiime (firmware might be corrupted). while not handshake_received: reset_prompt = \ prompt.CallbackPrompt( title="Please Reset Piksi", actions=[prompt.close_button], ) reset_prompt.text = \ "You must press the reset button on your Piksi in order\n" + \ "to update your firmware.\n\n" + \ "Please press it now.\n\n" reset_prompt.run(block=False) while not reset_prompt.closed and not handshake_received: handshake_received = self.pk_boot.handshake(1) reset_prompt.kill() reset_prompt.wait() self._write("received bootloader handshake message.") self._write("Piksi Onboard Bootloader Version: " + self.pk_boot.version) self.pk_flash = flash.Flash(self.link, flash_type, self.pk_boot.sbp_version)
def main(): """ Get configuration, get driver, get logger, and build handler and start it. """ args = get_args() port = args.port[0] baud = args.baud[0] timeout = args.timeout[0] log_filename = args.log_filename[0] append_log_filename = args.append_log_filename[0] tags = args.tags[0] # Driver with context with get_driver(args.ftdi, port, baud) as driver: # Handler with context with Handler(Framer(driver.read, driver.write, args.verbose)) as link: # Logger with context with get_logger(args.log, log_filename) as logger: with get_append_logger(append_log_filename, tags) as append_logger: link.add_callback(printer, SBP_MSG_PRINT_DEP) link.add_callback(log_printer, SBP_MSG_LOG) Forwarder(link, logger).start() Forwarder(link, append_logger).start() # Reset device if args.reset: link(MsgReset()) try: if timeout is not None: expire = time.time() + float(args.timeout[0]) while True: if timeout is None or time.time() < expire: # Wait forever until the user presses Ctrl-C time.sleep(1) else: print "Timer expired!" break if not link.is_alive(): sys.stderr.write("ERROR: Thread died!") sys.exit(1) except KeyboardInterrupt: # Callbacks call thread.interrupt_main(), which throw a KeyboardInterrupt # exception. To get the proper error condition, return exit code # of 1. Note that the finally block does get caught since exit # itself throws a SystemExit exception. sys.exit(1)
def reboot_and_log(self): if self.state_dict: self.log_state_dict() self.num_cycles += 1 if self.commanded_cycles != None and self.num_cycles > self.commanded_cycles: print("Completed {} commanded cycles.".format(self.commanded_cycles)) self.timer.cancel() self.file.close() self.handler.stop() sys.exit(0) else: print("Starting {} cycles of {} cycles".format(self.num_cycles, self.commanded_cycles)) self.clear_state() self.reset_time = time.time() self.timer.reset() self.handler(MsgReset(flags=0)) time.sleep(0.25)
def manage_multi_firmware_update(self): # Set up progress dialog and transfer file to Piksi using SBP FileIO progress_dialog = PulsableProgressDialog(len(self.stm_fw.blob)) progress_dialog.title = "Transferring image file" GUI.invoke_later(progress_dialog.open) self._write("Transferring image file...") try: FileIO(self.link).write("upgrade.image_set.bin", self.stm_fw.blob, progress_cb=progress_dialog.progress) except Exception as e: self._write("Failed to transfer image file to Piksi: %s\n" % e) progress_dialog.close() return try: progress_dialog.close() except AttributeError: pass # Setup up pulsed progress dialog and commit to flash progress_dialog = PulsableProgressDialog(100, True) progress_dialog.title = "Committing to flash" GUI.invoke_later(progress_dialog.open) self._write("Committing file to flash...") def log_cb(msg, **kwargs): self._write(msg.text) self.link.add_callback(log_cb, SBP_MSG_LOG) code = shell_command(self.link, "upgrade_tool upgrade.image_set.bin", 240) self.link.remove_callback(log_cb, SBP_MSG_LOG) progress_dialog.close() if code != 0: self._write('Failed to perform upgrade (code = %d)' % code) return self._write('Resetting Piksi...') self.link(MsgReset(flags=0))
def manage_multi_firmware_update(self): self.blob_size = float(len(self.stm_fw.blob)) self.pcent_complete = 0 # Set up progress dialog and transfer file to Piksi using SBP FileIO self._clear_stream() self._write("Transferring image to device...\n\n00.0 of {:2.1f} MB trasnferred".format( self.blob_size * 1e-6)) try: FileIO(self.link).write( b"upgrade.image_set.bin", self.stm_fw.blob, progress_cb=self.file_transfer_progress_cb) except Exception as e: self._write("Failed to transfer image file to Piksi: %s\n" % e) self._write("Upgrade Aborted.") import traceback print(traceback.format_exc()) return -1 self.stream.scrollback_write( "Image transfer complete: {:2.1f} MB transferred.\n".format(self.blob_size * 1e-6)) # Setup up pulsed progress dialog and commit to flash self._write("Committing file to Flash...\n") self.link.add_callback(self.log_cb, SBP_MSG_LOG) code = shell_command( self.link, b"upgrade_tool upgrade.image_set.bin", 200) self.link.remove_callback(self.log_cb, SBP_MSG_LOG) if code != 0: self._write('Failed to perform upgrade (code = %d)' % code) if code == -255: self._write('Shell command timed out. Please try again.') return self._write("Upgrade Complete.") self._write('Resetting Piksi...') self.link(MsgReset(flags=0))
def reset(self): """ Reset the Piksi via a MSG_RESET. """ self.send_msg(MsgReset())
connection_description = os.path.split(port)[-1] + " @" + str(baud) else: # Use the port passed and assume serial connection print("Using serial device '%s'" % port) selected_driver = s.get_driver(args.ftdi, port, baud, args.file, rtscts=args.rtscts) connection_description = os.path.split(port)[-1] + " @" + str(baud) with selected_driver as driver: with sbpc.Handler(sbpc.Framer(driver.read, driver.write, args.verbose)) as link: if args.reset: link(MsgReset(flags=0)) log_filter = DEFAULT_LOG_LEVEL_FILTER if args.initloglevel[0]: log_filter = args.initloglevel[0] with SwiftConsole(link, args.update, log_filter, cnx_desc=connection_description, error=args.error, json_logging=args.log, log_dirname=args.log_dirname, override_filename=args.logfilename, log_console=args.log_console, networking=args.networking, serial_upgrade=args.serial_upgrade) as console: console.configure_traits()
def _piksi_reset_button_fired(self): self.link(MsgReset(flags=0))
def _save_and_reset(self): self._settings_save_button_fired() self.link(MsgReset(flags=0))
def reset(self): self.link(MsgReset(flags=0))
def reset(self): """Reset to default settings and reset device""" self.link(MsgReset(flags=1))
def reset_piksi(self): print 'RESET PIKSI' msg = MsgReset() self.send_to_piksi(msg.to_binary())
def main(): warnings.simplefilter(action="ignore", category=FutureWarning) logging.basicConfig() args = None parser = get_args() try: args = parser.parse_args() port = args.port baud = args.baud show_usage = args.help error_str = "" except (ArgumentParserError, argparse.ArgumentError, argparse.ArgumentTypeError) as e: print(e) show_usage = True error_str = "ERROR: " + str(e) if args and args.toolkit[0] is not None: ETSConfig.toolkit = args.toolkit[0] else: ETSConfig.toolkit = 'qt4' # Make sure that SIGINT (i.e. Ctrl-C from command line) actually stops the # application event loop (otherwise Qt swallows KeyboardInterrupt exceptions) signal.signal(signal.SIGINT, signal.SIG_DFL) if show_usage: usage_str = parser.format_help() print(usage_str) usage = ShowUsage(usage_str, error_str) usage.configure_traits() sys.exit(1) selected_driver = None connection_description = "" if port and args.tcp: # Use the TPC driver and interpret port arg as host:port try: host, ip_port = port.split(':') selected_driver = TCPDriver(host, int(ip_port)) connection_description = port except: raise Exception('Invalid host and/or port') sys.exit(1) elif port and args.file: # Use file and interpret port arg as the file print("Using file '%s'" % port) selected_driver = s.get_driver(args.ftdi, port, baud, args.file) connection_description = os.path.split(port)[-1] elif not port: # Use the gui to get our driver port_chooser = PortChooser(baudrate=int(args.baud)) is_ok = port_chooser.configure_traits() ip_address = port_chooser.ip_address ip_port = port_chooser.ip_port port = port_chooser.port baud = port_chooser.baudrate mode = port_chooser.mode # todo, update for sfw flow control if ever enabled rtscts = port_chooser.flow_control == flow_control_options_list[1] if rtscts: print("using flow control") # if the user pressed cancel or didn't select anything if not (port or (ip_address and ip_port)) or not is_ok: print("No Interface selected!") sys.exit(1) else: # Use either TCP/IP or serial selected from gui if mode == cnx_type_list[1]: print("Using TCP/IP at address %s and port %d" % (ip_address, ip_port)) selected_driver = TCPDriver(ip_address, int(ip_port)) connection_description = ip_address + ":" + str(ip_port) else: print("Using serial device '%s'" % port) selected_driver = s.get_driver(args.ftdi, port, baud, args.file, rtscts=rtscts) connection_description = os.path.split(port)[-1] + " @" + str( baud) else: # Use the port passed and assume serial connection print("Using serial device '%s'" % port) selected_driver = s.get_driver(args.ftdi, port, baud, args.file, rtscts=args.rtscts) connection_description = os.path.split(port)[-1] + " @" + str(baud) with selected_driver as driver: with sbpc.Handler(sbpc.Framer(driver.read, driver.write, args.verbose)) as link: if args.reset: link(MsgReset(flags=0)) log_filter = DEFAULT_LOG_LEVEL_FILTER if args.initloglevel[0]: log_filter = args.initloglevel[0] with SwiftConsole(link, args.update, log_filter, cnx_desc=connection_description, error=args.error, json_logging=args.log, log_dirname=args.log_dirname, override_filename=args.logfilename, log_console=args.log_console, networking=args.networking, serial_upgrade=args.serial_upgrade) as console: console.configure_traits() # Force exit, even if threads haven't joined try: os._exit(0) except: pass
port_chooser = PortChooser() is_ok = port_chooser.configure_traits() port = port_chooser.port if not port or not is_ok: print "No serial device selected!" sys.exit(1) else: print "Using serial device '%s'" % port selected_driver = s.get_driver(args.ftdi, port, baud, args.file) with selected_driver as driver: with sbpc.Handler(sbpc.Framer(driver.read, driver.write, args.verbose)) as link: if args.reset: link(MsgReset()) log_filter = DEFAULT_LOG_LEVEL_FILTER if args.initloglevel[0]: log_filter = args.initloglevel[0] SwiftConsole(link, args.update, log_filter, port=port, error=args.error, json_logging=args.log, log_dirname=args.log_dirname[0]).configure_traits() # Force exit, even if threads haven't joined try: os._exit(0) except:
def reset_factory_defaults(self): # Reset the Piksi, with flag set to restore default settings self.link(MsgReset(flags=1))