The State of Rust for Embedded Development in Mid-2026
A survey of where Rust stands for embedded and edge development in mid-2026, from bare-metal async on microcontrollers to services on embedded Linux, including the toolchain, the safety-certification story, the wireless gaps, and measurements from this blog's own boards.
Rust for Embedded Development in Mid-2026
Two of the boards on my desk are running Rust as I write this. One is an ST Nucleo-F401RE executing an async four-thread scheduling demo whose entire firmware image is 13 kilobytes, flashed and debugged with a single cargo run. The other is a Raspberry Pi 5 where Rust plays a completely different role: an ordinary Linux process, built with the full standard library, serving a web dashboard. A few years ago, choosing Rust for either job would have been an act of advocacy. In mid-2026 it is now a realistic option, and for a growing set of development teams it is the default one.
This article is a survey of how that happened and where the boundaries now sit: what the embedded Rust stack actually consists of, what changed in the toolchain and the institutions around the language, where Rust is genuinely production-ready, where it still is not, and how to decide between Rust and the C-based ecosystems (Zephyr chief among them) that this blog also uses heavily. Like its companion piece on the state of edge AI, it is a reading article rather than a building one: no code, important links, and a final section mapping the hands-on articles on this site (published and forthcoming) onto the landscape. Where the survey quotes flash sizes and API-migration pain, the numbers are first-hand, measured on the boards this blog builds with.
Why Rust reached embedded at all
The case for Rust is usually stated in one line – memory safety without garbage collection – but it is worth unpacking why it lands with impact in embedded work.
Embedded software is a C monoculture of long standing, and C's failure modes are well understood. Buffer overruns, use-after-free, data races between interrupt handlers and main-loop code: historical data from large system codebases, such as Microsoft's 2019 MSRC study, consistently attributes around 70 per cent of serious CVEs to memory-safety defects, and on a microcontroller these bugs are particularly expensive to find. There is no operating system to segfault your process, often no memory protection at all; a stray write corrupts a scheduler structure and the symptom appears minutes later, three subsystems away. Every embedded developer has lost days this way (this blog's Thread web-server debugging saga is a mild example of how indirect embedded failures get, and that one was not even a memory bug).
As described in my interactive textbook, Rust's proposition is that whole classes of these defects become compile-time errors. Ownership and borrowing rules make use-after-free and double-free unrepresentable in safe code; the Send/Sync trait system makes cross-thread (and cross-interrupt) data races a type error rather than a lost Tuesday afternoon. Crucially for microcontrollers, all of this is enforced statically, with no runtime, no garbage collector, and binaries that compete with C on size and speed. Where hardware access requires stepping outside the rules, the unsafe keyword marks the deviation (just as the often unsafe C++ reinterpet_cast marks "Here be Dragons"), concentrating review attention on the few dozen lines that need it instead of the whole codebase.
The costs sit alongside: a learning curve that is challenging (the borrow checker forces new habits precisely because it is checking things C never checked), a younger ecosystem than C's fifty-year history, and, as we will see, some specific holes where challenges remain. The story of embedded Rust since about 2018 is the story of those costs shrinking while the benefits hold.
How we got here: a short history
Foundations (2015 to 2019). Rust 1.0 arrived in 2015 with the no_std capability already in its fabric: the language core is separable from its standard library, which is exactly what an environment with no operating system, no heap and no filesystem requires. The community's Embedded Working Group formed in 2018, and its early artefacts still anchor the ecosystem: svd2rust generating type-safe register access crates from vendor hardware descriptions, the cortex-m runtime crates, and above all embedded-hal, a set of traits (SPI, I2C, GPIO, delay) that let a sensor driver be written once against abstractions and run on any chip whose HAL implements them. It is ddevicetree's separation-of-concerns instinct expressed through a type system instead of a build system.
svd2rust is a command line tool that transforms SVD files into crates that expose a type safe API to access the peripherals of the device." From: https://docs.rs/svd2rust/latest/svd2rust/Async comes to bare metal (2020 to 2023). Rust's async/await needs no operating system threads, which makes it a natural fit for microcontrollers, where "wait for the UART byte without burning the CPU" is the fundamental problem. Embassy built an executor and a family of HALs around that insight: tasks are plain async functions, awaiting a pin change or a timer compiles down to interrupt-driven wakeups, and the pattern this blog's Embassy article demonstrates (cooperative tasks by default, pre-emption only where you explicitly place an interrupt-priority executor) replaced a whole tier of RTOS machinery with language features. RTIC matured in parallel as an alternative: a concurrency framework that maps tasks directly onto interrupt priorities with statically-checked resource sharing, important where hard real-time analysis matters.
Legitimacy (2022 to 2025). Three separate institutions then did things. The Linux kernel merged Rust support in 6.1 and let drivers begin arriving. Ferrocene qualified the Rust compiler itself for functional-safety use (ISO 26262 ASIL D, IEC 61508 SIL 3, and later IEC 62304 for medical software), removing the "no qualified toolchain" blocker that had kept Rust out of automotive and medical tenders regardless of its merits. And government security bodies (the NSA, CISA, and their European counterparts) began explicitly recommending memory-safe languages for new systems code. embedded-hal reached 1.0 in early 2024, stabilising the trait contracts the driver ecosystem builds on. Espressif made esp-rs an officially supported SDK for its chips, the first silicon vendor to put Rust on the same footing as its C toolchain.
Mid-2026. The recent months have been dense enough to justify this article's existence. With Linux 7.0 in April, the kernel's Rust experiment was declared over and permanent, with production Rust drivers (NVIDIA's Nova GPU driver most visibly) in mainline. Ferrocene's 26.02.0 release extended qualification beyond the compiler into a certified subset of the core library, which is precisely the layer no_std firmware stands on. CISA's deadline for vendors to publish memory-safety roadmaps arrived in January, and the EU's Cyber Resilience Act is pulling the same direction from my side of the Atlantic. None of this makes Rust mandatory for anyone; all of it changes what "the safe default choice" means in planning meetings.
libcore subset qualification in Ferrocene 26.02.0 is crucial. This was the exact missing link for no_std teams in automotive (ISO 26262) and medical (IEC 62304) who couldn't rely on compiler-only qualification. In Rust, libcore is the foundational, dependency-free core of the language. Unlike the full standard library (std), which assumes the existence of an operating system, file system, and heap allocation, libcore makes absolutely zero assumptions about the hardware or runtime environment. When you write a no_std application for a bare-metal microcontroller, you are stripping away std, but your firmware is still entirely dependent on libcore. It is the layer that provides Rust's fundamental building blocks: primitive types, essential structures like Option and Result, memory operations, and foundational traits. By qualifying a specific subset of libcore natively, Ferrocene removed this final structural barrier. Instead of an engineering team having to defend the safety of the underlying language constructs to an auditor, they can point to the Ferrocene certification.A guide to the stack in mid-2026
The single most clarifying point about embedded Rust is that it is really two ecosystems sharing a language, split along the same line as this blog's own Rust articles.
The no_std tier: microcontrollers
On a bare microcontroller you build without the standard library, and the stack looks like this, bottom up:
- Register access: peripheral access crates (PACs), generated mechanically from vendor SVD files, giving type-checked access to every register bit. You rarely touch these directly, but everything above stands on them.
- HALs: hand-written, ergonomic APIs per chip family. The community
stm32-rs,nrf-haland friends remain, but the centre of gravity has shifted to the Embassy HALs (embassy-stm32covers effectively every STM32;embassy-nrf,embassy-rp, and Espressif's officialesp-hal), which are async-first and, in practice, currently the best-documented route onto most mainstream parts. - Frameworks: The Embassy ecosystem is, by mid-2026, the de facto default for new projects (an assessment the community's own blog shares). Rather than a single monolithic release, it has matured into a stable umbrella of independently versioned crates (
embassy-executor,embassy-time, etc.) that provide the foundation for async-first hardware control. RTIC serves the hard-real-time analytical niche; a plainfn mainwith interrupt handlers remains available. It is worth knowing that Hubris, Oxide Computer's all-Rust microcontroller operating system, exists as proof that even the RTOS layer itself can be rebuilt in Rust, though it is a product component rather than a general-purpose community platform. - Drivers: the
embedded-hal1.0 trait contracts mean a published driver crate for an I2C sensor works across every conforming HAL. Coverage is good for common hobbyist and industrial parts, thinner than C for the long tail; the awesome-embedded-rust list is the census.
no_std Rust applications. It serves as a highly efficient alternative to a traditional RTOS (like FreeRTOS) by utilising the microprocessor's native hardware interrupt controller to manage scheduling. RTIC provides the concurrency and preemptive multitasking required for complex embedded implementations without the memory or processing overhead of an operating system.The tooling deserves discussion, because for developers arriving from C it is the biggest change. There is no SDK installer, no vendor IDE, no gigabyte of toolchain: rustup target add thumbv7em-none-eabihf fetches the cross-compiler as a component, Cargo handles dependencies the way the rest of the software world expects, and probe-rs has, in practice, replaced the OpenOCD-and-GDB scaffolding entirely: one cargo run compiles, flashes through the debug probe, and streams structured logs back over defmt, whose trick of keeping format strings on the host makes logging cheap enough to leave in production builds. My Embassy article walks this exact flow on the Nucleo-F401RE with its on-board ST-LINK.
The std tier: embedded Linux
On a Raspberry Pi or any Linux-class edge device, Rust is simply a first-class systems language with the whole standard library, and the embedded angle is about which crates matter: tokio for async runtime, axum for web services, rppal for GPIO/I2C/SPI on the Pi, serialport and friends for talking to microcontrollers. The result is the class of program you would once have written in Python for convenience or C++ for performance, delivered with both: services that start in milliseconds, run in megabytes, and do not decay over months of uptime. Cross-compilation, historically the misery of embedded Linux work and the subject of many of my YouTube videos, is now a solved problem several times over (the cross tool, or increasingly cargo-zigbuild); this blog's forthcoming Rust on the Pi article makes the Windows-to-Pi workflow its centrepiece.
This tier matters to the AIoT story from the companion survey more than it first appears: the hub tier of an edge fleet (the Pi-class machine aggregating sensors, serving dashboards, brokering model updates) is precisely where Rust's reliability-per-megabyte shines, and precisely the code you want never to fall over.
The interop seam
Between the tiers, and between Rust and the C world, the boundary is workable but not seamless. Calling C from Rust (and vice versa) via bindgen/FFI is routine and is how Rust firmware borrows mature C stacks today. The Zephyr project's official Rust support is under active development, aiming to let Rust application code run on Zephyr's kernel, drivers and networking; it is promising and worth watching, but in mid-2026 it is not yet how you would ship a product.
The gap that remains: wireless
If you ask what still separates embedded Rust from the C ecosystems on capability rather than taste, the answer in mid-2026 is overwhelmingly connectivity.
The C world's main asset is the certified, vendor-maintained wireless stacks. Zephyr ships mature BLE, 802.15.4, Thread (via OpenThread) and increasingly Matter support across hundreds of boards; Nordic's SDK wraps qualified stacks with vendor guarantees. Pure-Rust equivalents are arriving, but unevenly:
- BLE: TrouBLE, the Embassy project's BLE host stack, is the credible contender, running over standard HCI controllers (including a Zephyr-based controller over serial) with qualification stated as a goal. It is usable and improving; it is not yet the drop-in, qualified stack a product team gets from the C vendors. The older route of Rust bindings over Nordic's SoftDevice remains common on nRF52 parts.
- Thread and 802.15.4: the practical pattern is Rust around C: the esp-rs
openthreadcrate that this blog's own Embassy Thread web server builds on wraps the OpenThread C library rather than reimplementing it. That is engineering pragmatism, but it means the Rust project inherits the C build alongside the Rust one. - Matter: rs-matter exists under the CSA's own umbrella, and its progress has been visibly entangled with the BLE story, since BLE commissioning is how Matter devices "just work".
- Wi-Fi: is excellent on ESP32 parts through Espressif's official channels but patchy elsewhere.
The strategic reading: for connected products in 2026, Rust-plus-C-stack hybrids and plain Zephyr both beat pure Rust on time-to-market for anything radio-heavy, and the gap is closing from the Rust side at a pace worth re-checking every six months. For unconnected or wired devices, the gap does not really apply.
Measured: numbers from this desk
Language debates float free of data; here is what this blog has measured on its own boards, C and Rust implementing the same four-task scheduling demo on the same Nucleo-F401RE (full detail in articles one and two of that series):
Embassy's numbers are surprising (an eighth of the RAM), but the comparison is between a framework compiled to exactly what one application uses and a general-purpose RTOS carrying a kernel, a shell and configurability for hundreds of boards; strip Zephyr down and the flash gap narrows substantially. The conclusions are narrower and still valuable: Rust's async model imposes no size penalty for its safety, monomorphised Rust binaries are extremely lean, and on RAM-constrained parts Embassy's statically-allocated task model is a structural advantage.
My same blog series recorded the costs, and they deserve equal attention. Migrating the Embassy demo across framework versions surfaced a string of small breaking API changes (executor feature renames, interrupt-binding signatures, timer tick configuration), each fixed, but collectively a cost that mature C APIs don't charge. The no_std ecosystem versions fast and deprecates fast; pinning dependencies and budgeting for migration is part of the deal in 2026, in a way it largely is not with Zephyr's LTS (Long Term Support) releases. Compile times, too, run longer than C's, though incremental builds and fast linkers have blunted the worst of it.
And a final measured observation from the other tier: nothing in the Pi-class Rust story carries these caveats. std Rust on Linux is a stable, boring, excellent toolchain, and has been for years.
Choosing in mid-2026: a decision path...
Surveys should end in usable shape. For the classes of project this blog concerns itself with:
If a single sentence must summarise mid-2026: Rust is no longer the risky choice anywhere on this table, but it is only the obviously superior choice on some rows. The interesting engineering, as ever, is in knowing which row you are on.
Where this blog focuses:
This survey is the map in mid-2026; the hands-on articles are the walking, current and planned:
- Async Rust on bare metal, from zero: the Embassy scheduler article re-implements the Zephyr demo and captures every measured number and migration described above.
- Rust meets a real radio: the Embassy Thread web server on the XIAO nRF52840 is the wireless-gap section made concrete: pure-Rust application over a wrapped C OpenThread stack, with an earlier, gentler version in the ESP32-C3 Embassy web server.
stdRust at the hub tier: the forthcoming Pi 5 article (axum, rppal, and the Windows-to-Pi cross-compilation workflow) puts Rust in the role this survey argued suits it best, and a RustbluerBLE gateway is pencilled in as the follow-on, which chosebleakfor reader accessibility and deferred the Rust treatment.- The measurement habit: when the five-platform YOLOv8n capstone lands, its harness code on the Linux-class contenders is a further candidate for
stdRust, keeping the benchmarking instrumentation out of the measured path.
Further reading
- The Embedded Rust Book: the canonical
no_stdstarting point. - Embassy and the Embassy book: the async-first framework and HALs.
- RTIC: the real-time interrupt-driven concurrency framework.
- embedded-hal: the 1.0 trait contracts the driver ecosystem stands on.
- probe-rs and defmt: the modern flash-debug-log toolchain.
- Ferrocene and the Rust project's safety-critical retrospective: the qualification story from both ends.
- TrouBLE and rs-matter: the wireless gap, closing in public.
- zephyr-lang-rust: Rust on Zephyr, officially.
- awesome-embedded-rust: the living census of the ecosystem.