Trying Rust on ESP32

Hi there!

I'm currently trying to get started with Rust on ESP32 controllers. In the past I've played around a little with Rust and long before I put together a few little projects with ESP32 controllers using the Arduino libraries.

The best resource to get started from what I've found is the esp-rs book.

Another nice hub for information is the awesome-esp-rust collection.

So far I've managed to install the pre-built esp rust fork & generate a playground from their template:

curl -LO https://raw.githubusercontent.com/esp-rs/rust-build/main/install-rust-toolchain.sh
chmod +x install-rust-toolchain.sh
./install-rust-toolchain.sh
source export-esp.sh
cargo install cargo-generate
cargo generate --git https://github.com/esp-rs/esp-idf-template cargo

After installing a few more dependencies I managed to have this playground run on an ESP32 board by clicking the "Run" link showing above the fn main() { line:

cargo install ldproxy
cargo install espflash
cargo install cargo-espflash
cargo install cargo-espmonitor
cd esp32-rust-playground
code .

Here I found a sample that pauses execution, and that actually still works in the environment provided by the current esp-rs/rust-build, unlike the code found here & here).

Next I found the watchdog process was unhappy with my code, which I resolved by copying code from this github issue.

So my playground now contains this code:

use esp_idf_sys as _; // If using the `binstart` feature of `esp-idf-sys`, always keep this module imported

use embedded_hal::blocking::delay::DelayMs;
use esp_idf_hal::delay;

fn main() {
    // Temporary. Will disappear once ESP-IDF 4.4 is released, but for now it is necessary to call this function once,
    // or else some patches to the runtime implemented by esp-idf-sys might not link properly.
    esp_idf_sys::link_patches();

    unsafe {
        // Disable IDLE task WatchDogTask on this CPU.
        esp_idf_sys::esp_task_wdt_delete(esp_idf_sys::xTaskGetIdleTaskHandleForCPU(esp_idf_hal::cpu::core() as u32));

        // Enable WatchDogTask on the main (=this) task.
        esp_idf_sys::esp_task_wdt_add(esp_idf_sys::xTaskGetCurrentTaskHandle());
    };
    
    let mut delay = delay::Ets;

    let mut i: u128 = 0;
    loop {
        println!("loop pass #{i}");
        delay.delay_ms(100 as u32);
        
        // Feed WatchDogTask.
        unsafe {esp_idf_sys::esp_task_wdt_reset();}
        i=i+1;
    }   
}

Next tasks on my list:

  • connect to Wifi (should be easy, seen lot's of samples I can copy from)
  • get OTA to work (this is gonna be hard, found some issues but no sample code as of yet)
  • find an equivalent for millis() from the Arduino envrionment to tell the uptime of the board

The most active community talking about Rust on the ESP32 seems to be this matrix chat channel.

Looking at past topics concerning embedded development on Espriff boards on here doesn't make me too hopeful that I'll get helpful replies, but at least now I've collected & documented my thoughts / experiences so far for myself here :wink:

3 Likes

I also try to do some demos on the c3 device. The information I'm currently looking at is esp-rs and discovery

1 Like

I'm trying to learn Rust by programming a few ESP32 boards, currently the ESP32-C3. Here's my repo with some example code and links to various resources.

I'm not very good at Rust yet but I'd love to collaborate and learn. I'm trying to get all these peripherals working on the ESP32-C3:

  • Cloud

    • MQTT upload data
    • OTA
  • Peripherals

    • ADC
    • SPI
    • I2C
    • WIFI
    • GPIO
    • Interrupt
    • DMA
  • General

    • Unit tests
    • Multi-Threading
2 Likes