Fearless concurrency in your microcontroller

https://japaric.github.io/rustfest-2017-09-30

Jorge Aparicio - @japaric - jorapa-7@student.ltu.se

Per Lindgren - Per.Lindgren@ltu.se

Lulea University of Technology

Microcontrollers

I/O with the world

A microcontroller soldered to a PCB

Cheap. Simple. Low power. Full control.

Tasks


let mut task1 = || {
    loop {
        let byte = await!(serial.gread()).unwrap();
        await!(serial.gwrite(byte)).unwrap();
    }
};
              

let mut on = false;
let mut task2 = || {
    loop {
        on = !on;

        if on {
            LED.on();
        } else {
            LED.off();
        }

        await!(timer.gwait());
    }
};
              

The need for preemption

Scenario: You need to execute two periodic tasks concurrently.

  • Task 1 needs to be run every 10 ms and takes 2 ms to complete.
  • Task 2 needs to be run every 1 ms and takes 100 us to complete.

Can these timing constrains be satisfied using cooperative multitasking?

In general, no. We need task prioritization, which requires preemption.

Disabling interrupts


use cortex_m::interrupt;

fn main() {
    loop {
        interrupt::free(|_|
            unsafe { DATA.modify(); }
        );
    }
}

interrupt!(EXTI0, handler);
fn handler() {
    unsafe { DATA.modify() }
}

Now this is memory safe.

Not all contexts need to lock the data.

Real Time For the Masses (RTFM)

Beyond locking.

What's next?

Concurrent Reactive Objects (CRO)

  • Model: Objects and Message Passing
  • Synchronous and asynchronous messages
  • Timing semantics

Thanks!

Questions?

(if there's time)

(inb4 "Where are my threads?!")