def main(): # Initialise the CRTP link driver link = None try: cflib.crtp.init_drivers() link = cflib.crtp.get_link_driver("radio://") except Exception as e: print("Error: {}".format(str(e))) if link: link.close() sys.exit(-1) # Set the default parameters clink = None action = "info" boot = "cold" filename = None # type: Optional[str] targets = None # type: Optional[List[Target]] bl = None # type: Optional[Bootloader] if len(sys.argv) < 2: print() print("==============================") print(" CrazyLoader Flash Utility") print("==============================") print() print(" Usage:", sys.argv[0], "[CRTP options] <action> [parameters]") print() print("The CRTP options are described above") print() print("Crazyload option:") print(" info : Print the info of the bootloader " "and quit.") print(" Will let the target in bootloader " "mode") print(" reset : Reset the device in firmware mode") print(" flash <file> [targets] : flash the <img> binary file from " "the first") print(" possible page in flash and reset " "to firmware") print(" mode.") if link: link.close() sys.exit(0) # Analyse the command line parameters sys.argv = sys.argv[1:] argv = [] i = 0 while i < len(sys.argv): if sys.argv[i] == "--cold-boot" or sys.argv[i] == "-c": boot = "cold" elif sys.argv[i] == "--warm-boot" or sys.argv[i] == "-w": boot = "reset" i += 1 clink = sys.argv[i] else: argv += [sys.argv[i]] i += 1 sys.argv = argv # Analyse the command if len(sys.argv) < 1: action = "info" elif sys.argv[0] == "info": action = "info" elif sys.argv[0] == "reset": action = "reset" elif sys.argv[0] == "flash": if len(sys.argv) < 2: print("The flash action require a file name.") link.close() sys.exit(-1) action = "flash" filename = sys.argv[1] targets = [] # Dict[Target] for t in sys.argv[2:]: if t.startswith("deck-"): [deck, target, type] = t.split("-") targets.append(Target("deck", target, type)) else: [target, type] = t.split("-") targets.append(Target("cf2", target, type)) else: print("Action", sys.argv[0], "unknown!") link.close() sys.exit(-1) try: # Initialise the bootloader lib bl = Bootloader(clink) warm_boot = (boot == "reset") if warm_boot: print("Reset to bootloader mode ...") sys.stdout.flush() else: # The connection is done by a cold boot ... print("Restart the Crazyflie you want to bootload in the next"), print(" 10 seconds ..."), sys.stdout.flush() ###################################### # Doing something (hopefully) useful ###################################### if action == "info": def print_info(version: int, connected_targets: [Target]): print("Connected to bootloader on {} (version=0x{:X})".format( BootVersion.to_ver_string(version), version)) for target in connected_targets: print(target) # flash_full called with no filename will not flash, just call # our info callback bl.flash_full(None, warm_boot, None, print_info) elif action == "flash" and filename and targets: try: bl.flash_full(filename, warm_boot, targets) except Exception as e: print("Failed to flash: {}".format(e)) elif action == "reset": bl.reset_to_firmware() else: None except Exception as e: import traceback traceback.print_exc(file=sys.stdout) print(e) finally: ######################### # Closing the connection ######################### if bl: bl.close()
###################################### # Doing something (hopefully) useful ###################################### if action == "info": def print_info(version: int, connected_targets: [Target]): print("Connected to bootloader on {} (version=0x{:X})".format( BootVersion.to_ver_string(version), version)) for target in connected_targets: print(target) # flash_full called with no filename will not flash, just call # our info callback bl.flash_full(None, None, warm_boot, None, print_info) elif action == "flash" and filename and targets: try: bl.flash_full(None, filename, warm_boot, targets) except Exception as e: print("Failed to flash: {}".format(e)) elif action == "reset": bl.reset_to_firmware() else: None except Exception as e: import traceback traceback.print_exc(file=sys.stdout) print(e)
class CrazyloadThread(QThread): # Input signals declaration (not sure it should be used like that...) program = pyqtSignal(str, str) initiateColdBootSignal = pyqtSignal(str) resetCopterSignal = pyqtSignal() writeConfigSignal = pyqtSignal(int, int, float, float) # Output signals declaration programmed = pyqtSignal(bool) verified = pyqtSignal() statusChanged = pyqtSignal(str, int) connectedSignal = pyqtSignal() connectingSignal = pyqtSignal() failed_signal = pyqtSignal(str) disconnectedSignal = pyqtSignal() updateConfigSignal = pyqtSignal(int, int, float, float) updateCpuIdSignal = pyqtSignal(str) radioSpeedPos = 2 WARM_BOOT = 0 COLD_BOOT = 1 def __init__(self, crazyflie: cflib.crazyflie.Crazyflie): super(CrazyloadThread, self).__init__() self._terminate_flashing = False self._bl = Bootloader() self._cf = crazyflie self._boot_mode = self.COLD_BOOT # Make sure that the signals are handled by this thread event loop self.moveToThread(self) self.program.connect(self.programAction) self.initiateColdBootSignal.connect(self.initiateColdBoot) self.resetCopterSignal.connect(self.resetCopter) def __del__(self): self.quit() self.wait() def set_boot_mode(self, mode): self._boot_mode = mode def initiateColdBoot(self, linkURI): self.connectingSignal.emit() try: success = self._bl.start_bootloader(warm_boot=False) if not success: self.failed_signal.emit("Could not connect to bootloader") else: self.connectedSignal.emit() except Exception as e: self.failed_signal.emit("{}".format(e)) def programAction(self, filename, mcu_to_flash): targets = {} if mcu_to_flash: targets[mcu_to_flash] = ("fw", ) try: self._terminate_flashing = False self._bl.clink = self._cf.link_uri self._bl.flash_full(str(filename), self._boot_mode is self.WARM_BOOT, targets, None, self.statusChanged.emit, lambda: self._terminate_flashing) self.programmed.emit(True) except Exception as e: self.failed_signal.emit("{}".format(e)) self.programmed.emit(False) def terminate_flashing(self): self._terminate_flashing = True def resetCopter(self): try: self._bl.reset_to_firmware() except Exception: pass self._bl.close() self.disconnectedSignal.emit()