Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Blinking an LED with ESP RTOS (Embassy) on ESP32 in Rust

Let's re-setup the blinky project but with embassy support.

Setup project

To start the project, use the esp-generate command. Run the following:

esp-generate --chip esp32 blinky-embassy

This time, we need to select "Add Embassy framework support". Since this requires unstable feature, we'll first click "Enable unstable HAL features" and then proceed to select Embassy support. Finally, we'll press 's' to save the generated project with Embassy support.

Key points

If you notice, the main function is now marked as async, along with a few other changes in the code. However, the core logic for blinking the LED remains the same.

The key addition is this part:

#![allow(unused)]
fn main() {
let timg0 = TimerGroup::new(peripherals.TIMG0);
esp_rtos::start(timg0.timer0);
}

This sets up a timer that Embassy needs to handle async tasks like delays. We create a timer group using hardware timer TIMG0, then pass one of its timers to esp_rtos::start to let Embassy use it for time-based operations.

The Full code

#![no_std]
#![no_main]
#![deny(
    clippy::mem_forget,
    reason = "mem::forget is generally not safe to do with esp_hal types, especially those \
    holding buffers for the duration of a data transfer."
)]

use embassy_executor::Spawner;
use embassy_time::{Duration, Timer};
use esp_hal::clock::CpuClock;
use esp_hal::gpio::{Level, Output, OutputConfig};
use esp_hal::timer::timg::TimerGroup;

#[panic_handler]
fn panic(_: &core::panic::PanicInfo) -> ! {
    loop {}
}

// This creates a default app-descriptor required by the esp-idf bootloader.
// For more information see: <https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/system/app_image_format.html#application-description>
esp_bootloader_esp_idf::esp_app_desc!();

#[esp_rtos::main]
async fn main(_spawner: Spawner) -> ! {
    // generator version: 1.0.0

    let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max());
    let peripherals = esp_hal::init(config);

    let timg0 = TimerGroup::new(peripherals.TIMG0);
    esp_rtos::start(timg0.timer0);

    let mut led = Output::new(peripherals.GPIO2, Level::High, OutputConfig::default());

    loop {
        led.toggle();
        Timer::after(Duration::from_secs(1)).await;
    }
}

Clone the existing project

You can clone (or refer) project I created and navigate to the async-projects/blinky-embassy folder.

git clone https://github.com/ImplFerris/esp32-projects
cd esp32-projects/async-projects/blinky-embassy