Embedded Rust
Rust on bare metal — Embassy, RTIC, esp-rs, embedded-hal, probe-rs, defmt.
Rust on microcontrollers crossed the "production-grade" line in 2024–25 and is the fastest-growing serious-firmware option in 2026. Memory safety without an MMU, async without an RTOS heap, and a debug experience that's better than what most C toolchains offer. For Rust-in-the-browser see WebAssembly; for the chip families see MCU Platforms.
The two main async / scheduling stories
- ★ Embassy — async-Rust executor for embedded; cooperative scheduling without an RTOS. Crates:
embassy-executor,embassy-time,embassy-net,embassy-usb, plus chip-specific HALs (embassy-stm32,embassy-nrf,embassy-rp,esp-halworks alongside). Apache/MIT. Embassy 1.0 shipped late 2025, with stabilized executor API,embassy-timetraits, andembassy-netIPv6. The default for new embedded Rust projects in 2026. - ★ RTIC (Real-Time Interrupt-driven Concurrency) — preemptive, statically-analyzed concurrency model; uses interrupt priorities as scheduler. Apache/MIT. Predictable real-time properties; preferred for hard-real-time work where Embassy's cooperative model isn't enough.
HALs (hardware abstraction layers)
The trait crates and per-chip implementations.
- ★ embedded-hal 1.0 — the trait crate everything implements. Stable since 2024. Async traits (
embedded-hal-async) are the modern path. - embedded-hal-async — async versions of the I2C / SPI / Serial traits.
- embedded-io / embedded-io-async — generic I/O traits (replaces
embedded_hal::serial::*). - stm32-rs HALs (
stm32f4xx-hal,stm32g4xx-hal,stm32h7xx-hal, etc.) — per-family HALs over PAC crates. - embassy-stm32 — Embassy's own STM32 HAL; covers most STM32 families with a unified API. Often the better pick than the per-family HALs.
- embassy-nrf — Nordic nRF52 / nRF53 HAL.
- embassy-rp — Raspberry Pi RP2040 / RP2350 HAL.
- ★ esp-hal — Espressif's official Rust HAL (covers ESP32 / S2 / S3 / C2 / C3 / C6 / H2 / P4). Apache/MIT. Embassy-compatible. Primary surface area of esp-rs.
- rp2040-hal / rp235x-hal — non-Embassy Pi HALs; use these with the official
rp2040-halecosystem if you don't want Embassy. - atsamd-hal — SAMD21 / SAMD51 HAL.
esp-rs — Espressif's official Rust effort
Espressif funds a dedicated Rust team. Tooling is excellent.
- ★ esp-hal — bare-metal HAL (no RTOS). Use this with Embassy.
- esp-idf-hal / esp-idf-svc / esp-idf-sys — Rust bindings on top of ESP-IDF (FreeRTOS underneath). Use this when you need IDF features (Wi-Fi/BLE driver, Matter stack, OTA framework) and want Rust as the application layer.
- espup — Rust toolchain installer; bootstraps the Xtensa fork of rustc and the standard RISC-V toolchain.
- esp-generate —
cargo generatetemplate for esp-rs projects (replaces olderesp-template). - espflash — Rust flasher / bootloader writer; replaces
esptool.pyfor Rust workflows. Fullcargo runintegration. Apache/MIT. - probe-rs run — alternative
cargo runrunner using JTAG instead of UART; works on chips with built-in USB JTAG (S3, C3, C6, P4 all qualify). - esp-wifi — Wi-Fi / BLE / ESP-NOW stack for
esp-hal(i.e., bare-metal, no IDF). 2026 makes this the more popular path.
Debugging & logging
- ★ probe-rs — Rust-native replacement for OpenOCD + GDB. Implements ARM CMSIS-DAP, J-Link, ST-Link, ESP USB JTAG.
probe-rs runflashes and streams logs in one command. The default debug runner for embedded Rust. MIT/Apache. - ★
defmt— deferred / efficient embedded logging from Ferrous Systems. Sends pre-formatted indices over RTT; host-sidedefmt-printreconstructs strings. ~10× smaller code thanprintln!-style logs. defmt-rtt— RTT (Real-Time Transfer) transport for defmt; pairs with probe-rs for live log streams.panic-probe/panic-rtt-target/panic-halt— panic handlers that print a backtrace over RTT or halt cleanly.- probe-rs VS Code extension — debug UI for VS Code over probe-rs; stable in 2026.
- knurling-rs — Ferrous Systems' embedded toolset (defmt, flip-link, app-template, knurling-quickstart).
- flip-link — linker wrapper that puts the stack at the bottom of RAM so overflows fault instead of corrupting state. Cheap insurance.
- rtt-target — alternate RTT-on-the-target crate; pairs with
JLinkRTTViewerif you'd rather use Segger's toolchain.
Networking / wireless
- ★ embassy-net — async TCP/IP/UDP stack on top of
smoltcp; works over Wi-Fi (esp-wifi), Ethernet, USB CDC-NCM, PPP. The standard Rust embedded TCP/IP stack. - smoltcp — the lower-level pure-Rust TCP/IP stack (Embassy net is a thin async wrapper).
- trouble — pure-Rust BLE host stack (no_std, async); works on nRF, ESP32, RP-Pico-W. Replaces / supplements
nrf-softdeviceand is portable across chips. - nrf-softdevice — Rust bindings for Nordic's binary BLE stack (SoftDevice). Mature, less portable than
trouble. - embassy-usb — async USB device stack (HID, CDC, MIDI, MSC, Audio).
Static / domain-specific niceties
heapless— fixed-capacity stack-allocated collections (Vec,String,Pool,mpmc). Standard.fixed— fixed-point arithmetic for FPU-less MCUs.static_cell— declare statics holding non-constvalues (singletons) cleanly.critical-section— pluggable critical sections; lets HALs and apps coexist regardless of the underlying chip.portable-atomic— atomic ops on chips that lack native CAS (Cortex-M0+, RP2040).panic-persist— keep last panic message in a special RAM region across reboots.
On-target test
- ★
embedded-test—defmt-aware on-device test framework; runs#[test]functions on the chip via probe-rs. Replaces ad-hoc test setups. probe-rs runintegration tests — host-side integration tests that flash, run, and assert on RTT output.- See Wokwi & Embedded Simulators for sim-side options.
Books / tutorials worth knowing exist
- The Embedded Rust Book — official entrypoint.
- Embedded Rust on Espressif (esp-rs/no-std-training) — Espressif's own training repo; Embassy-on-ESP from scratch.
- The Embedonomicon — interrupt handlers, linker scripts, panic handling.
- 101: Hands-on Embassy — Ferrous Systems training material; some open.
- The Discovery Book — STM32F3 Discovery walkthrough; aging but still good for fundamentals.
Pick this if…
- Default async embedded Rust: Embassy (1.0+).
- Hard real-time, predictable IRQ priorities: RTIC.
- ESP32 with Rust, modern: esp-hal + Embassy + esp-wifi.
- ESP32 with Rust, need IDF features (Matter, Wi-Fi mesh, etc.): esp-idf-hal/svc on top of IDF.
- Default flashing & debug runner: probe-rs + defmt +
flip-link. - BLE in Rust, multi-chip:
trouble. - You miss
println!: usedefmt::info!instead — same ergonomics, 10× smaller binary. - You want C/C++ instead: see ESP-IDF, Arduino & PlatformIO, or Embedded RTOSes.