Rust on Espressif chips - 2023 Roadmap

This is the next quarterly update of esp-rs effort, detailing the progress over Q4 2022 as well as a roadmap for 2023.

Rust Compiler & LLVM

Other than the occasional rebase for every Rust release, there is not too much to report on the rust compiler fork. However, we have really exciting news about LLVM. The first 10 Xtensa patches have been approved and committed upstream 🎉, you can view them here. This is exciting for us, Espressif has been pushing this upstreaming effort since 2019! So it's very nice to have something upstream, with plenty more patches to follow. At this point, I'd also like to make it clear that you do not need the forked compiler for our RISC-V-based chips, esp32c2, esp32c3, esp32c6 etc. You only need the forked compiler for our Xtensa-based chips, esp32, esp32s2 & esp32s3.

espup, our custom toolchain manager has seen some nice improvements over the quarter. It now leverages async to improve installation times, by downloading multiple things concurrently. We switched to espup in our CI pipelines and saw a significant improvement in setup time.

esp-hal - no_std

esp-hal has seen two releases in the last quarter, adding many features including our first async driver, async GPIO.

  • Async: GPIO - #333
  • Rework the CI workflow - #343
  • Remove the signals from the GPIO structs - #337
  • Fix GPIO interrupts for pins > 31 - #335
  • Finish PeripheralRef - #334
  • Use the latest PACs - #331
  • Fix the CI badge - #330
  • pulse counter implementation - #328
  • enable TWAI on ESP32-S3 - #325
  • Completely remove pac references in hal drivers - #309
  • Support ESP32-C2 with 26MHz Xtal - #301
  • Add a CI job to verify formatting - #297
  • New releases for all HALs - #296
  • Fix LEDC duty-cycle updates - #294
  • Correct Systimer delay implementation - #293
  • Fix ESP32-C2 trap handler - #292
  • Embassy init updates - #290
  • Add cfg symbols for i2s and mcpwm - #289
  • Pass trap frame to CPU interrupt handlers (Xtensa) - #286
  • Fix clippy warnings, update READMEs - #284
  • remove i2c::SetupError and make i2c::I2C::new infallible - #281
  • GPIO module refactoring - #280
  • Export InputSignal and OutputSignal - #276
  • Finalize I2S RX Implementation - #274
  • Update install sections - #273
  • PeripheralRef init: uart - #272
  • Implemented ability to write bytes in UsbSerialJtag - #271
  • Fix example in esp-hal-procmacros::interrupt doc - #270
  • Add Rx and interrupts to UsbSerialJtag - #267
  • Avoid potential linker error for ESP32-C2 and ESP32-C3 - #266
  • New releases for all HALs - #265
  • Add more configuration symbols and simplify the build script - #264
  • Detangle I2C clock calculation - #263
  • Preliminary I2S Implementation - #262
  • Fix UART unlisten calls so they clear the interrupt enable - #261
  • Add more trait re-exports to prelude module - #260
  • Update all PACs to their latest versions - #259
  • Add SHA accelerator implementation - #257
  • doc: add #[doc(inline)] to esp-hal-common re-exports - #256
  • MCPWM MVP implementation - #255
  • Add Mcpwm0 and Mcpwm1 to system::Peripheral - #254
  • add/correct docs for gpio::OutputSignal and add PWM output signal to ESP32-S3 - #251
  • Add LEDC support for ESP32-C2 - #250
  • Update to newest PACs for C2/C3/S3 and clean up GDMA implementation - #248
  • Add uninit section to bl and mv linker scripts to match db - #246
  • ADC: Refactor, join S2 and S3 together and C2 and C3 as well - #245
  • ESP32-C2 APB clock is 40MHz, not 80MHz - #244

esp-wifi - no_std

esp-wifi saw some nice features over the last quarter, along with some bug fixes, performance improvements and refactors.

  • ESP32-C2 BLE - #110
  • WiFi for ESP32-C2 - #107
  • Update Drivers - #106
  • BTLE for ESP32-S3 - #105
  • Add ps_min_modem feature - #103
  • Misc improvements - #102
  • Update dependencies - #100
  • Have a way to yield from a task - #98
  • Re-introduce a Queue for TX - #96
  • Add static IP and socket listening example - #95
  • Fix ESP32-C3 development mode - #90
  • Works on ESP32-C3-DevKit-RUST-1 again - #86
  • Update embedded svc - #84
  • Support multiple sockets, UDP and multicast - #82
  • Fix the newest ESP-HALs Alarm's method - #81
  • Update README.md wording - #75

esp-idf - std

  • General purpose delay provider - #210
  • LEDC Clock enum name/typedef change in esp-idf master - #208
  • Update xtensa-toolchain action - #206
  • Fix issue #201: Use NonZeroUsize to specify DMA transfer size - #203
  • Add queue length to CAN config - #202
  • Fix a typo - #196
  • Correct endianness of RMT signal in neopixel example - #195
  • Add input_delay_ns to config struct - #192
  • Add auto_reload functionality to timers - #190
  • Use EspError::from_infallible - #189
  • #180 ledcdriver redundand timer config - #188
  • Adjust for esp-idf-sys size_t -> usize - #185
  • Ci for idf 5.0 - #183
  • Implement watchdog interface - #182
  • Fix typo in doc copy - #181
  • Implement exclusive SPI Bus - #174
  • Use Cell<Option<NonNull<QueueDefinition>>> instead of UnsafeCell<*mut QueueDefinition> - #170
  • do some clippy/Cargo.toml housekeeping, update st7789 example to use a non-deprecated driver - #169
  • Add can custom timing - #166
  • Overhaul UART to support single wire transmitters/receivers - #164
  • PCNT implementation for v4 esp-idf api (will work for on v5 with v4 api) - #157
  • Ledc: Add SpeedMode enum, allow lpoint < hpoint < max_duty - #155
  • Fix GPIO docstrings - #151
  • RFC: Multi CS Spi Implementation - #150
  • Add half duplex and 3wire mode support to SPI - #143
  • spi/adc_st7789_example - #125
  • Add RMT receiver - #104

Tooling

espflash

  • Make Interface constructor public - #354
  • Fix CI warnings - #350
  • Remove the USB Serial JTAG watchdog workaround now that we use the stub - #345
  • No longer build releases for the Windows GNU target - #343
  • Organize, simplify, and generally improve the errors - #342
  • If a bootloader and/or partition table other than the defaults have been provided, indicate such - #339
  • Mark public enums as #[non_exhaustive] for semver compatibility - #338
  • Use the flasher stub by default - #337
  • CLI improvements and dependency updates - #334
  • Add an optional callback trait which can be implemented and provided to most flashing functions - #333
  • Fix monitor after flash for ESP32-C2 - #330
  • Make the flasher return a struct of device information instead of printing directly - #328
  • Mention the bootloader/partition table auto-detection feature of cargo-espflash - #327
  • Fix the CI badge in the README - #325
  • Reorder ports so that known ports appear first in CLI - #324
  • Support ESPFLASH_BAUD env var - #322
  • Add support for flashing the ESP32-C6 - #317
  • Fix the serial monitor when using 26MHz ESP32-C2 - #315
  • Fix crystal frequency detection for ESP32-C2 and ESP8266 - #314
  • Version 2.0.0-rc.2 - #309
  • Fix typo in ImageFormatKind's FromStr implementation - #308
  • Display the newer 'v{major}.{minor}' chip revision format - #307
  • Make command module public - #303
  • Clean up unused code, optimize comparison in find_serial_port - #302
  • Add support for using custom cargo metadata when in a workspace - #300
  • Update dependencies to their latest versions - #299
  • Add shortopt -M for --monitor - #296
  • Allow SerialPortType::PciPort during port detection - #295
  • Report the image and partition size in the error - #293
  • Add option to supply the ELF image path in the monitor subcommand - #292
  • Version 2.0.0-rc.1 - #288
  • Make the interface module public - #287
  • Fix FlashSize discrepancy between clap, strum and FromStr - #286
  • Only display progress bars when cli feature is enabled, allow passing progress callback - #283
  • Print app size when using any image format, cleanup/use new features - #281
  • Add updated bootloaders for all chips - #278
  • Load stubs from TOML instead of JSON files - #277
  • Add a test for the Direct Boot image format - #276
  • Extract common functionality for erasing partition tables into a function - #275
  • Replace --erase-otadata with --erase-parts and --erase-data-parts - #273
  • Print additional information when invoking the save-image subcommand - #272
  • Additional docstrings for enums, structs, and traits - #271
  • connection: error handling - #270
  • connection: Swap error and status in CommandResponse - #269
  • Add back the image format tests which had been previously removed - #266
  • Remove unneeded attributes and pub(crate)s, old test data - #263

The 2023 roadmap

We've been thinking about what we'd like to achieve in the next year, and have put together a roadmap for 2023.

Async

Over the last year, we've made a real effort to get blocking implementations available for most peripherals both in our Standard library effort, and no_std efforts. Blocking is generally simpler to implement, as async relies on a good story for interrupts & DMA (direct memory access). This year we'd like to push for more async across both approaches; this includes async peripheral drivers (SPI, UART, I2C etc), including but not limited to the embedded-hal-async traits, as well as async networking solutions. Those of you familiar with the Standard library approach may have noticed there is actually quite a good async networking solution already available using smol-rs but we need to upstream many of our changes. Our main focus for no_std async networking will be on the esp-wifi crate.

Chip support

For both approaches, we will be adding support for the newly released ESP32-C6, as well as preparing support for the ESP32-H2 and ESP32-P4 once they are officially released. Support for the ESP32-C6 is in progress for no_std, and for STD, ESP32C6 support will be added with the release of esp-idf v5.1 (expected in May).

Low Power modes and co-processor support

Starting from the ESP32-S2, our chips have included a low-power RISC-V coprocessor for handling low-power operations when the main CPU is not needed. We'd like to leverage esp-hal for creating applications that can run on the constrained low-power core, for both no_std and std applications. The low-power core is too resource-constrained to run the full standard library, so using esp-hal makes perfect sense here.

STD build times

One of the barriers when developing for the STD platform is build times. We know of several improvements we can make to reduce the build time. One thing we'd like to take a look at this year is slimming down the esp-idf build, currently, we build everything, but esp-idf is made of components, which can be disabled if they're not needed. We're also aware that a lot of the 'build' time is spent downloading esp-idf sources via git, so we'd like to investigate how to reduce this time.

Documentation

We've made a lot of progress over the last year, but moving so fast has left the documentation situation in a not-so-great state. We're rewriting the book this year to cut out irrelevant, outdated information as well as fill the gaps created in the last year. We're currently self-hosting our standard library documentation because we need an internet connection to download toolchains/sources not present on the docs.rs runners, if possible we'd like to find a way to host our docs on docs.rs.