diff --git a/Tools/px_uploader.py b/Tools/px_uploader.py index b5ed3cafcf..f3db944023 100755 --- a/Tools/px_uploader.py +++ b/Tools/px_uploader.py @@ -191,11 +191,16 @@ class uploader(object): self.sn = b'' self.baudrate_bootloader = baudrate_bootloader self.baudrate_flightstack = baudrate_flightstack + self.baudrate_flightstack_idx = -1 def close(self): if self.port is not None: self.port.close() + def open(self): + if self.port is not None and not self.port.is_open: + self.port.open() + def __send(self, c): # print("send " + binascii.hexlify(c)) self.port.write(c) @@ -511,11 +516,25 @@ class uploader(object): self.__reboot() self.port.close() + def __next_baud_flightstack(self): + self.baudrate_flightstack_idx = self.baudrate_flightstack_idx + 1 + if self.baudrate_flightstack_idx >= len(self.baudrate_flightstack): + return False + + self.port.baudrate = self.baudrate_flightstack[self.baudrate_flightstack_idx] + + return True + def send_reboot(self): + if (not self.__next_baud_flightstack()): + return False + + print("Attempting reboot on %s with baudrate=%d..." % (self.port.port, self.port.baudrate), file=sys.stderr) + print("If the board does not respond, unplug and re-plug the USB connector.", file=sys.stderr) + try: # try MAVLINK command first self.port.flush() - self.port.baudrate = self.baudrate_flightstack self.__send(uploader.MAVLINK_REBOOT_ID1) self.__send(uploader.MAVLINK_REBOOT_ID0) # then try reboot via NSH @@ -532,6 +551,8 @@ class uploader(object): except Exception: pass + return True + # Detect python version if sys.version_info[0] < 3: @@ -541,9 +562,9 @@ else: # Parse commandline arguments parser = argparse.ArgumentParser(description="Firmware uploader for the PX autopilot system.") -parser.add_argument('--port', action="store", required=True, help="Serial port(s) to which the FMU may be attached") +parser.add_argument('--port', action="store", required=True, help="Comma-separated list of serial port(s) to which the FMU may be attached") parser.add_argument('--baud-bootloader', action="store", type=int, default=115200, help="Baud rate of the serial port (default is 115200) when communicating with bootloader, only required for true serial ports.") -parser.add_argument('--baud-flightstack', action="store", type=int, default=57600, help="Baud rate of the serial port (default is 57600) when communicating with flight stack(Mavlink or NSH), only required for true serial ports.") +parser.add_argument('--baud-flightstack', action="store", default="57600", help="Comma-separated list of baud rate of the serial port (default is 57600) when communicating with flight stack (Mavlink or NSH), only required for true serial ports.") parser.add_argument('--force', action='store_true', default=False, help='Override board type check and continue loading') parser.add_argument('--boot-delay', type=int, default=None, help='minimum boot delay to store in flash') parser.add_argument('firmware', action="store", help="Firmware file to be uploaded") @@ -575,6 +596,8 @@ try: else: portlist = patterns + baud_flightstack = [ int(x) for x in args.baud_flightstack.split(',') ] + for port in portlist: # print("Trying %s" % port) @@ -584,15 +607,15 @@ try: if "linux" in _platform: # Linux, don't open Mac OS and Win ports if "COM" not in port and "tty.usb" not in port: - up = uploader(port, args.baud_bootloader, args.baud_flightstack) + up = uploader(port, args.baud_bootloader, baud_flightstack) elif "darwin" in _platform: # OS X, don't open Windows and Linux ports if "COM" not in port and "ACM" not in port: - up = uploader(port, args.baud_bootloader, args.baud_flightstack) + up = uploader(port, args.baud_bootloader, baud_flightstack) elif "win" in _platform: # Windows, don't open POSIX ports if "/" not in port: - up = uploader(port, args.baud_bootloader, args.baud_flightstack) + up = uploader(port, args.baud_bootloader, baud_flightstack) except Exception: # open failed, rate-limit our attempts time.sleep(0.05) @@ -600,24 +623,31 @@ try: # and loop to the next port continue - # port is open, try talking to it - try: - # identify the bootloader - up.identify() - print("Found board %x,%x bootloader rev %x on %s" % (up.board_type, up.board_rev, up.bl_rev, port)) + found_bootloader = False + while (True): + up.open() - except Exception: - # most probably a timeout talking to the port, no bootloader, try to reboot the board - print("attempting reboot on %s..." % port) - print("if the board does not respond, unplug and re-plug the USB connector.") - up.send_reboot() + # port is open, try talking to it + try: + # identify the bootloader + up.identify() + found_bootloader = True + print("Found board %x,%x bootloader rev %x on %s" % (up.board_type, up.board_rev, up.bl_rev, port)) + break - # wait for the reboot, without we might run into Serial I/O Error 5 - time.sleep(0.5) + except Exception: + if not up.send_reboot(): + break - # always close the port - up.close() - continue + # wait for the reboot, without we might run into Serial I/O Error 5 + time.sleep(0.5) + + # always close the port + up.close() + + if not found_bootloader: + # Go to the next port + continue try: # ok, we have a bootloader, try flashing it