sleep: fix deadlock in esp_timer_impl_advance after light sleep

When light sleep is started, the other CPU gets halted using DPORT
stall mechanism. This can happen while it is inside an esp_timer
critical section, which may lead to a deadlock. This change adds
functions to take and release esp_timer lock before entering
DPORT critical section, preventing the deadlock.
This commit is contained in:
Ivan Grokhotkov
2018-05-04 12:50:39 +08:00
parent 296b280801
commit 8c307a5720
4 changed files with 60 additions and 0 deletions

View File

@@ -91,6 +91,35 @@ TEST_CASE("light sleep stress test", "[deepsleep]")
vSemaphoreDelete(done);
}
TEST_CASE("light sleep stress test with periodic esp_timer", "[deepsleep]")
{
void timer_func(void* arg)
{
ets_delay_us(50);
}
SemaphoreHandle_t done = xSemaphoreCreateCounting(2, 0);
esp_sleep_enable_timer_wakeup(1000);
esp_timer_handle_t timer;
esp_timer_create_args_t config = {
.callback = &timer_func,
};
TEST_ESP_OK(esp_timer_create(&config, &timer));
esp_timer_start_periodic(timer, 500);
xTaskCreatePinnedToCore(&test_light_sleep, "ls1", 4096, done, UNITY_FREERTOS_PRIORITY + 1, NULL, 0);
#if portNUM_PROCESSORS == 2
xTaskCreatePinnedToCore(&test_light_sleep, "ls1", 4096, done, UNITY_FREERTOS_PRIORITY + 1, NULL, 1);
#endif
xSemaphoreTake(done, portMAX_DELAY);
#if portNUM_PROCESSORS == 2
xSemaphoreTake(done, portMAX_DELAY);
#endif
vSemaphoreDelete(done);
esp_timer_stop(timer);
esp_timer_delete(timer);
}
#ifdef CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_CRYSTAL
#define MAX_SLEEP_TIME_ERROR_US 200
#else