Rust on Espressif chips - 10-01-2022

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

Documentation

Feedback we have received over the last quarter has primarily been about documentation, or lack there of. We've been working hard on this, making multiple contributions to the book ourselves, as well as some community contributions too. We're also working on documentation for the esp-idf-* based crates required for using the standard library; because the build process currently requires an internet connection to download esp-idf sources it's not possible to host the docs on docs.rs. I've recently opened a PR to self host the documentation until we can figure out a vendoring solution.

Standard library

Bug fixes and incremental improvements to the standard library port have been rolling in. We have also been working on a new build approach, dubbed the "native" build. To explain why we are trying to switch the native build, I'll explain how it currently works. The embuild project manages the download of sources, tools and patches before generating bindings and compiling the esp-idf project ready for use with Rust. The build step initially started using platformIO (PIO) to build esp-idf, which worked great, there are a few caveats to this approach. PIO lags behind in chip support, for example with the new native approach the esp32s3 is now supported, however PIO does not yet support this. The new native approach uses esp-idf's native cmake build system, specifically the cmake file APIs to interact and build esp-idf ready for use in Rust. This has the added advantage that we have control of both sides of the build process and can consider changes in esp-idf to make using it with Rust easier.

One common question we receive is regarding the esp8266 and why there is no standard library support (please note that there is decent support for the esp8266 with bare metal Rust (no_std)). Unfortunately esp-idf does not support the esp8266, and instead is supported a different project. It is very possible to run the standard library on the esp8266, but will require some work implementing support like we did for esp-idf. It may be easier to add support for the esp8266 to esp-idf but we don't have any plans of doing any of this at the moment.

Bare metal

The bare metal story has been a little quiet over the last quarter, with the main focus on the standard library effort & tooling. However, @jessebraham has started work on esp-hal which is set to be a combined bare metal HAL for Espressif chips! It's in very early stages but already has a GPIO driver for the esp32 & esp32c3. Contributions are most welcome!

Atomic story for the esp32c3 (no_std)

In the last post I mentioned we were working on an atomic trap handler to emulate atomics for the esp32c3 for bare metal projects. We have now released it under our Github organization and it's very simple to use, simply include this line in your application:

use riscv_atomic_emulation_trap as _;

It integrates seamlessly with the riscv_rt crate, meaning any other exceptions, or instructions that can't be emulated are pushed to the riscv_rt exception handler. Last but by no means least, this will work for any RISC-V chip without atomic support1! Not just Espressif chips.

probe-rs

probe-rs support for the esp32c3 is relatively complete now. Most excitingly @Yatekii wrote a driver for the on die USB JTAG peripheral inside the esp32c3! Meaning it's possible to flash and debug a esp32c3 (and upcoming chips...) with just a USB cable! Best part is that all our fixes and changes have made it into the v0.14 release of probe-rs, so with the latest version installed you're ready to debug & program a esp32c3! More details in the the book.

espflash

espflash has seen a few minor releases since its 1.0 release in the last post, in which the following features and fixes have been included:

  • CLI argument parsing was unified between cargo-espflash and espflash
    • Same subcommands and arguments available for both binaries (minus the build-related stuff for espflash)
  • Support added for flashing the ESP32-S3
  • Serial port auto-detection implemented
    • Optionally allows for a VID/PID to be specified via config file
  • Various bugfixes and improvements:
    • Add --package and --target options
    • Retry connections with different delays (for older ESP32 chips)
    • Improved handling of custom partition tables

Compiler

There is little to report on the compiler front, the main addition is the esp32s3 bare metal and std target. However, using Rust has been a great test bed for our LLVM fork supporting the Xtensa architecture and it has already brought a few code generation bugs to light which have been promptly fixed with patch releases to the LLVM fork. I'd also like to reiterate that we have prebuilt toolchains available with Xtensa support under the rust-build repository, it is no longer required to build the compiler yourself. We have builds for:

  • x86
    • Windows
    • Linux
    • MacOS
  • aarch64
    • MacOS (M1)
    • Linux2

What's next?

Our main goal are squashing bugs and documentation improvements. We also would like to start creating some more advanced examples to show off the progress we've made, if you have any projects you're working on that please feel free to drop into the matrix chat and tell us all about it! If the project is open source we may also add it to our CI regression test so we (hopefully) won't break your project in the future. I'd also like to take this time to thank all of our community contributors, we've made some awesome progress in the last two quarters thanks to your help!




1

This hasn't yet been tested on 64bit RISC-V.

2

There is some missing tooling on the esp-idf side for Linux aarch64, please track this issue if you are interested.