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.
Embassy can (these days, not sure if this is more recent than the article) do preemption, but it works by setting up multiple task pools and executors for each priority level: https://docs.embassy.dev/embassy-executor/git/cortex-m/struc... Non-realtime compute heavy tasks can be processed in the background executor and interrupted by latency sensitive ones.
In my experience, it is pretty rare to run much actual work on a microcontroller.
Testing at effectively idle represents most of my usecases.
For the times where there is a background load: RTIC has task priorities and pre-emption, so you can run your compute-intensive task with a lower priority and react to interrupts in a timely manner.
The title in the article is literally "Async Rust vs RTOS showdown!" and the article shows "Embassy/Rust against FreeRTOS/C". There should also be a (2022) appended.
You just need to read the Reddit comments to see why this is not a useful comparison [1] [2].
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.
For the times where there is a background load: RTIC has task priorities and pre-emption, so you can run your compute-intensive task with a lower priority and react to interrupts in a timely manner.
Perhaps "Embedded async Rust vs. C RTOS"
You just need to read the Reddit comments to see why this is not a useful comparison [1] [2].
[1] https://www.reddit.com/r/rust/comments/sik3g0/async_rust_vs_...
[2] https://www.reddit.com/r/embedded/comments/she3u9/async_rust...
The title on HN should probably be updated to that