Rust on Espressif chips - 04-04-2022

This is the next quarterly update of esp-rs effort, detailing the progress over Q1 2022.

Standard library

Build system changes

The last post mentioned we were moving towards using the built-in esp-idf build system to compile esp-idf (dubbed "native" build) instead of PlatformIO. I'm happy to announce we have completed this step, going forward the native approach is the default, and platformIO is opt-in via the pio feature of esp-idf-sys.

New default version

The default esp-idf version we target in the Rust world was v4.3 (note that this can be configured on a per-project basis), we have now bumped this to now default to v4.4. Version 4.4 has some quality of life fixes, as well as some features.

  • Atomic Emulation up to 64 bits for espidf targets - esp-rs/rust#107.
  • A realpath implementation to get usable panic messages for espidf targets.
  • Toolchain update to support developing on Windows - espressif/esp-idf#7864.

Compiler & Xtensa code generation

Rust has been a good stress test for the Xtensa LLVM backend. We've spotted a few bugs over the last quarter which are important to squash as eventually esp-idf will be compiled with clang instead of GCC (Hopefully by that time, clang will be available as a rustup component). We have also fixed a few issues with our standard library port.

  • LLVM compilation error when optimizing loops for the hardware loop assistance registers of the esp32 - esp-rs/rust#95.
  • LLVM atomic swap code generation broken on Xtensa targets for atomics smaller than 32 bits - esp-rs/rust#106.
  • Add implementations for lstat & ftruncate in esp-idf - esp-rs/rust#100.
  • Fix the size of certain c types for espidf targets such that stat works correctly - esp-rs/rust#92.

Bare metal

Goodbye esp-rs/esp32-hal, hello esp-rs/esp-hal

The new esp-hal is coming along very well, it already has support for GPIO, TIMG, UART, I2C, SPI, and RNG for esp32, esp32s2, esp32s3, and esp32c3. Please see this tracking issue to see the chip support status. This multi-chip HAL is now using the official SVDs from Espressif instead of the hacked together SVD used in the original esp32 peripheral access crate (PAC), see the esp-rs/esp-pacs repository. We've added a quick start template repository esp-rs/esp-template to get started with the new bare metal HAL.

The original HAL for the esp32 is now in maintenance mode, and will soon be deprecated once all drivers are ported to the new multi-chip HAL. There is still a number of drivers to be ported to the new HAL. Porting them would be a good first issue for anyone interested as the implementation would mostly stay the same, just a few API & type changes. Please see this issue if you want to help out.

Preliminary WiFi support

This is something I'm personally very excited about. We've had WiFi support for the standard library (espidf) targets for a long while now, but just recently we've managed to get WiFi going in pure Rust1! It's possible to scan for Access Points (APs) and connect to an AP, and use smoltcp to talk over the network! Check out the dhcp example. The repository is currently in a proof of concept state and can be found here. It will be moved into the esp-rs org once we clean it up and add xtensa support.

Tooling

espflash

Since the last post we have released 1.3.0 and the 1.4.0 release is due to be published very soon which boasts some great features and fixes.

  • Better partition table support. We now properly handle partitions other than factory (OTA, etc).
  • USB Serial JTAG support. It's now possible to flash over the serial part of onboard the USB Serial JTAG peripheral.
  • The ability to modify firmware header via the command line. Configure custom flash sizes, flash speeds, and flash modes.
  • Use espmonitor as the --monitor inside espflash. espmonitor can decode addresses to source functions, providing a stack trace on abort over the serial port.

Github actions

Want to test your Xtensa based projects in CI? We recently released xtensa-toolchain, a Github action for installing our forked Rust compiler with Xtensa support. Instructions on how to use can be found here.

esp-rs devcontainer for Visual Studio Code

To target Xtensa based chips (esp32, esp32s2, esp32s3, etc) we need a custom rust compiler, with a custom LLVM backend for Xtensa. This adds some friction to getting started with Xtensa based chips. We already offer scripts to download pre-built compiler toolchains, but we are happy to announce esp-rs-devcontainer. This integrates into Visual Studio Code using the remote containers feature, allowing easy setup for developers already familiar with containers. Please see the setup section for supported configurations and initialization steps.

Community

The ESP Rust Board

We've developed an open source development board with a focus on being ready for Rust development! It's based on the RISCV esp32c3, so a standard Rust compiler will work. Whilst the boards are not yet on sale, the source files are available here if you want to build one yourself.

Ferrous training

We have collaborated with Ferrous Systems to produce a training workshop to help teach developers how to get productive with Rust on Espressif chips! Please see the newsletter release for the full details.

What's next?

Continue the rapid progress on the bare metal multi-chip HAL, esp-hal and add bare metal WiFi support for Xtensa chips. The esp-idf series of crates are starting to stabilize however, there are still plenty of drivers and libraries not yet covered by nice Rust abstractions, so lots still to do here!




1

The WiFi binary blobs are not written in Rust