Using Rust on ESP32

This document aims to guide the readers in understanding Rust and how it can be utilized on ESP32 (Espressif Systems). After reading this article, the reader should have a clear understanding of how Rust is used in an embedded system like ESP32.

Table of Contents

  1. Introduction
  2. Pre-requisites
  3. Installing Rust
  4. Setting Up the Toolchain for ESP32
  5. Writing Your First Rust Application on ESP32
  6. Debugging your Rust Application on ESP32
  7. Common Issues and Solutions
  8. References

Introduction

Rust is a powerful system programming language with memory safety featuring zero-cost abstraction. It's increasingly popular for system level programming and has recently gained attention for embedded system development. One such application is in the programming of ESP32 System on Chip (SoC).

ESP32 is a Wi-Fi & Bluetooth microchip and has an excellent performance in power consumption, RF performance, robustness, versatility, and reliability. It also supports a wide variety of peripherals. Rust brings robustness and safety to ESP32 development, making it much easier to develop reliable code.

Pre-requisites

Before we proceed, ensure you have the following:

  1. A computer running on Linux, MacOS, or Windows.
  2. ESP32 Development board.
  3. Familiarity with the basics of Rust programming and fundamentals of embedded systems.

Installing Rust

To install Rust, you can use rustup, the recommended way to install the Rust programming language. Open a terminal and enter the following commands:

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

After installation, add Rust to your system PATH by running:

source $HOME/.cargo/env

You can verify your installation by running the following command:

rustc --version

Setting Up the Toolchain for ESP32

For programming ESP32 using Rust, you need to set up a suitable Rust toolchain. Here are the steps:

  1. Add the appropriate target by running the command:
rustup target add xtensa-esp32-none-elf
  1. Install cargo, a Rust package manager, for cross-compiling:
cargo install cargo-xbuild

Writing Your First Rust Application on ESP32

After the toolchain setup, let's write a simple Rust "Hello, World!" application for ESP32:

  1. Create a new program with cargo:
cargo init hello_world
  1. Replace the content of your main.rs with:
#![no_std]
#![no_main]

use core::panic::PanicInfo;

#[no_mangle]
pub extern "C" fn app_main() {
    println!("Hello, world!");
}

#[panic_handler]
fn handle_panic(_info: &PanicInfo) -> ! {
    loop {}
}
  1. Build and flash it to your ESP32:
cargo xbuild --target xtensa-esp32-none-elf

Debugging your Rust Application on ESP32

Debugging will require a GDB server running on your computer. In your terminal, open the GDB server as follows:

openocd -f interface/ftdi/esp32_devkitj_v1.cfg -f board/esp-wroom-32.cfg

In another terminal, connect to your GDB server:

xtensa-esp32-elf-gdb target/xtensa-esp32-none-elf/debug/hello_world

Latest Status of Rust on Espressif Chips - Q4 2023 Update

Introduction

The last quarter of 2023 has brought significant developments in the integration of Rust with Espressif chips. This update covers the major milestones achieved in this period.

Rust Compiler Upstream Improvements

RISC-V Target Enhancements

Rust's support for RISC-V targets, which includes popular Espressif chips like ESP32C3 and ESP32C2, has seen considerable improvements. The most notable change is the enablement of atomic load/store code generation for non-atomic RISC-V targets. This enhancement, initially a major bottleneck, is currently in the nightly release and is expected to be stabilized in Rust 1.76.

  • RISC-V (pronounced "risk-five") is an open standard instruction set architecture (ISA) based on established reduced instruction set computing (RISC) principles.
  • Unlike most other ISAs, RISC-V is open and freely available for anyone to use, which has led to its increasing adoption in a wide range of processors, including those used in embedded systems like the Espressif chips.

New RISC-V Target

The riscv32imafc-unknown-none-elf target has been introduced, primarily for the ESP32P4, Espressif's first chip without a rajio component.

Promotion to Tier 2

Existing bare metal RISC-V targets have been elevated to tier 2, indicating improved support and stability.

New ESPIDF Target

The riscv32imafc-esp-espidf target for ESP32P4 marks another significant addition, enhancing Rust's compatibility with Espressif's newer models.

Xtensa LLVM Backend Updates

While there have been advancements in the Xtensa LLVM backend (now based on LLVM 17), no significant upstream progress is reported for this quarter.

esp-hal - no_std

The v0.13, v0.14, and v0.15 releases of esp-hal introduced several new features:

  • Asynchronous drivers for PARL_IO, I2S, and RMT.
  • Update to embedded-hal v1.0.
  • Unified low-power support API and ULP core support for ESP32S2 & ESP32S3.
  • Implementation of flip-link for ESP32C6 and ESP32H2, offering zero-cost stack overflow detection.

Breaking Change in esp-hal

The discontinuation of atomic emulation support, as Rust now handles atomic operations on non-atomic targets natively.

esp-wifi - no_std

  • Addition of BLE support for ESP32H2.
  • Improved coexistence support for ESP32.
  • Introduction of a WiFi throughput benchmark example.
  • Official release of esp-wifi on crates.io, after extensive refinement and documentation.

Conclusion

The Q4 2023 update underscores Rust's growing integration and compatibility with Espressif chips. These enhancements not only streamline development but also open new possibilities for leveraging Rust's efficiency and safety in embedded systems.

Common issues and Solutions

  • Issue: Unable to compile due to 'linking with cc failed'.

    • Solution: Install the latest C compiler on your system.
  • Issue: 'Error: no device found' during flashing.

    • Solution: Check your ESP32 board connection and drivers.

References

  1. The Rust Programming Language Book
  2. ESP32 Specifications and Documentation
  3. Rust Embedded Working Group
  4. Rustup Documentation