Rust

Embedded, Async, all the way!

Who are we?

  • Ulf Lilleengen (@lulf)

  • Jens Reimann (@ctron)

Software Engineers @ Red Hat

What do we do?

  • Work on open source IoT

  • Cloud & embedded

  • With a focus on "Drogue IoT"

Why Rust?

A language empowering everyone to build reliable and efficient software.
— https://rust-lang.org
~70% of the vulnerabilities Microsoft assigns a CVE each year continue to be memory safety issues
A proactive approach to more secure code
— Microsoft

Meaning?

Those 70% would never have existed, if Rust had been used!

twitter 1

Recall EclipseCon 2019?

A tale of Rust, the ESP32 and IoT

A talk to get you excited about Rust.

layers 2019

We can do better!

Embedded Rust

Embedded?

  • 16 kB - 512 kB RAM

  • 128 kB - 2 MB ROM/Flash

  • No operating system

  • No memory allocator

A working group

  • Rust Embedded

  • Official working group of the Rust language

  • Community to collaborate on Rust embedded topics

Rust compiler

  • ARM (Cortex-M)

    • STM32

    • nRF (micro:bit)

    • Raspberry Pi Pico

  • RISC-V

    • ESP32 C3

Layers

Rust embedded layers

Creating applications

  • Plain Rust

  • RTIC

  • Embassy

Async Rust

Without async

fn main() {
    let mut button = Button::new();
    let mut led = Led::new();
    loop {
        if button.is_pressed() {
            led.on();
        } else {
            led.off();
        }
    }
}
  • Inefficient (busy looping)

Using interrupts

static BUTTON: Mutex<Option<Button>> = Mutex::new(None);
static LED: Mutex<Option<Led>> = Mutex::new(None);
fn main() {
    LED.lock().replace(Led::new());
    BUTTON.lock().replace(Button::new());
    setup_irq(button_event); // Magic
}

fn button_event() {
    if BUTTON.lock().as_mut().unwrap().is_pressed() {
        LED.lock().as_mut().unwrap().on();
    } else {
        LED.lock().as_mut().unwrap().off();
    }
}
  • Complex!

Using async

async fn main() {
    let mut button = Button::new();
    let mut led = Led::new();
    loop {
        button.wait_changed().await;
        if button.is_pressed() {
            led.on();
        } else {
            led.off();
        }
    }
}
  • Interrupt handling internally

  • Efficient - executor puts app to sleep on await points

Async executor

Rust requires an "executor" to drive async workload.

Tokio

  • Async executor for std

  • Builds on top of an I/O loop

Bare metal vs standard library

Bare metal Rust

Embassy

EMBedded ASYnc

  • An executor for embedded Rust, supporting no_std.

  • Async synchronization primitives, time keeping

  • HALs for nRF, STM32 and RP2040

  • Bootloader

  • USB, TCP/IP, LoRa and BLE

Embassy & friends

  • Drivers from crates.io

  • Ector

  • Drogue Device

Ector

An actor framework.

Drogue Device

Distribution of Embassy focused on a few boards supporting IoT, OTA updates.

Why RTOS?

No RTOS needed

DEMO?!

Recap

Rust embedded community

Thank you!

Questions?