On a dual-core ESP32, a high-priority task that never blocks does not always starve a lower-priority one. Why not, and what still goes wrong?
ESP-IDF's FreeRTOS schedules on both cores, and each core runs the highest-priority ready task it can. The busy high task occupies one core, so the other core runs the low task. The idle task on the busy core still never runs, and the task watchdog warns about it.
* Two unpinned tasks on a dual-core ESP32: A occupies core 0, so B gets core 1. *
Tasks created with plain xTaskCreate on ESP-IDF have no core affinity, so either core may run them. The scheduler makes the "highest ready priority" choice per core:
- Core 0 picks task A (priority 10), which spins forever.
- Core 1 cannot run A, because A is already running on core 0, so it picks the next one, task B. When B blocks on its delay, core 1's idle task gets its turn. If B never blocked either, core 1's idle task would starve as well.
So on real dual-core hardware the starvation from the single-core picture can disappear, and the output looks fine. It comes back if you enable "run FreeRTOS only on first core", pin both tasks to the same core with xTaskCreatePinnedToCore, or add a third busy task.
What does not disappear is the idle task of the busy core. The idle task frees the memory of deleted tasks and lets the chip save power, and ESP-IDF's task watchdog watches each core's idle task by default. If it hasn't run for the timeout (5 s by default), the watchdog prints "Task watchdog got triggered" and a backtrace. By default it only warns; it can be configured to panic and reset.
Tip: a program that "works on the board" can still be wrong; test scheduling assumptions single-core, where they cannot hide behind the second core.
Go deeper:
ESP-IDF — FreeRTOS (IDF): SMP scheduling — core affinity and how each core picks its task.
ESP-IDF — Watchdogs — the task watchdog, which idle tasks it watches, and the panic option.
Wikipedia — Processor affinity — what pinning a task to a core means, the idea behind
xTaskCreatePinnedToCore.