Description
On the esp32 automatic light sleep / dynamic frequency scaling / power management puts the CPU to sleep when all tasks are idle thereby reducing the power consumption to about 1mA instead of around 40mA @ 160Mhz. The special feature of auto light sleep is that it can maintain a Wifi association by waking up at the appropriate times to receive AP beacons and respond to them. This ticket proposes to discuss how to enable auto light-sleep.
The first issue is that FREERTOS_USE_TICKLESS_IDLE
needs to be enabled in sdkconfig.h and that machine.freq()
must set pm.light_sleep_enable = true
.
The next issue is that mp_hal_stdin_rx_chr
and mp_hal_delay_ms
in mphalport.h
do not call vTaskDelay
and instead call ulTaskNotifyTake
which does not seem to enable auto light sleep (need to dig into this). Specifically, in the idle loop without wifi enabled ulTaskNotifyTake
almost always returns after 100ms, which seems to be too little for light sleep to kick in.
The use of vTaskDelay
got switched to ulTaskNotifyTake
as part of 14ab81e because it affects interrupt latency too much, see #3894.
Adding a call to vTaskDelay(4)
in there for test purposes results in the expected power savings (a value of 4 is the minimum for light sleep to kick in). However, it messes up gpio: they all(?) go low, which is unexpected (I expected ESP-IDF to handle this appropriately). The gpio issue also affects the uart: the console no longer works unless one manages to get a char in while mp is polling. Mysteries...
Update: I had not understood the second parameter of ulTaskNotifyTake
: setting that to 4 also causes light sleep to kick in.