Embedded sensor application with Rust on ESP32

Embedded sensor application with Rust on ESP32

There is a growing adoption of Rust across various domains. One interesting field is development of embedded systems. Rusts provides memory safety and high-level concepts with uncompromised machine level performance.

But how mature is the Rust ecosystem for embedded systems?

We build an embedded sensor IoT-device using Rust and the ESP32 micro controller from Espressif Systems.

Application

The ESP32 is used to read from an infra-red sensor to detect motion. The sensor state is shared using WiFi and a HTTP server hosted on the ESP32. To utilize network and multithreading functionality, the Rust standard library is used.

Additionally, an LCD display is used to provide direct access to sensor information. Communication between the ESP32 and the display is implemented by a dedicated device driver.

The whole software application is written in Rust.

Hardware

  • ESP32-C3
  • Passive infra-red sensor HW-416
  • 1.9-inch ST7789 LCD Display (I8080 interface)

Toolchain

Espressif Systems provides pre-configured toolchains for Rust development on ESP32:

  • Compilation
  • Flashing
  • Monitoring
  • BSP for ESP32 SoC
  • Pre-defined crates with bindings to the hardware

Practical experience

We were able to use the Rust tools provided by Espressif without major problems. Documentation is available and up to date.

Setting up a project with access to the Rust standard library is straightforward, with well-documented tooling for compilation, flashing, and monitoring.

Not all hardware is supported, but it was possible to create a dedicated driver for the display. (This would be the same for C or C++).

At least for this platform, professional and commercial use of Rust is a serious option.

Technical Details

Core vs Standard Library

There are two options to use Rust on an ESP32. The first option is using the core library (no std), resulting in bare metal development. The core library is a subset of the standard library that does not depend on the existence of an operating system. This approach results in a small memory footprint and direct hardware control (see https://docs.esp-rs.org/book/overview/using-the-core-library.html).

The second option is using the standard (std) library. This approach provides rich functionality and therefore rapid development (see https://docs.esp-rs.org/book/overview/using-the-standard-library.html). Rust std library is utilizing the C-based development framework called ESP-IDF, developed by Espressif Systems. ESP-IDF is based on FreeRTOS and supports different SoCs. To expose ESP-IDF to Rust the following crates are used:

  • esp-idf-sys: sys crate to provide the unsafe bindings
  • esp-idf-svc: higher-level crate offering safe and comfortable Rust abstraction
  • esp-idf-hal: low-level independent hardware access

For more information regarding the difference between core and std see https://docs.rust-embedded.org/book/intro/no-std.html#a-no_std-rust-environment.

Setup ESP32 toolchain for std development

Install Rust: https://www.rust-lang.org/tools/install

Install prerequisites for ESP-IDF: https://docs.espressif.com/projects/esp-idf/en/v5.2.1/esp32/get-started/linux-macos-setup.html#step-1-install-prerequisites

Install cargo commands: https://github.com/esp-rs/esp-idf-template#prerequisites

Generate ESP32 std project from template

Run the following command to create a buildable std project with all the correct configurations.

cargo generate esp-rs/esp-idf-template cargo

Use “cargo build” to compile the project using the appropriate toolchain and target. Running “cargo run” will compile the project, flash it, and open a serial monitor with our target device.

For more information regarding the project template see https://docs.esp-rs.org/book/writing-your-own-application/generate-project/esp-idf-template.html.

Resources

List of resources regarding Rust on ESP32: https://github.com/esp-rs/awesome-esp-rust

Rust on ESP Book: https://docs.esp-rs.org/book/introduction.html

Supported SoCs: https://github.com/espressif/esp-idf?tab=readme-ov-file#esp-idf-release-and-soc-compatibility