This Skill covers the IDF FreeRTOSbundled with ESP-IDF (a kernel modified based on Vanilla FreeRTOS v10.5.1, high-confidence baseline), not the upstream original FreeRTOS. Task partitioning, synchronization primitives, stacks/priorities, dual-core core pinning.The two easiest differences to trip over: stack units are bytes; the priority upper limit is configurable (default 25, subject to sdkconfig).
Determine Task Type
- Concurrency structure design — partition tasks, choose queues/semaphores/timers → Workflow 1.
- Stack/priority tuning — suspected stack overflow, suspected priority inversion → Workflow 2 (stack unit = bytes).
- Dual-core/SMP issues — core pinning, cross-core contention, PRO_CPU/APP_CPU → Workflow 3, read smp-pinning。
- Crash scene(panic/backtrace/coredump) → hand off to
esp32-debug。 - Concurrency at the driver/pin layer(ISR interaction with peripheral drivers) → hand off to
esp32-peripherals。
Preflight (verify at runtime first)
idf.py --version # IDF 版本决定内核版本
grep -E "CONFIG_FREERTOS_(UNICORE|MAX_PRIORITIES)" sdkconfig
grep -nE "xTaskCreate|PinnedToCore|xQueue|Semaphore|portMUX" main/*.c
- Confirm whether this project runs single-core or dual-core (
CONFIG_FREERTOS_UNICORE)。 - Confirm this project's actual priority upper limit (
CONFIG_FREERTOS_MAX_PRIORITIES)——do not answer with 25, answer according to sdkconfig。 - Record the stack parameters and core pinning of existing tasks; reproduce the issue before making changes.
Offline Baseline
- IDF FreeRTOS facts are based on a dated baseline:modified based on Vanilla FreeRTOS v10.5.1, walk through 2026-09-02, does not auto-update.
- SMP dual-core targets:ESP32、ESP32-S3、ESP32-P4、ESP32-H4(Core 0=PRO_CPU / Core 1=APP_CPU); single-core chips like S2/C3 are always unicore.
- For semantic changes after upstream FreeRTOS v10.5.1, defer to the official documentation and the local sdkconfig/source code.
Contracts
- Verify the chip's core count and target against the physical device/schematic before discussing core pinning; discussing PinnedToCore on a single-core chip is meaningless.
- Stack size, priority, and queue length areproject decisions: defer to the current state of the code and sdkconfig; do not fabricate "recommended values" while claiming they are official values.
- Changing concurrency parameters changes timing behavior: change only one dimension at a time (stack OR priority OR core pinning), and keep a way to reproduce before changing.
Capability Boundaries + Hand-off
| User Intent | Skill |
|---|---|
| Project skeleton/sdkconfig/build and flash | esp32-idf |
| Peripheral drivers and ISR pin layer | esp32-peripherals |
| panic localization, stack overflow scene evidence collection (coredump/JTAG) | esp32-debug |
| Low power (sleep strategy when tasks are idle) | esp32-lowpower |
| On-board measured concurrency timing (logic analyzer/stress testing) | fw-hil-testing |
Workflow 1: Concurrency structure design
- Partition tasks by "event source → processing → output": one task, one responsibility; avoid a "god task".
- For inter-task communication usequeuesto pass data copies, not shared raw pointers; prefer queues over global flags for event notification.
- For mutual exclusion usemutexes(consider priority inheritance), for counting usesemaphores, for one-shot events use binary semaphores;do notuse
vTaskSuspendAllas a mutex—it only suspends scheduling on the current core (explicit in the baseline). - For periodic non-precise scheduling usesoftware timers(running in the timer service task context); for high-precision/hard real-time requirements switch to a dedicated task + delay primitives, and do not stuff them into timer callbacks.
- Call only
*FromISRvariant APIs in ISR context (upstream FreeRTOS general rule); leave processing to the task side.
Workflow 2: Stack and Priority
- Stack units are bytes(IDF FreeRTOS differs from upstream "words", baseline high confidence) — when reviewing code, convert first: 4096 = 4KB, not 1024 words.
- For new tasks, first use a conservative stack value + print the high water mark to verify, then tighten gradually; do not guess "2048 is enough".
- Priority: valid range 0 to
CONFIG_FREERTOS_MAX_PRIORITIES-1(default 25 → 0–24, higher is higher, idle=0);subject to this project's sdkconfig。 - Rank priority inversion: confirm the mutex has priority inheritance; for same-priority tasks, confirm time-slice behavior matches expectations.
- Forensic evidence collection for suspected stack overflow (backtrace/coredump) is handed off to
esp32-debug。
Workflow 3: Dual-core Pinning
- Read smp-pinning: SMP target chip table, per-core independent scheduler and idle task, portMUX spinlock semantics.
- For pinning strategy, first clarify "why pin" (cache locality/ISR ownership/isolation jitter), then implement
xTaskCreatePinnedToCore(); not pinning and letting the scheduler migrate freely is usually the default starting point. - After changing pinning, measure: don't just look at "it runs", verify timing and load distribution (mark without hardware evidence
Build Verification Only)。
Validation Gates
idf.py buildpasses; changed task parameters are consistent with sdkconfig.- Long-duration run (at least covering the worst-case business path) with no task starvation, no watchdog trigger.
- Stack high water mark still has margin after stress testing; conclusions have log/measurement evidence, do not claim "stable" without evidence.
Pitfalls
- Do notcalculate IDF task stacks in upstream FreeRTOS "word" units —IDF uses bytes, a 4x difference.
- Do notassume priorities are 0–31 — IDF's default upper limit is 25 (configurable), and references must state "subject to sdkconfig".
- Do notuse
vTaskSuspendAllas a mutex — on dual-core it only suspends the current core and cannot lock the other core. - Do notcall non-FromISR APIs in an ISR or perform blocking waits — leave that to the task side.
- Do notpin all tasks to Core 0 — for the PRO_CPU (Core 0)/APP_CPU (Core 1) division of labor, read smp-pinning first before deciding.
- Do notdirectly assert IDF behavior based on "upstream FreeRTOS experience" — first compare against this version's baseline and sdkconfig.
Official Sources
Privacy
This Skill only analyzes local code and configuration; it does not collect or send user data or credentials externally; accessing official links complies with the user's environment network policy.