def _flash_deck(self, artifacts: List[FlashArtifact], targets: List[Target]): flash_all_targets = len(targets) == 0 if self.progress_cb: self.progress_cb('Detecting deck to be updated', int(25)) with SyncCrazyflie(self.clink, cf=Crazyflie()) as scf: deck_mems = scf.cf.mem.get_mems(MemoryElement.TYPE_DECK_MEMORY) deck_mems_count = len(deck_mems) if deck_mems_count == 0: return mgr = deck_memory.SyncDeckMemoryManager(deck_mems[0]) decks = mgr.query_decks() for (deck_index, deck) in decks.items(): if self.terminate_flashing_cb and self.terminate_flashing_cb(): raise Exception('Flashing terminated') # Check that we want to flash this deck deck_target = [ t for t in targets if t == Target('deck', deck.name, 'fw') ] if (not flash_all_targets) and len(deck_target) == 0: print(f'Skipping {deck.name}') continue # Check that we have an artifact for this deck deck_artifacts = [ a for a in artifacts if a.target == Target('deck', deck.name, 'fw') ] if len(deck_artifacts) == 0: print( f'Skipping {deck.name}, no artifact for it in the .zip' ) continue deck_artifact = deck_artifacts[0] if self.progress_cb: self.progress_cb(f'Updating deck {deck.name}', int(50)) print(f'Handling {deck.name}') # Test and wait for the deck to be started while not deck.is_started: print('Deck not yet started ...') time.sleep(500) deck = mgr.query_decks()[deck_index] # Run a brunch of sanity checks ... if not deck.supports_fw_upgrade: print( f'Deck {deck.name} does not support firmware update, skipping!' ) continue if not deck.is_fw_upgrade_required: print(f'Deck {deck.name} firmware up to date, skipping') continue if not deck.is_bootloader_active: print( f'Error: Deck {deck.name} bootloader not active, skipping!' ) continue # ToDo, white the correct file there ... result = deck.write_sync(0, deck_artifact.content) if result: if self.progress_cb: self.progress_cb( f'Deck {deck.name} updated succesfully!', int(75)) else: if self.progress_cb: self.progress_cb(f'Failed to update deck {deck.name}', int(0)) raise Exception(f'Failed to update deck {deck.name}')
def _flash_deck_incrementally(self, artifacts: List[FlashArtifact], targets: List[Target], start_index: int): flash_all_targets = len(targets) == 0 if self.progress_cb: self.progress_cb('Identifying deck to be updated', 0) with SyncCrazyflie(self.clink, cf=Crazyflie()) as scf: # Uncomment to enable console logs from the CF. # scf.cf.console.receivedChar.add_callback(self.console_callback) deck_mems = scf.cf.mem.get_mems(MemoryElement.TYPE_DECK_MEMORY) deck_mems_count = len(deck_mems) if deck_mems_count == 0: return -1 mgr = deck_memory.SyncDeckMemoryManager(deck_mems[0]) try: decks = mgr.query_decks() except RuntimeError as e: if self.progress_cb: message = f'Failed to read decks: {str(e)}' self.progress_cb(message, 0) logger.error(message) time.sleep(2) raise RuntimeError(message) for (deck_index, deck) in decks.items(): if self.terminate_flashing_cb and self.terminate_flashing_cb(): raise Exception('Flashing terminated') # Skip decks up to the start_index if deck_index < start_index: continue # Check that we want to flash this deck deck_target = [ t for t in targets if t == Target('deck', deck.name, 'fw') ] if (not flash_all_targets) and len(deck_target) == 0: print(f'Skipping {deck.name}, not in the target list') continue # Check that we have an artifact for this deck deck_artifacts = [ a for a in artifacts if a.target == Target('deck', deck.name, 'fw') ] if len(deck_artifacts) == 0: print( f'Skipping {deck.name}, no artifact for it in the .zip' ) continue deck_artifact = deck_artifacts[0] if self.progress_cb: self.progress_cb(f'Updating deck {deck.name}', 0) # Test and wait for the deck to be started timeout_time = time.time() + 5 while not deck.is_started: if time.time() > timeout_time: raise RuntimeError(f'Deck {deck.name} did not start') print('Deck not yet started ...') time.sleep(0.5) deck = mgr.query_decks()[deck_index] # Supports upgrades? if not deck.supports_fw_upgrade: print( f'Deck {deck.name} does not support firmware update, skipping!' ) continue # Reset to bootloader mode, if supported if deck.supports_reset_to_bootloader: print(f'Deck {deck.name}, reset to bootloader') deck.reset_to_bootloader() time.sleep(0.1) deck = mgr.query_decks()[deck_index] else: # Is an upgrade required? if not deck.is_fw_upgrade_required: print( f'Deck {deck.name} firmware up to date, skipping') continue # Wait for bootloader to be ready timeout_time = time.time() + 5 while not deck.is_bootloader_active: if time.time() > timeout_time: raise RuntimeError( f'Deck {deck.name} did not enter bootloader mode') print( f'Error: Deck {deck.name} bootloader not active yet...' ) time.sleep(0.5) deck = mgr.query_decks()[deck_index] progress_cb = self.progress_cb if not progress_cb: def progress_cb(msg: str, percent: int): frames = ['|', '/', '-', '\\'] frame = frames[int(percent) % 4] print(f'{frame} {percent}% {msg}') # Flash the new firmware deck.set_fw_new_flash_size(len(deck_artifact.content)) result = deck.write_sync(0, deck_artifact.content, progress_cb) if result: if self.progress_cb: self.progress_cb( f'Deck {deck.name} updated successful!', 100) else: if self.progress_cb: self.progress_cb(f'Failed to update deck {deck.name}', int(0)) raise RuntimeError(f'Failed to update deck {deck.name}') # We flashed a deck, return for re-boot next_index = deck_index + 1 if next_index >= len(decks): next_index = -1 return next_index # We have flashed the last deck return -1