Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Asynchronous Rust on Cortex-M Microcontrollers (2023) (memfault.com)
26 points by Tomte 8 months ago | hide | past | favorite | 7 comments


I am of the opinion that async/await syntax for efficient embedded programming is one of the true revolutions of Rust -- and often overlooked. I gave a presentation about this very idea at a recent Rust meetup in Paris. The slides are there if some are interested (though admittedly not very explicit on their own): https://docs.google.com/presentation/d/e/2PACX-1vRT_ejw7Uza6...


I lost access to the slides half way through reading them... Too bad! I was enjoying the presentation! (“Rust makes me feel guilty” :)

EDIT: Never mind. Access came back. Good slides!


Sorry about that, I switched the link. Thanks.


Cortex M micros have a builtin preemptive async scheduler - the NVIC.

My personal style for doing embedded firmware have evolved to do everything in interrupt handlers and dynamically set priorities and pending bits to launch the next 'task' - main is just an empty for loop with a WFE/WFI instruction in it. The hardware is even specifically designed for this style with interrupt call chaining - when you exit an interrupt handler and another pending interrupt is asserted you dont take the full overhead of pushing/popping registers.


Async embedded rust is fantastic. Absolutely nailed it once a couple more unstable features stabilize.

Also on cortex-m, you can put an executor on each cooperative priority but also you can put an executor on the main priority. That means you have one preemptive executor for blocking tasks and a couple cooperative choices.

I should add that I saw a huge reduction in RAM usage going to Embassy from Zephyr for a couple complicated applications. (on the order of 100KiB with all the stack and buffering reductions)


Can you give/point me to an example for how to do this (preemptive + cooperative combination)? What are the use cases? I’m new to embedded programming (and intermediate in Rust).


The main executor that you get when main is spawned is preemptive. You can do compression, math, etc there for as long as you like. You can spawn other executors from the main with assigned priorities. Using SWI executors for high priority cooperative scheduling can be great for timely handling of hardware peripherals. You slap an async Channel in between tasks that run on the same or different executors.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: