You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: .github/cpp.instructions.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -464,7 +464,7 @@ On ESP32, `delay(ms)` calls `vTaskDelay(ms / portTICK_PERIOD_MS)`, which **suspe
464
464
Even in stock arduino-esp32, `yield()` calls `vTaskDelay(0)`, which only switches to tasks at equal or higher priority — the IDLE task (priority 0) is never reached.
465
465
**Do not use `yield()` to pace ESP32 tasks or assume it feeds any watchdog**.
466
466
467
-
**Custom `xTaskCreate()` tasks must call `delay(1)` in their loop, not `yield()`.** Without a real blocking call, the IDLE task is starved and the IDLE watchdog may panic:
467
+
**Custom `xTaskCreate()` tasks must call `delay(1)` in their loop, not `yield()`.** Without a real blocking call, the IDLE task is starved. The IDLE watchdog panic is the first visible symptom — but the damage starts earlier: deleted task memory leaks, software timers stop firing, light sleep is disabled, and Wi-Fi/BT idle hooks don't run. See `esp-idf.instructions.md` for a full explanation of what IDLE does.
468
468
469
469
```cpp
470
470
// WRONG — IDLE task is never scheduled; yield() does not feed the idle task watchdog.
|`SOC_ADC_MAX_BITWIDTH`|`int`|`util.cpp`| ADC resolution (12 or 13 bits) |
63
+
|`SOC_ADC_MAX_BITWIDTH`|`int`|`util.cpp`| ADC resolution (12 or 13 bits). Renamed to `CONFIG_SOC_ADC_RTC_MAX_BITWIDTH` in IDF v5|
64
64
|`SOC_ADC_CHANNEL_NUM(unit)`|`int`|`pin_manager.cpp`| ADC channels per unit |
65
65
|`SOC_UART_NUM`|`int`|`dmx_input.cpp`| Number of UART peripherals |
66
66
|`SOC_DRAM_LOW` / `SOC_DRAM_HIGH`|`addr`|`util.cpp`| DRAM address boundaries for validation |
@@ -588,16 +588,27 @@ ADC is one of the most fragmented APIs across IDF versions:
588
588
589
589
### Bit width portability
590
590
591
-
Not all chips have 12-bit ADC. Use `SOC_ADC_MAX_BITWIDTH` to adapt:
591
+
Not all chips have 12-bit ADC. `SOC_ADC_MAX_BITWIDTH`reports the maximum resolution (12 or 13 bits). Note that in IDF v5, this macro was renamed to `CONFIG_SOC_ADC_RTC_MAX_BITWIDTH`. Write version-aware guards:
adc1_config_width(ADC_WIDTH_BIT_12); // ESP32, S3, C3, etc.
598
607
#endif
599
608
```
600
609
610
+
WLED-MM's `util.cpp` uses the IDF v4 form (`SOC_ADC_MAX_BITWIDTH`) — this will need updating when the codebase migrates to IDF v5.
611
+
601
612
---
602
613
603
614
## RMT Best Practices
@@ -699,6 +710,17 @@ FreeRTOS on ESP32 is **preemptive** — all tasks are scheduled by priority rega
699
710
700
711
**`yield()` does not yield to IDLE.** Any task that loops with only `yield()` calls will starve the IDLE task, causing the IDLE watchdog to fire. Always use `delay(1)` (or a blocking FreeRTOS call) in tight task loops. Note: WLED-MM redefines `yield()` as an empty macro on ESP32 WLEDMM_FASTPATH builds — see `cpp.instructions.md`.
701
712
713
+
#### Why the IDLE task is not optional
714
+
715
+
The FreeRTOS IDLE task (one per core on dual-core ESP32/S3) is not idle in the casual sense — it performs essential system housekeeping:
716
+
717
+
-**Frees deleted task memory**: when a task calls `vTaskDelete()`, the IDLE task reclaims its TCB and stack. Without IDLE running, deleted tasks leak memory permanently.
718
+
-**Runs FreeRTOS software timers**: the timer daemon relies on IDLE-priority execution. Many ESP-IDF components (Wi-Fi, BLE, NVS) schedule work via software timers.
719
+
-**Implements tickless idle / light sleep**: on battery-powered devices, IDLE is the entry point for low-power sleep. A permanently starved IDLE task disables light sleep entirely.
720
+
-**Runs registered idle hooks**: ESP-IDF components register callbacks via `esp_register_freertos_idle_hook()` (e.g., Wi-Fi background maintenance, Bluetooth housekeeping). These only fire when IDLE runs.
721
+
722
+
In short: **starving IDLE corrupts memory cleanup, breaks software timers, disables low-power sleep, and prevents Wi-Fi/BT maintenance.** The IDLE watchdog panic is a symptom — the real damage happens before the watchdog fires.
723
+
702
724
### Watchdog management
703
725
704
726
Long-running operations may trigger the task watchdog. Feed it explicitly:
0 commit comments