# Crazyflie firmware: Crazyflie 1.0 support ends at 2017.06

> crazyflie-firmware is the C firmware for Bitcraze quadcopters and the Roadrunner tag, built with a Makefile targeting Cortex-M4 over FreeRTOS. The repository's clearest design decision is that Crazyflie 1.0 support stopped at the 2017.06 release and lives on as a branch.

**bitcraze/crazyflie-firmware** — The main firmware for the Crazyflie Nano Quadcopter, Crazyflie Bolt Quadcopter and Roadrunner Positioning Tag.

- Repository: https://github.com/bitcraze/crazyflie-firmware
- Stars: 1,562 · Forks: 1,292
- Language: C
- License: GPL-3.0
- Published: 2026-10-16 · Updated: 2026-10-16 · Language: en
- Canonical page: https://hysenlabs.com/projects/bitcraze-crazyflie-firmware

## Two platforms, one branch, and a tag that is the archive

The first structural decision is stated at the very top of the README, and it is the kind of thing that saves a newcomer an afternoon.

The 2017.06 release was the last release with Crazyflie 1.0 support. If you want to work with a Crazyflie 1.0 and modify the code, the instruction is to clone the repository and branch off from the 2017.06 tag. Not from an old branch, not from a release archive: from the tag in this repository.

That choice keeps one history rather than two. Everything after 2017.06 targets the Crazyflie 2.x range and the Roadrunner, as the description states, covering the Nano Quadcopter, the Bolt Quadcopter and the Roadrunner Positioning Tag. The default branch is `master`, and the release tags follow a calendar scheme: 2026.08, with 2026.08-rc1 and 2026.08-rc2 preceding it on dates two to three days apart.

That tag scheme has a practical consequence for automation. 

The 1.0 situation also illustrates a choice Bitcraze made deliberately: to stop supporting a hardware platform in the main line and leave the last working state addressable, rather than to keep compatibility shims in the current code. If you are maintaining an older fleet, that is the pattern to follow, and the cost is that anything you build on 1.0 gets no upstream fixes.

## The Makefile is the documentation of the target hardware

The root Makefile is the most informative file in the repository for understanding what this firmware is and what it targets.

The CPU is declared as `stm32f4`, and the compiler flags are spelled out: `-mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -g3`, with `-fno-math-errno`, `ARM_MATH_CM4`, `__FPU_PRESENT=1` and IEEE half-precision floats enabled. Defines include `STM32F4XX`, `STM32F40_41xxx`, `HSE_VALUE=8000000` and `USE_STDPERIPH_DRIVER`. That is an STMicroelectronics STM32F4 part with a Cortex-M4 core, hardware floating point, an 8 MHz external crystal, and the vendor peripheral library rather than the HAL. The `-Wno-array-bounds` and `-Wno-stringop-overflow` suppressions show the code is compiled with a toolchain new enough to produce warnings against this style of firmware.

The real-time kernel is FreeRTOS, vendored rather than fetched. The Makefile points `FREERTOS` at `vendor/FreeRTOS` and `PORT` at the GCC ARM_CM4F port, which is why `vendor/` exists as a directory and why `.gitmodules` is present in the root listing for the parts that are still submodules.

Linking is done against `FLASH_CLOAD.ld` from `tools/make/F405/linker`, with `--specs=nosys.specs --specs=nano.specs -nostdlib`, no executable stack, section garbage collection, and a linker option `--undefined=uxTopUsedPriority` that forces the FreeRTOS scheduler symbol to be retained so the task priority table survives `--gc-sections`. Two load addresses are declared, `0x8000000` for a normal build and `0x8004000` for a Cload build, which is how the firmware is flashed over the radio bootloader.

Flashing has two paths and the Makefile names both. OpenOCD is configured for an ST-LINK v2 interface and an STM32F4 target, overridable through `OPENOCD`, `OPENOCD_INTERFACE`, `OPENOCD_TARGET` and `OPENOCD_CMDS`. DFU is available through `dfu-util`. For the Cload path there is a detail worth knowing: on WSL the script deliberately calls the Windows Python interpreter, `python.exe -m cfloader`, instead of the Linux one.

## Out-of-tree apps and the overrides folder

The `examples/` directory is what makes this a platform rather than a product. Twelve example applications ship in the tree, and the names describe the extension surface.

The basics are `app_hello_world/` in C and `app_hello_world-cpp/`, plus `app_hello_file_tree/`, which suggests an application can be distributed as a file tree rather than a single source file. `app_hello_rs/` points at Rust support in the build.

Then there is the set that maps to the framework features. `app_internal_param_log/` and `app_persistent_param/` show the parameter system, in memory and persisted. `app_peer_to_peer/` and `app_p2p_DTR/` cover the peer-to-peer radio link with data rate tradeoffs. `app_state_stream_aideck/` shows state streaming to an AI deck, which is an expansion board. `app_out_of_tree_controller/` is the important one for anyone planning real work: it demonstrates a controller that lives outside the firmware tree.

The Makefile explains how that works, and the comment is unusually precise. An out-of-tree app can shadow in-tree interface headers, for example a custom `platform_defaults.h`, by placing them in an `overrides` subfolder, and that folder gets first priority in the include search path ahead of every other entry.

That single mechanism is what the rest of the architecture rests on. If you can shadow a header and build an app outside the tree, you can write your own flight controller, your own sensor pipeline or your own protocol handler without maintaining a fork of the whole firmware. For research work this is the difference between a project and a contribution backlog.

Supporting infrastructure is visible in the root listing: `Kconfig` and `configs/` for configuration, `app_api/` for the application API, `bq_config`, `build_targets.json`, `module.json` and `cffirmware_setup.py` for build and setup, `generated/` for generated sources, `bin/` for tools, `test/` and `test_python/` for the two test layers, `tools/make/` for the build system, and `docs/` including a `building-and-flashing/build.md` that the README points to. `pixi.toml`, `pixi.lock` and `flake.nix` alongside `flake.lock` mean the build environment is pinned through Pixi or Nix.

## Two test layers and generated API docs

Testing is split in a way that matches the two languages in the tree. There is a `test/` directory and a `test_python/` directory, and the README directs contributors to unit testing documentation on the Bitcraze site rather than describing the harness in the README itself. A `.flake8` file in the root covers the Python side, which is real enough to suggest a meaningful amount of tooling.

API documentation is generated rather than written. The README says the easiest way to generate it is to use the toolbelt, an external Bitcraze repository:

```bash
tb build-docs
```

and to view it as a web page:

```bash
tb docs
```

Note what those commands are not. They are not `make docs`, and they do not come with this repository. The toolbelt is a separate tool you install, so documentation generation is a two-project setup rather than a single clone. If you need to read the API offline, plan for that or use the published documentation site instead.

Documentation is split between two places. Generated API documentation comes from the source, and hand-written official documentation lives on the Bitcraze website under `bitcraze.io/documentation`, with the README linking the repository documentation for the current branch. The `docs/` directory in the repository holds developer material such as the building and flashing instructions.

For contributing, the README routes you to a contribute page on the website and a `RELEASE_CHECKLIST.md` in the root that describes how a release is put together. That checklist is a small signal about how releases actually happen here, and it is more useful to a prospective contributor than the release notes would be.

One detail worth flagging in the licensing section: the project's SPDX metadata says GPL-3.0 while the README states the code is licensed under LGPL-3.0, with the actual terms in `LICENSE.txt` at the root. The README text is the more specific statement, but the discrepancy between the two is exactly the kind of thing to check in the licence file before you ship firmware derived from it.

## Maintenance state and who this is for

The repository is not archived, and the last push was on 2026-10-14. The 2026.08 release with two release candidates before it indicates an active release practice, and the presence of a CI badge in the README title, a pre-commit-style `.flake8`, and pinned environment files all point to a maintained codebase rather than a hobby project.

The commit cadence and the audience together tell you what kind of user this is for. The extension mechanisms, the out-of-tree examples and the Cload flashing path all serve experimentation rather than fleet management.

Where it is the wrong choice is equally clear. There is no product certification story, no long-term support branch visible in the README, and a date-based tag scheme that does not promise API stability across releases. For a commercial product, the LGPL obligation on a linked firmware image needs proper review, and the platform migration path from 1.0 shows what happens when hardware ages out: you end up on a tag.

The closest alternatives are not software. A more capable open flight stack written for a different hardware target gives you more control over the control loop but abandons the Crazyflie hardware advantage, which is its size, weight and safety margins. The comparison that actually matters is against the stock firmware for your board: if you are not modifying behaviour, you are paying complexity you do not need.

## Conclusion

Crazyflie firmware fits a research group that wants full control of flight code on hardware built to be modified, and the out-of-tree app and parameter mechanisms make it a genuine development platform rather than a firmware blob. Do not adopt it for a commercial product without reading the LGPL obligations, and do not start from master expecting Crazyflie 1.0 to build. Verify first which platform your board is, since the current README names the Crazyflie 2.x range and the Roadrunner while 1.0 lives only on the 2017.06 tag.

## FAQ

### How do I build the Crazyflie firmware?

The build is driven by the root Makefile, which targets an STM32F4 with a Cortex-M4 core using hard floating point, and links against FreeRTOS vendored in the repository. The README points to the building and flashing instructions in the docs folder of the repository for the full procedure.

### Can I still build firmware for the Crazyflie 1.0?

Yes, but only from a fixed point. The README states that the 2017.06 release was the last with Crazyflie 1.0 support, and that you should clone the repository and branch off from the 2017.06 tag. Anything after that tag targets the Crazyflie 2.x range and the Roadrunner.

### How do I flash firmware to a Crazyflie?

The Makefile defines two flashing paths. OpenOCD is configured for an ST-LINK v2 interface and an STM32F4 target, with the variables OPENOCD, OPENOCD_INTERFACE, OPENOCD_TARGET and OPENOCD_CMDS available for override. The Cload path uses the cfloader Python module, and under WSL the Makefile deliberately calls the Windows Python interpreter instead.

### How do I write my own controller without forking the firmware?

Use the out-of-tree app mechanism. The examples directory contains app_out_of_tree_controller, and the Makefile documents that an out-of-tree app can shadow in-tree interface headers such as platform_defaults.h by placing them in an overrides subfolder, which is given first priority in the include search path.

### What license is the Crazyflie firmware released under?

The README states the code is licensed under LGPL-3.0, with the terms in LICENSE.txt at the repository root. The project's SPDX metadata says GPL-3.0, so read the LICENSE file rather than relying on either label.

### How are releases named for Crazyflie firmware?

By calendar date. The recent tags are 2026.08, with 2026.08-rc1 and 2026.08-rc2 before it. There is no semantic version contract in the tag name, so pin the exact tag your application was built against.

## Sources

- [bitcraze/crazyflie-firmware on GitHub](https://github.com/bitcraze/crazyflie-firmware)
- [Issues](https://github.com/bitcraze/crazyflie-firmware/issues)
- [License: GPL-3.0](https://github.com/bitcraze/crazyflie-firmware/blob/master/LICENSE)
- [README](https://github.com/bitcraze/crazyflie-firmware/blob/master/README.md)
- [Releases](https://github.com/bitcraze/crazyflie-firmware/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/bitcraze-crazyflie-firmware
