Skip to content

Commit 0160110

Browse files
authored
Merge pull request #528 from bitcraze/rik/flash-detect-boot-delay
Refactor boot delay handling into `_get_boot_delay()` method
2 parents a9cdfa2 + 236a344 commit 0160110

File tree

1 file changed

+53
-17
lines changed

1 file changed

+53
-17
lines changed

cflib/bootloader/__init__.py

+53-17
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)