I managed to program my ESP32 in Rust Bare Metal (not std) with the latest version of Rust (rustc 1.90.0-nightly (abf50ae2e 2025-09-16) (1.90.0.0))

110 points Safe-Hat373 57 comments

First of all, I'm not an expert, I'm just a 16-year-old kid curious about low-level programming and the ESP32. A while ago I wanted to start learning Rust by programming my ESP32 (which is a really bad idea to start with), but I realized there's very little information on the subject. I started researching and noticed that the available templates work when using the standard std library, but they don't work when you don't. I found that very strange. I realized that the libraries have changed and are all in esp-hall (except for "esp-bootloader-esp-idf"; a description of your program is required to compile it like this: "esp_bootloader_esp_idf::esp_app_desc!(); // that's for the default"). Besides that, when it finally compiled, I had problems with my program's output. It seems the serial port monitor was out of sync, so I used this command: "cargo espflash flash --release --monitor --baud 115200"

I'm not an expert, but this is my solution, and if it can help someone else, that would be great. I'm leaving you the source code and a link to a zip file with my project folder so you can use it as a template because I know my explanation won't be enough.

I forgot to mention, I use a Debian machine, VS Code, and my ESP32 is the ESP32 devkitv1.

Also, my native language is Spanish, so please understand if there are any mistakes; everything was translated.

////////////////////source code

use esp_backtrace as _;

use esp_hal::delay::Delay;

use esp_hal::main;

use esp_hal::time::Duration;

// Ahora sí, llamando al crate que acabamos de añadir

esp_bootloader_esp_idf::esp_app_desc!();

#[main]

fn main() -> ! {

// Esto configurará los relojes internos automáticamente

let _peripherals = esp_hal::init(esp_hal::Config::default());

let delay = Delay::new();

esp_println::logger::init_logger_from_env();

loop {

// Usa println! primero para probar, es más directo que log::info

esp_println::println!("¡Hola Mundo desde Rust!");

delay.delay(Duration::from_millis(1000));

}

}

///////////////////////////////////////

link to my proyect file (mediafire) : https://www.mediafire.com/file/6nkjaqn9j6ba35t/proyecto.zip/file