Skip to content

Latest commit

 

History

History
319 lines (215 loc) · 5.22 KB

presentation.md

File metadata and controls

319 lines (215 loc) · 5.22 KB
title author theme
Rust on ESP32
name
terminal-dark

Who's here?

We'll be talking about Rust and ESP32. Let's do a quick poll.

  • Who has written Rust before?
  • Who has developed for MCUs before?
  • Who has written Rust code for MCUs?

You need to know neither of these topics to follow.

Outline

  1. esp32 ?!
  2. rust ?!
  3. Implementing distributed coordination with the Anti-Firefly Algorithm

Workshop Preparation

For those participating

We brought ~20 ESP32 MCU's.

-> follow steps up to 5

For those listening

The complete code is in the above repo and can be explored.

For those that missed something

The presentation is in the same repo. Feel free to ask questions at any time. Q&A at the end for longer questions.

ESP32

32-bit microprocessors by Espressif

ESP32-C3 Super Mini

RISC-V, 1-core 160 MHz

sometimes 4 MiB flash

Pin compatible with ESP8266

ESP32-WROOM-32

Xtensa, 2-core 240 MHz

4 MiB flash

Rust embedded

The ecosystem is growing rapidly. See

rustc Platform support

Architecture Support
Bare ARM Tier 2 read "guaranteed to build"
RISC-V Tier 2 (ESP32-C, -H, and -P series)
AVR Tier 3 supported but untested
Xtensa Tier 3 (ESP32 and ESP32-S series)

Xtensa has open PRs in LLVM that need to be merged before official support can be improved.

std and no_std

std

Rust std (standard) library

Supported with esp-idf (layer between bare metal and program)

Higher level -> power usage

no_std

Rust core library
(strict subset of std)

Supported by esp-hal, the Hardware Abstraction Layer

Runs on bare metal, no OS

No memory allocator -> No heap

Can be circumvented with custom allocators

We'll focus on this

Anatomy of an embedded Rust program

#![no_std]
#![no_main]

use esp_backtrace as _; // panic handler

#[entry]
fn main() -> ! {
    // setup code

    loop {
        // loop code
    }
}

C -> Rust

A rather contentious topic.

C -> Rust

Why

  • Memory corruption can lead to hidden security issues and days to weeks of "blind" debugging.

A fast language that crashes all the time is like a supercar ... that crashes all the time.

~ noboilerplate.org

  • C will be replaced by a memory safe language. (fight me)
  • The Rust type system is an absolute joy to work with!

Rust type system

fn increment(_cs: &CriticalSection) {
  // incrementing something
  // must happen atomically
}

fn main() {
  // compile time error
  increment();
//^^^^^^^^^-- an argument is missing

  // instead do
  interrupt::free(|cs| increment(cs));
  // critical section is dropped ---^ here
  // because it is local to the closure
}

Iterators

let array = [0u16; 1'000'000];

// use
let max = array
    .iter()
    .max()
    .expect("The array is empty");

// instead of
let mut max = u16::MIN;
for i in 0..array.len() {
    if array[i] > max {
        max = array[i];
    }
}

C -> Rust

Why not #1

C -> Rust

Why not #2

The compile times are so slow and the compiler is annoying.

C -> Rust

Why not #2

The compile times are so slow and the compiler is annoying.

Let me present an alternative view:

Programming with the Rust compiler is like pair-programming with someone on the Rust Compiler Team.

Clippy

impl Add for Vec1 {
    type Output = Vec1;
    fn add(self, other: Vec1) -> Vec1 {
        Vec1(self.0 - other.0)
    }
}
warning: suspicious use of `-` in `Add` impl
 --> src/main.rs:9:21
  |
9 |         Vec1(self.0 - other.0)
  |                     ^

Questions?

[email protected]

Anti-Firefly

pick random time_slot
loop once per round:
    send beacon at time slot
    update time_slot :=
        predecessor
        + average(predecessor, successor)
        + interval