Skip to content

Add swarm bootload info and flash (unicast) - #32

Merged
evoggy merged 3 commits into
mainfrom
evoggy/swarm-bootload
Oct 5, 2026
Merged

evoggy merged 3 commits into
mainfrom
evoggy/swarm-bootload

Conversation

@evoggy

@evoggy evoggy commented Oct 5, 2026 •

Copy link
Copy Markdown
Member

Adds cfcli swarm bootload info and cfcli swarm bootload flash.

This is unicast only for now: the Crazyflies are flashed one after another, the same way cfcli bootload flash flashes one. Broadcast flashing, where every Crazyflie with a new enough bootloader receives each image at the same time, will follow in a separate PR. It depends on bitcraze/cfloader-rs#3, which isn't merged or released yet.

What's in it

cfcli swarm bootload flash

cfcli swarm bootload flash --release 2026.08
cfcli swarm bootload flash --bin stm32-fw=cf21bl.bin --cf CF-01,CF-02
  • Arguments: takes the same --release, --zip, --bin and --targets as bootload flash, plus the usual --cf, --exclude and --swarm.
  • Checks before touching any Crazyflie: the release, the files and the targets.
  • Checks before flashing anything: the firmware for every platform in the swarm is prepared up front, so a --zip built for another platform stops the command instead of failing halfway.
  • Flashing: one Crazyflie after another, with the normal flash output under a header per Crazyflie and a summary table at the end. A Crazyflie that fails doesn't stop the others, and the exit code follows the swarm rules (0, the usual code if all failed the same way, otherwise 50). A unicast flash keeps the radio busy, so flashing several at once wouldn't be faster.

Swarms with several platforms

STM32 images differ between platforms (a Crazyflie 2.1 and a 2.1 Brushless can't run each other's), and nRF51 images differ for some of them:

  • --release: downloaded per platform, so every Crazyflie gets its own platform's files.
  • STM32 and nRF51 images given with --bin: only flashed when all the Crazyflies to flash have the same platform. Otherwise the command stops before flashing anything, listing the platforms and their Crazyflies.
  • Deck firmware: works whatever the Crazyflie, so it still goes to all of them.
  • --platform cf21|cf21bl|bolt11|flapper|tag: flashes only the Crazyflies of one platform and skips the rest, so a mixed swarm is flashed one platform at a time.

cfcli swarm bootload info

CF    | nRF51 bootloader | STM32 bootloader | Broadcast
------+------------------+------------------+-----------
CF-01 | 0x11             | 0x11             | yes
CF-02 | 0x10             | 0x10             | no

Refactoring

  • Shared flash handling: the release, --bin and --targets handling of bootload flash moves out of main.rs into utils/flash_source.rs, and the four arguments into FirmwareSourceArgs, shared by both commands. bootload flash works as before.
  • Platform names: shared by both commands. An unknown --platform for bootload flash --cold now exits 30 instead of 1.
  • Smaller changes: bootloader::bootloader_versions() reads both versions and restarts into the firmware, and FirmwareUpgrade is Clone.

Fix: bootloader protocol version

get_info read the protocol version from byte 1 of the GET_INFO answer, which is the GET_INFO command echoed back. So every bootloader reported 0x10, and bootload info always printed "Protocol Version: 16". It also read the CPU ID as 2 bytes instead of 12. The answer is [target, GET_INFO, page size, buffer pages, flash pages, start page, 12-byte CPU ID, protocol version], as cfloader and cflib read it. The version now comes from byte 22 (0 for bootloaders from before it existed), and the CPU ID is printed in full. This affects bootload info too.

Testing

  • Unit tests: 61. The new ones cover the platform names, which --bin keys are platform-bound, and the refusal for mixed platforms.
  • Without flashing anything:
    • An unknown release (20), an unknown target (30, after the release download, before flashing), an unknown platform (30), and --platform with no matching Crazyflie (20).
    • A --bin that can't be read stops before flashing, after reading the platforms.
    • Crazyflies that don't answer give 10 for both commands.
  • On hardware, with 3 Crazyflie 2.1 Brushless on 3 Crazyradios:
    • swarm bootload flash was run on the swarm.
    • swarm bootload info showed protocol 0x11 on both bootloaders after the version fix (0x10 before it). The Crazyflies were back in their firmware afterwards.

evoggy added 3 commits October 5, 2026 22:16
cfcli swarm bootload flash flashes every Crazyflie of a swarm, one after
another over unicast, the same way bootload flash flashes one, and takes
the same --release, --zip, --bin and --targets. The release, the files
and the targets are resolved before any Crazyflie is touched; each
Crazyflie's platform then decides which files of a release it gets, so
a swarm can mix platforms. A Crazyflie that fails doesn't stop the
others, and a summary shows how each one went.

cfcli swarm bootload info shows the bootloader versions of each
Crazyflie, and whether both bootloaders can take broadcast flashing
(protocol 0x11). Unlike bootload info, it restarts each Crazyflie back
into its firmware afterwards, and gives each Crazyflie 15 s so that one
that hangs doesn't hold up the rest.

The release, --bin and --targets handling moves out of main.rs into
utils/flash_source.rs, and the four arguments into FirmwareSourceArgs,
shared by both commands. bootload flash works as before.
STM32 images differ between platforms (a Crazyflie 2.1 and a 2.1
Brushless can't run each other's), and so do nRF51 images for some of
them. A release has the files for every platform and is downloaded per
platform, but --bin gave the same file to every Crazyflie of a swarm.

swarm bootload flash now refuses --bin STM32 or nRF51 images when the
Crazyflies to flash have more than one platform, before flashing
anything. Deck firmware works whatever the Crazyflie and still goes to
all. --platform cf21|cf21bl|bolt11|flapper|tag flashes only the
Crazyflies of one platform and skips the others, so a mixed swarm can be
flashed one platform at a time.

The firmware for every platform is now prepared before any Crazyflie is
flashed: a zip built for another platform stops the command instead of
failing those Crazyflies halfway, and each platform is prepared once.

The platform names move into utils/flash_source.rs, shared with the
--platform of bootload flash --cold, which now gives exit code 30 for an
unknown platform.
The answer to GET_INFO is [target, GET_INFO, page size, buffer pages,
flash pages, start page, 12-byte CPU ID, protocol version], as cfloader
and cflib read it. get_info took the protocol version from byte 1, which
is the GET_INFO command echoed back, so every bootloader reported 0x10:
bootload info always printed "Protocol Version: 16", and swarm bootload
info said no Crazyflie could take broadcast flashing. It also read the
CPU ID as 2 bytes instead of 12.

The version now comes from byte 22 (0 for bootloaders from before it was
added, which stop after the CPU ID) and the CPU ID is printed in full.
@evoggy
evoggy merged commit fb4bf9f into main Oct 5, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant