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}')
示例#2
0
    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