stm32-rs: Rust PACs for STM32 Microcontrollers
Embedded Rust device crates for STM32 microcontrollers
At a glance
- What is it?
- stm32-rs generates family-specific Rust peripheral access crates from patched STM32 SVD files. It suits firmware developers who need register-level Rust APIs, but its documentation explicitly warns that not every register has been tested on hardware.
- Who is it for?
- Adopt stm32-rs when an STM32 firmware project needs a generated, register-level Rust API and its device family is supported at the required revision. Do not treat its API coverage as proof of hardware correctness or use it when a higher-level HAL is required.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 37 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What stm32-rs solves for STM32 Rust firmware
stm32-rs addresses the gap between STM32 hardware descriptions and Rust code. A microcontroller has many memory-mapped peripherals and registers, while application firmware needs typed access to those facilities. The project generates Rust device crates that expose peripherals through APIs produced by `svd2rust` and a community-built collection of SVD patches.
The intended users are embedded Rust developers working directly with STM32 devices. This is low-level device support, not an application framework. A program using one of these crates still has to establish the target's execution environment, clocks, pins, interrupt configuration, and peripheral sequencing. The crates solve the binding and peripheral API layer; they do not turn an STM32 board into a ready-made application platform.
There is one published crate per device family, such as `stm32f4`, `stm32g4`, or `stm32h7`. Each supported device is a feature-gated module inside its family crate. That arrangement matters because `stm32f4` alone does not identify a part such as `stm32f405`. The application selects both the family dependency and the specific device feature.
The README describes these packages as peripheral access crates, or PACs. They are most relevant when register-level control is needed. If the requirement is a high-level abstraction that handles common peripheral workflows, this repository alone is the wrong layer. A higher-level STM32 Rust framework would be a different kind of dependency, although the documentation does not name or define one.
The SVD patching and crate generation pipeline
The repository is primarily a source and tooling project. According to the README, the STM32-rs repository contains patches for underlying SVD files and the tooling needed to generate crates. Generated Rust source is published through separate family crates, while the generated code can also be inspected in the `stm32-rs-nightlies` repository, which the documentation says is rebuilt after each commit to `stm32-rs` `master`.
The Makefile exposes the main stages. `make patch` produces patched SVD files, and `make svd2rust` generates device crates. The default `all` target combines those stages. Other targets cover extraction, conversion, formatting, checks, cleanup, and related repository artifacts. The Makefile names `devices/patches/`, `devices/fields/`, and `devices/collect/` as inputs to the generation flow, while `svd/vendor/` contains the ST-supplied SVD archives shown in the README diagram.
The generated API is based on `svd2rust`. This makes the API's shape dependent on a generated binding model rather than on a small hand-written abstraction over each STM32 family. Device selection is handled through crate features. The optional `rt` feature is described as helpful and links readers to the `svd2rust` documentation for its exact behavior.
The project publishes a coverage site with per-chip, register, and field information. The README defines coverage carefully: a documented field may list possible values, and even a chip with low coverage is expected to expose every register and field through the API. Documentation coverage and hardware validation are therefore different measures. The repository explicitly warns that not every register of every device has been tested on hardware and says errors or omissions may remain.
Adding an STM32F405 device crate and taking peripherals
The README's first-use path begins in an existing Rust project's `Cargo.toml`. This example selects the `stm32f405` device in the `stm32f4` family and also enables `rt`. Replace `stm32f4` and `stm32f405` with the target family and part; the family crate README contains the complete supported-device list.
[dependencies.stm32f4]
version = "0.16.0"
features = ["stm32f405", "rt"]After Cargo resolves that dependency, application code can request the singleton peripheral set for the selected device. The following is the complete Rust example given by the project README.
use stm32f4::stm32f405;
let mut peripherals = stm32f405::Peripherals::take().unwrap();`Peripherals::take()` returns the device peripheral collection used by generated STM32 APIs. The README does not document what happens when `take()` returns `None`, so calling `unwrap()` means the example will panic if that case occurs. It also does not provide a complete blinking program, board initialization sequence, linker configuration, flashing procedure, or target-specific build command. Those parts depend on the selected STM32 device and the surrounding embedded setup.
For development against the latest repository output rather than a published family-crate version, the README documents a Git dependency against `stm32-rs-nightlies`. The device feature remains explicit in the manifest.
[dependencies.stm32f4]
git = "https://github.com/stm32-rs/stm32-rs-nightlies"
features = ["stm32f405", "rt"]Wait, exactness matters. The documented Git URL is `https://github.com/stm32-rs/stm32-rs-nightlies`, so the usable block is below.
[dependencies.stm32f4]
git = "https://github.com/stm32-rs/stm32-rs-nightlies"
features = ["stm32f405", "rt"]The documentation says nightly builds should be as stable as the latest release while containing newer patches and updates. That is a project statement, not an independent compatibility guarantee.
Generating patched SVD files and Rust crates locally
Local generation is intended for contributors or developers who need to reproduce the repository's code-generation process. On x86-64 Linux, the documented `make install` target downloads prebuilt tools at the versions currently used by stm32-rs. On other systems, the README directs maintainers to check `scripts/tool_install.sh` and install pinned tools through Cargo.
cargo install form --version 0.13.0
cargo install svdtools --version 0.5.0
cargo install svd2rust --version 0.37.1
rustup component add rustfmtThese commands install `form`, `svdtools`, and `svd2rust`, followed by the Rust formatting component. The version pins apply to the generation instructions at that point and should be checked against `scripts/tool_install.sh` rather than assumed to describe every future toolchain.
The main local generation commands are documented directly by the README.
make patch
make svd2rust`make patch` applies the device definitions to produce patched SVD files. `make svd2rust` runs the crate-generation stage. Formatting is optional and uses a separate target.
make formThe README notes that parallel execution may be useful for `make patch`. For Windows, it describes a `cargo-make` alternative. The required runner installation and patch command are shown here.
cargo install cargo-make
cargo make patchThis workflow is substantial. It requires several Rust tools, source SVD data, device patch files, generated outputs, and enough disk and processing capacity for generation across many device families. It is appropriate when inspecting or changing generated device support. It is unnecessary for an application that can use a published family crate.
Coverage, maintenance, and upgrade boundaries
The repository is not archived, and the last push was on 2026-09-16. That is recent activity, but it does not erase the difference between repository changes and published crate releases. The listed releases are `v0.15.1` on 2022-07-04, `v0.15.0` on 2022-07-04, and `v0.14.0` on 2021-10-03. Newer repository patches may therefore be visible through the nightly-build path before they appear in a named release.
This creates a concrete upgrade decision. A project can pin a published family-crate version for reproducible dependency resolution, or use `stm32-rs-nightlies` for repository updates. The latter follows another repository whose generated code is rebuilt after commits to `master`. The documentation does not describe a stable release channel for every nightly crate, compatibility policy across device additions, or a rollback procedure.
Coverage also needs precise interpretation. A register can exist in the generated API while its field descriptions remain incomplete. Conversely, a documented possible value does not establish that the field was exercised on physical hardware. The README makes no correctness guarantee and asks users to report bugs. Engineers adopting a PAC should inspect the specific peripheral documentation rather than treating crate availability as validation.
The repository includes `LICENSE-APACHE` and `LICENSE-MIT`, while the repository metadata identifies `Apache-2.0`. This article does not interpret the licensing terms or provide legal advice. Users who modify or redistribute generated crates should inspect the applicable license files and dependency metadata directly.
stm32-rs compared with direct svd2rust use
The closest documented alternative is generating a device crate directly with `svd2rust`. Both approaches can produce Rust bindings from SVD descriptions, but they have different maintenance boundaries. `svd2rust` is the generator that creates bindings. stm32-rs adds an STM32-specific input and maintenance layer: ST-supplied SVD archives, device patches, field information, collection files, conversion steps, and repository Makefile targets.
Direct `svd2rust` use may fit a project that already controls its SVD inputs, generator version, and device corrections. It avoids depending on the stm32-rs patch set, although the project then owns the quality and consistency of those inputs. That ownership is a cost when working with a large STM32 portfolio.
stm32-rs is the more relevant choice when the application should consume the community-maintained STM32 device definitions and published family crates. Its convenience comes with boundaries: users must select the correct device feature, understand that coverage does not imply hardware testing, and decide between published versions and generated nightly output. Neither path supplies the board bring-up or high-level peripheral behavior that firmware may still need.
For application code, the PAC is most appropriate when direct register access is a design requirement. It is less suitable when the same application must support many unrelated STM32 families through one stable abstraction, or when the team requires documented, hardware-validated support for every field used.
Editorial conclusion
Adopt stm32-rs when an STM32 firmware project needs a generated, register-level Rust API and its device family is supported at the required revision. Do not treat its API coverage as proof of hardware correctness or use it when a higher-level HAL is required. Verify the exact device feature, generated documentation coverage, runtime setup, and required `svd2rust` behavior before committing the firmware design.
Frequently asked questions
Which stm32-rs crate should an STM32F405 project use?
The README uses `stm32f4` as the family dependency and `stm32f405` as the device feature. It also shows enabling the optional `rt` feature.
How do I use the latest stm32-rs generated crates?
The documented approach adds the family crate from `https://github.com/stm32-rs/stm32-rs-nightlies` and enables the target device and `rt` features. The README says this repository is rebuilt after each update to `master`.
Does stm32-rs prove that every STM32 register works correctly on hardware?
No. The README states that not every register of every device has been tested on hardware and warns that errors or omissions may remain.
How are stm32-rs device crates generated locally?
The repository documentation uses `make patch` to produce patched SVD files and `make svd2rust` to generate device crates. Tool installation depends on platform, and other systems may need to check the versions in `scripts/tool_install.sh`.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/stm32-rs-stm32-rs)Was this useful?