How to Create, Build, Flash, and Simulate a “Hello World” Rust Bare Metal Application for ESP32-S3

Rust is a great programming language when developing for embedded devices like MCUs, which have limited resources. Especially, Bare Metal (a.k.a. no_std) brings many advantages and allows for the creation of whole applications purely in Rust.

The following steps describe how to create, build, flash, and simulate an application for ESP32-S3, which is included in many DevKits like the ESP32-S3-BOX-3 or M5Stack CoreS3.

There are several tools that need to be installed.

First of all, we need to install Rust itself. We will use rustup.

WindowsmacOS, Linux
Invoke-WebRequest -Uri https://win.rustup.rs/x86_64 -OutFile rustup-init.exe; Start-Process -FilePath .\rustup-init.exe -NoNewWindow -Wait
curl –proto ‘=https’ –tlsv1.2 -sSf https://sh.rustup.rs | sh

We will need several additional tools. We can use cargo install to perform the installation from the source code. The faster method is to use cargo-binstall which deploys binaries of tools, saving time compared to installation from the source code.

curl -L --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/cargo-bins/cargo-binstall/main/install-from-binstall-release.sh | bash

Now we can install additional tools:

  • espup – Tool for installing and maintaining Espressif Rust ecosystem.
  • cargo-generate – Tool for creating Rust projects from template.
  • espflash – Serial flasher utility for Espressif SoCs and modules. Rust replacement for Python based esptool.py
cargo binstall espup cargo-generate espflash

Since we’re targeting ESP32-S3, which is based on the Xtensa architecture, we will need the Rust Xtensa toolchain, which needs to be installed separately. Note: For chips introduced after ESP32-S3, like ESP32-C3, which are based on the RISC-V architecture, this dependency is not needed.

espup install
source ~/export-esp.sh

Now we can generate a project using the Bare Metal template from esp-rs/esp-template using cargo-generate. The tool will ask several questions. Here’s the recommended setup:

cargo generate esp-rs/esp-template
   Project Name: embedded-rust
   Destination: /home/georgik/projects/embedded-rust ...
   project-name: embedded-rust ...
   Generating template ...
✔    Which MCU to target? · esp32s3
✔    Configure advanced template options? · true
✔    Enable allocations via the esp-alloc crate? · true
✔    Enable WiFi/Bluetooth/ESP-NOW via the esp-wifi crate? · false
✔    Configure project to use Dev Containers (VS Code and GitHub Codespaces)? · true
✔    Configure project to support Wokwi simulation with Wokwi VS Code extension? · true
✔    Add CI files for GitHub Action? · true
✔    The template is requesting to run the following command. Do you agree?
cargo fmt · yes
   Moving generated files into: `/home/georgik/projects/embedded-rust`...
   Initializing a fresh Git repository
✨   Done! New project created /home/georgik/projects/embedded-rust

The project embedded-rust should be created, and now we’re ready to build and flash.

It’s recommended to build the project in the Release profile, due to performance considerations, especially if you plan to use WiFi, which requires a lot of resources, and the debug profile is too slow.

Connect the ESP32-S3-BOX-3 to your computer using a USB cable and type the following command, which will invoke a build and espflash command with the monitor option to flash and monitor the hardware.

cd embedded-rust
cargo run --release

If you do not have the ESP32-S3-BOX-3 with you, it’s possible to use the Wokwi Simulator. Open VS Code:

code .

Install the Wokwi VS Code Extension (Ctrl+Shift+P), select Install extension, search for Wokwi, and click install.

Activate the free Wokwi license (Ctrl+Shift+P), select Wokwi: Request a new license, and follow the activation process in the web browser.

If the project was created in the Release profile, we need to change the path to the binary in the wokwi.toml file:

[wokwi]
version = 1
elf = "target/xtensa-esp32s3-none-elf/release/embedded-rust"
firmware = "target/xtensa-esp32s3-none-elf/release/embedded-rust"

Run the simulation (Ctrl+Shift+P), select Wokwi: Start Simulator.

The simulated chip should appear, and you should get the following result:

ESP-ROM:esp32s3-20210327
Build:Mar 27 2021
rst:0x1 (POWERON),boot:0x8 (SPI_FAST_FLASH_BOOT)
SPIWP:0xee
mode:DIO, clock div:1
load:0x3fce3808,len:0x370
load:0x403c9700,len:0x900
load:0x403cc700,len:0x2364
entry 0x403c98ac
INFO - Hello world!

Congratulations! You’ve completed your first Rust Bare Metal project for ESP32-S3-BOX-3.

Productivity tip: You can keep the Wokwi window with the simulator open while developing the application. Once you build the app using cargo run –release, the simulator will pick up the change and show you the simulation, even while you’re waiting for the flashing procedure to complete. This can greatly save time by allowing you to see the results of a code change immediately.