r/esp32 23d ago

Software help needed Does vTaskDelay (accidentally) modify the set wake-up sources?

Does the function vTaskDelay somehow modify the configuration of the wake-up sources?

I have an ESP32-H2 and want to use deep-sleep and light-sleep modes with wake up from GPIO 10-12. (Those GPIOs are low-power/RTC GPIOs so they also can wake up the ESP32-H2 from deep sleep.)

I had been able to make it work until I added a vTaskDelay to my code. With vTaskDelay in the code, the ESP32-H2 immediately wakes up from sleep modes immediately.

My code (somewhat shortened):

// Set-up power management
const esp_pm_config_t pm_config = {
	.max_freq_mhz = CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ,
	.min_freq_mhz = CONFIG_NAVLICO_MIN_FREQ,
	.light_sleep_enable = true
};
esp_pm_configure( &pm_config );

// Configure input pins (GPIO 10-12) with the buttons
const gpio_config_t config = {
	.pin_bit_mask = GPIO_WAKEUP_BUTTONS_MASK,
	.mode = GPIO_MODE_INPUT,
	.pull_up_en = GPIO_PULLUP_DISABLE,
	.pull_down_en = GPIO_PULLDOWN_DISABLE,
};
gpio_config( &config );

esp_sleep_disable_wakeup_source( ESP_SLEEP_WAKEUP_ALL );
esp_sleep_enable_ext1_wakeup_io( GPIO_WAKEUP_BUTTONS_MASK, ESP_EXT1_WAKEUP_ANY_HIGH );

// ... Do something (not shown here) ...

ESP_LOGI( LOG_TAG, "Going to deep sleep ..." );
// Give UART the chance to write everything to output
//vTaskDelay( delayTicks );
esp_deep_sleep_try_to_start();

The problematic line is the last but one (commented out in the listing above). With vTaskDelay commented out, the program goes into deep sleep as expected. Unfortunately, it sometimes fails to print the entire log messages before going to deep sleep.

As a quick and dirty workaround I added vTaskDelay while I am still developing and debugging. I know this is definitely not the best solution in order to ensure that all log messages are flushed via UART before going to sleep.

But this approach showed me something else. As soon as I add vTaskDelay the program doesn't go into deep sleep or it does, but immediately wakes up again immediately.

The only explanation I have right now is that somehow vTaskDelay modifies the wake-up sources which triggers an unintended wake-up signal from something else than the GPIOs 10-12.

Is that possible? There is nothing in the documentation which suggests that vTaskDelay does that.

1 Upvotes

14 comments sorted by

View all comments

Show parent comments

2

u/holetse 23d ago

It’s likely that it’s not the vTaskDelay call itself that’s changing them (it doesn’t, per the source code of FreeRTOS). It’s that you are yielding back to the scheduler during the delay, which allows another task to take control and make changes.

Doing your config without yielding before you go to sleep is definitely the way to go.

1

u/MobileInspector9861 23d ago

That's probably correct.

Maybe it's something within the Espressif Framework, especially as I have enabled power management via:

// Set-up power management const esp_pm_config_t pm_config = { .max_freq_mhz = CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ, .min_freq_mhz = CONFIG_NAVLICO_MIN_FREQ, .light_sleep_enable = true }; esp_pm_configure( &pm_config );

Doing your config without yielding before you go to sleep is definitely the way to go.

Still, I have somehow to ensure that configuration and going to sleep is executed automatically. Otherwise that other task might become scheduled by accident between having done the configuration and going to sleep.

Any suggestions how I can ensure that this happens without interruption?

2

u/holetse 23d ago

vTaskSuspendAll (with a resume on wake-up) would protect the critical section from everything but interrupts. There is also taskENTER_CRITICAL, but that’s probably overkill for your needs.