Rust en ESP32

Catálogo de opciones para programar un ESP32 en Rust. Es una alternativa a ESP-IDF en C con buen tooling oficial de Espressif.

Fuentes oficiales

Toolchain - Xtensa vs RISC-V

ChipToolchainPor qué
Xtensa: ESP32 clásico, S2, S3, ESP8266Rust fork de Espressif (esp-rs/rust) con LLVM fork para XtensaEl backend Xtensa no está aún en LLVM upstream; necesita la versión patcheada de Espressif
RISC-V: C2, C3, C5, C6, H2, P4Rust upstream estableRISC-V32 es un target soportado por Rust

Instalación con espup

espup es el gestor oficial , instala el toolchain Xtensa, GCC para linking y herramientas auxiliares (espflash, cargo-espflash):

Después de eso, cargo build --target xtensa-esp32s3-espidf funciona normal.

Para chips RISC-V puro (sin Xtensa), no se necesita espup - basta con rustup target add riscv32imac-unknown-none-elf.


Dos caminos principales: std vs no_std

Esta es la decisión más importante al arrancar.

std con esp-idf-svc (recomendado para empezar)

Rust sobre ESP-IDF + FreeRTOS mediante bindings.

  • Stack: ESP-IDF runtime de fondo + Rust como capa de aplicación
  • Crates clave: esp-idf-svc (bindings a APIs ESP-IDF) + esp-idf-hal (HAL para GPIO/I2C/SPI/etc desde Rust)
  • Ventajas:
    • Acceso a todo el ecosistema ESP-IDF (WiFi, BLE, MQTT, HTTP, mDNS, NVS, OTA)
    • Funcionalidad familiar de Rust std (std::thread, Mutex, String, etc.) - corre sobre FreeRTOS
    • Si querés saber cómo hacer X, buscás en docs ESP-IDF el nombre de función y lo copiás-pegás en el searchable crate doc de esp-idf-svc - las signatures coinciden casi 1:1
  • Trade-off: binario más grande (incluye runtime de ESP-IDF), más overhead que no_std

no_std con esp-hal

Bare metal Rust, sin FreeRTOS ni ESP-IDF de por medio.

  • Stack: Rust directo sobre el SoC
  • Crates clave: esp-hal (HAL nativo Rust) + esp-wifi si necesitás WiFi/BLE
  • Ventajas:
    • Binario chico, menor consumo, control total
    • Idiomático Rust (sin macros de bindgen, sin unsafe por todos lados)
    • Mejor experiencia de embedded Rust en general
  • Trade-off: menos batería incluida - features avanzadas (MQTT, OTA) requieren más trabajo manual

Cuándo elegir cada uno

NecesidadElección
Conocés Rust pero no embebido y querés algo que ande rápidostd + esp-idf-svc
Necesitás WiFi + MQTT + OTA y todo el stack IoT estándarstd + esp-idf-svc (más fácil)
Querés async/await embedded, máximo control, footprint mínimono_std + esp-hal + Embassy
Producto que va a batería con consumo críticono_std + esp-hal + Embassy

Embassy - async runtime para no_std

Embassy es un framework de Rust async para embedded. Habilita async/await sobre bare metal sin OS de por medio.

  • No es no_std/std agnostic: Embassy es estrictamente no_std
  • HAL para ESP: Embassy no mantiene HAL propio para Espressif - usa esp-hal que está siendo desarrollado dentro del proyecto esp-rs con integración nativa con el runtime async de Embassy
  • Provee:
    • Async runtime (embassy-executor)
    • HALs async (embassy-time, embassy-net, etc.)
    • Stack de red async, USB, BLE
    • Bootloader
  • Status en ESP32: “Embassy HAL support for Espressif chips, as well as Async Wi-Fi, Bluetooth, and ESP-NOW, is being developed” (cita textual del README de Embassy en 2025)

Caso típico: nodo IoT con WiFi async donde varios tasks (lectura de sensores, publicación MQTT, OTA check) corren concurrentemente sin un OS.


Tooling

HerramientaPara qué
espupInstalar/actualizar toolchain Xtensa, GCC linkers
espflashFlashear el chip - reemplazo de esptool.py
cargo-espflashcargo run que automáticamente flashea + abre monitor serie
cargo-generate + templates esp-rsGenerar proyecto skeleton (std o no_std)
probe-rsDebug JTAG, alternativa más Rust-friendly a OpenOCD

Dev environment

Setup estándar (cualquier OS)

  1. cargo install espup espflash cargo-espflash cargo-generate
  2. espup install
  3. . ~/export-esp.sh
  4. Generar proyecto: cargo generate esp-rs/esp-template (interactivo, elegís chip + std/no_std)
  5. cargo run ya flashea + abre monitor

Setup con Nix (sandboxed)

esp-rust-nix-sandbox - shell Nix que aísla los binarios pre-built (compiladores Rust y GCC de Espressif) en Bubblewrap sandbox con acceso restringido al filesystem. Razón: los binarios pre-built de Espressif son untrusted; este setup permite usarlos sin darles permisos sobre todo el sistema.

  • Soporta tanto Xtensa como RISC-V
  • Mantiene Cargo, rustfmt, espflash construidos desde source (fuera del sandbox)
  • Útil si querés un dev environment reproducible (Nix flake) o si te preocupa el supply chain de los blobs pre-built

Notas prácticas (del wisdom acumulado en la comunidad)

Esta sección agrega consejos de r/rust sobre ESP32 - no son spec oficial pero son lecciones que ahorran tiempo.

  • Si ya conocés Rust, arrancá con std (esp-idf-svc). El stack es más pesado pero la barrera de entrada es mínima.
  • No todo está en esp-idf-svc. Para cosas básicas como encender un LED necesitás también esp-idf-hal en Cargo.toml. Ambos crates conviven en el mismo proyecto sin conflicto.
  • Windows + path largos: generar templates en C:\ (no en C:\Users\<usuario>\Documents\...). Cargo + Windows tienen el problema histórico de “long file path” que rompe builds.
  • Empezar simple: los ejemplos del Rust on ESP Book son completos pero a veces over-engineered. Hacer blink leer GPIO leer I2C antes de meterse en WiFi+TLS.
  • Mapping ESP-IDF C esp-idf-svc Rust: las signatures son casi 1:1. Buscá la función que querés en docs.espressif.com ESP-IDF, copiá el nombre, buscá la misma en docs.esp-rs.org/esp-idf-svc.
  • FreeRTOS + Rust: el runtime FreeRTOS de fondo en el modo std hace que std::thread, Mutex, Arc y compañía funcionen igual que en un Linux común. Sorprende lo bien que anda.

Recursos de la comunidad

  • The Embedded Rustacean - blog/newsletter especializado en Rust embebido con foco fuerte en ESP32. Mantenido por Omar Hiari (su contenido es leído por ingenieros de Espressif según la propia página). Útil para complementar las docs oficiales con tutoriales paso a paso.
    • Newsletter bi-mensual con novedades del ecosistema embedded Rust
    • Libros propios: Simplified Embedded Rust: ESP Standard Library Edition (cubre std + esp-idf-svc) y ESP Core Library Edition (cubre no_std + esp-hal)
    • Posts cortos comparando patrones de async (Embassy), drivers de sensores, integración con probe-rs, etc.

DevKit Rust dedicado

Hay un DevKit específicamente armado para Rust con sensores onboard: ESP32-C3-DevKit-RUST-1. Incluye SHTC3 e IMU integrados - útil para no cablear nada al hacer los primeros experimentos en Rust.

Cualquier otro DevKit (ESP32-S3-DevKitC-1, ESP32-C3-DevKitC-02, etc.) sirve igual - el “RUST” en el nombre del primero es marketing, no requisito.