TL;DR: Do NOT use async-executor or edge-executor V <= 0.4.1 because the queues they use (crossbeam-queue and concurrent-queue) do NOT work with multi-prio threads and lead to priority inversion).
Until (or if) the problem in async-executor is confirmed and fixed, consider using:
embassy-executor
edge-executor from GIT
- The executor from the
futures crate
See this for more details.
====================================
Bug description
embassy-time timers (Timer::after()) occasionally never return when using the Embassy time driver provided in esp-idf-svc. This occurs more frequently with short delays (e.g., 50–100 ms) and with multiple tasks using Timer::after() calls
- Would you like to work on a fix? Yes
To Reproduce
- Enable the embassy-time-driver feature in esp-idf-svc.
- Use any executor (e.g., edge-executor) with the Embassy time driver.
- Spawn several tasks that repeatedly await short timers:
async fn ticker() { loop { Timer::after(Duration::from_millis(100)).await; // log or toggle GPIO } }
- After some period of time (minutes to hours depending on load), the loop stops printing/toggling.
- No panic occurs — the task simply hangs waiting for a timer that never fires.
Environment
- Crate (esp-idf-svc) version: 0.51.x
- ESP-IDF version: v5.3 / v5.5
- Target device (MCU): esp32
- OS: Windows 11 build-host (also reproducible on Linux)
TL;DR: Do NOT use
async-executororedge-executor V <= 0.4.1because the queues they use (crossbeam-queueandconcurrent-queue) do NOT work with multi-prio threads and lead to priority inversion).Until (or if) the problem in
async-executoris confirmed and fixed, consider using:embassy-executoredge-executorfrom GITfuturescrateSee this for more details.
====================================
Bug description
embassy-time timers (Timer::after()) occasionally never return when using the Embassy time driver provided in esp-idf-svc. This occurs more frequently with short delays (e.g., 50–100 ms) and with multiple tasks using Timer::after() calls
To Reproduce
async fn ticker() { loop { Timer::after(Duration::from_millis(100)).await; // log or toggle GPIO } }Environment