Async Rust vs RTOS showdown: Embassy and FreeRTOS face off on STM32

Embedded Rust RTOS vs. C RTOS

Async Rust vs RTOS showdown: Embassy and FreeRTOS face off on STM32

In this technical comparison, the author pits Embassy (async Rust) against FreeRTOS (C) on an STM32F446 microcontroller, running identical applications that blink an LED, respond to a button interrupt, and communicate via a message queue. They measure interrupt latency, program size, static memory usage, and ease of programming. The post explains the fundamental differences between cooperative async executors and preemptive RTOS kernels, and provides code examples for both. The author predicts the RTOS will have better latency, while Rust will use less static memory, but the results may surprise.

In the web world async/await has already won from threads, so that will probably be the case here as well.
  1. Animats

    That's under very light CPU load. So an async approach, with no preemption, can work. If there's any significant compute going on, it won't work as well.

    A useful number to measure on a scope is worst case interrupt latency. This is what matters if there's a hard real-time constraint. They measured standard deviation, but not worst case. The usual test setup is that an input signal (typically a square wave) goes to an input pin, interrupt happens if interrupts not prevented, task starts, task turns on an output pin. You watch input to output delay on a scope and look for outliers.

    If you're running entirely run to completion, the outliers are determined by the longest compute task. This is a problem if there's a compute task.

    This is historically where QNX shines. Interrupt is processed and schedules a thread. About all that happens at interrupt level is thread activation. The thread turns on the output pin. You can look on a scope for scheduling outliers. The best case latency is higher than doing the work at interrupt level, but the worst case latency is constant, even if lower priority threads are compute bound.

    This is the difference between real time and "near real time" scheduling.

  2. CupricTea

    Title should be changed. Async Rust != RTOS. RTOS's are preemptively multithreaded while async is done cooperatively with yield points.

    Perhaps "Embedded async Rust vs. C RTOS"

  3. joshchngs

    This article is almost 5 years old now, which makes it fairly ancient in Embedded Rust terms. I think the general landscape hasn't changed all that much, but I'd be cautious of relying on any details from it.

More from this day

2026-09-02