Skip to content

Commit 236a344

Browse files
committed
Refactor boot delay handling into _get_boot_delay() method
Replaced the previous ad-hoc boot delay checks with a dedicated `_get_boot_delay()` method. This function reads deck memory before flashing and determines if an AI deck is attached, returning the appropriate boot delay. This improves clarity, reduces the risk of missing a required delay, and ensures consistency in handling delayed boots. The method is now called within `flash_full`, ensuring the correct boot delay is used in all standard flashing operations. Responsibility for handling the delay remains with the caller in other cases, making the function more flexible while maintaining internal consistency.
1 parent a9cdfa2 commit 236a344

File tree

1 file changed

+53
-17
lines changed

1 file changed

+53
-17
lines changed

cflib/bootloader/__init__.py

Lines changed: 53 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,48 @@ def _get_provided_nrf51_bl_version(self, flash_artifacts: List[FlashArtifact]):
178178

179179
return provided_nrf_bl_version
180180

181-
def flash(self, filename: str, targets: List[Target], cf=None, enable_console_log: Optional[bool] = False):
181+
def _get_boot_delay(self, cf: Optional[Crazyflie] = None) -> float:
182+
"""
183+
Determines the boot delay for the Crazyflie.
184+
This method calculates the boot delay based on the presence of specific decks.
185+
If the AI deck is attached, a longer boot delay is used.
186+
@return: The boot delay in seconds. Returns -1 if no deck memory is found.
187+
@rtype: float
188+
@raises RuntimeError: If there is a failure in reading the decks.
189+
"""
190+
191+
if cf is not None and cf.link:
192+
cf.close_link()
193+
194+
try:
195+
with SyncCrazyflie(self.clink, cf=Crazyflie()) as scf:
196+
deck_mems = scf.cf.mem.get_mems(MemoryElement.TYPE_DECK_MEMORY)
197+
deck_mems_count = len(deck_mems)
198+
if deck_mems_count == 0:
199+
return -1
200+
201+
mgr = deck_memory.SyncDeckMemoryManager(deck_mems[0])
202+
try:
203+
decks = mgr.query_decks()
204+
except RuntimeError as e:
205+
if self.progress_cb:
206+
message = f'Failed to read decks: {str(e)}'
207+
self.progress_cb(message, 0)
208+
logger.error(message)
209+
time.sleep(2)
210+
raise RuntimeError(message)
211+
212+
if any(deck.name in ['bcAI:gap8', 'bcAI:esp'] for deck in decks.values()):
213+
return 5.0
214+
except Exception as e:
215+
# If we fail to connect to the Crazyflie in firmware mode, we assume the AI-deck is attached
216+
print(f'Failed to connect to Crazyflie in firmware mode: {str(e)}. Setting boot delay to 5.0 seconds')
217+
return 5.0 # AI-deck may be attached
218+
219+
return 0.0
220+
221+
def flash(self, filename: str, targets: List[Target], cf=None, enable_console_log: Optional[bool] = False,
222+
boot_delay: Optional[float] = 0.0):
182223
# Separate flash targets from decks
183224
platform = self._get_platform_id()
184225
flash_targets = [t for t in targets if t.platform == platform]
@@ -276,23 +317,21 @@ def flash(self, filename: str, targets: List[Target], cf=None, enable_console_lo
276317
self.progress_cb('Restarting firmware to update decks.', int(0))
277318

278319
# Reset to firmware mode
279-
self.reset_to_firmware(boot_delay=5.0)
320+
self.reset_to_firmware(boot_delay=boot_delay)
280321
self.close()
281322
time.sleep(2)
282323

283324
# Flash all decks and reboot after each deck
284325
current_index = 0
285326
while current_index != -1:
286327
current_index = self._flash_deck_incrementally(deck_artifacts, deck_targets, current_index,
287-
enable_console_log=enable_console_log)
328+
enable_console_log=enable_console_log,
329+
boot_delay=boot_delay)
288330
if self.progress_cb:
289331
self.progress_cb('Deck updated! Restarting...', int(100))
290332
if current_index != -1:
291333
PowerSwitch(self.clink).reboot_to_fw()
292-
if any(deck.target in ['bcAI:gap8', 'bcAI:esp'] for deck in deck_targets):
293-
time.sleep(7)
294-
else:
295-
time.sleep(2)
334+
time.sleep(2.0 + boot_delay)
296335

297336
# Put the crazyflie back in Bootloader mode to exit the function in the same state we entered it
298337
self.start_bootloader(warm_boot=True, cf=cf)
@@ -321,6 +360,9 @@ def flash_full(self, cf: Optional[Crazyflie] = None,
321360
Flash .zip or bin .file to list of targets.
322361
Reset to firmware when done.
323362
"""
363+
# Get the required boot delay
364+
boot_delay = self._get_boot_delay(cf=cf)
365+
324366
if progress_cb is not None:
325367
self.progress_cb = progress_cb
326368
if terminate_flash_cb is not None:
@@ -336,7 +378,7 @@ def flash_full(self, cf: Optional[Crazyflie] = None,
336378
info_cb(self.protocol_version, connected)
337379

338380
if filename is not None:
339-
self.flash(filename, targets, cf, enable_console_log=enable_console_log)
381+
self.flash(filename, targets, cf, enable_console_log=enable_console_log, boot_delay=boot_delay)
340382
self.reset_to_firmware(boot_delay=5.0)
341383

342384
def _get_flash_artifacts_from_zip(self, filename):
@@ -549,7 +591,7 @@ def console_callback(self, text: str):
549591
print(text, end='')
550592

551593
def _flash_deck_incrementally(self, artifacts: List[FlashArtifact], targets: List[Target], start_index: int,
552-
enable_console_log: Optional[bool] = False):
594+
enable_console_log: Optional[bool] = False, boot_delay=0.0):
553595
flash_all_targets = len(targets) == 0
554596
if self.progress_cb:
555597
self.progress_cb('Identifying deck to be updated', 0)
@@ -604,10 +646,7 @@ def _flash_deck_incrementally(self, artifacts: List[FlashArtifact], targets: Lis
604646
self.progress_cb(f'Updating deck {deck.name}', 0)
605647

606648
# Test and wait for the deck to be started
607-
if any(deck.name in ['bcAI:gap8', 'bcAI:esp'] for deck in decks.values()):
608-
timeout_time = time.time() + 9
609-
else:
610-
timeout_time = time.time() + 4
649+
timeout_time = time.time() + 4. + boot_delay
611650
while not deck.is_started:
612651
if time.time() > timeout_time:
613652
raise RuntimeError(f'Deck {deck.name} did not start')
@@ -634,10 +673,7 @@ def _flash_deck_incrementally(self, artifacts: List[FlashArtifact], targets: Lis
634673
continue
635674

636675
# Wait for bootloader to be ready
637-
if any(deck.name in ['bcAI:gap8', 'bcAI:esp'] for deck in decks.values()):
638-
timeout_time = time.time() + 9
639-
else:
640-
timeout_time = time.time() + 4
676+
timeout_time = time.time() + 4. + boot_delay
641677
while not deck.is_bootloader_active:
642678
if time.time() > timeout_time:
643679
raise RuntimeError(f'Deck {deck.name} did not enter bootloader mode')

0 commit comments

Comments
 (0)