esp32: fix regression introduced in automatic light sleep pm

Closes: https://github.com/espressif/esp-idf/issues/2459

Signed-off-by: Mahavir Jain <mahavir@espressif.com>
This commit is contained in:
Mahavir Jain 2018-09-25 22:40:32 +05:30
parent 46ad2c6ad0
commit b5c321d981
3 changed files with 28 additions and 10 deletions

View file

@ -60,9 +60,7 @@ void esp_vApplicationIdleHook()
esp_pm_impl_idle_hook();
#endif
#ifndef CONFIG_FREERTOS_USE_TICKLESS_IDLE
asm("waiti 0");
#endif
esp_pm_impl_waiti();
}
esp_err_t esp_register_freertos_idle_hook_for_cpu(esp_freertos_idle_cb_t new_idle_cb, UBaseType_t cpuid)

View file

@ -80,6 +80,14 @@ static uint32_t s_mode_mask;
static uint32_t s_ccount_div;
static uint32_t s_ccount_mul;
#if CONFIG_FREERTOS_USE_TICKLESS_IDLE
/* Indicates if light sleep entry was successful for given CPU.
* This in turn gets used in IDLE hook to decide if `waiti` needs
* to be invoked or not.
*/
static bool s_entered_light_sleep[portNUM_PROCESSORS];
#endif // CONFIG_FREERTOS_USE_TICKLESS_IDLE
/* Indicates to the ISR hook that CCOMPARE needs to be updated on the given CPU.
* Used in conjunction with cross-core interrupt to update CCOMPARE on the other CPU.
*/
@ -453,11 +461,24 @@ void IRAM_ATTR esp_pm_impl_isr_hook()
ESP_PM_TRACE_EXIT(ISR_HOOK, core_id);
}
void esp_pm_impl_waiti()
{
#if CONFIG_FREERTOS_USE_TICKLESS_IDLE
int core_id = xPortGetCoreID();
if (!s_entered_light_sleep[core_id]) {
asm("waiti 0");
} else {
s_entered_light_sleep[core_id] = false;
}
#else
asm("waiti 0");
#endif // CONFIG_FREERTOS_USE_TICKLESS_IDLE
}
#if CONFIG_FREERTOS_USE_TICKLESS_IDLE
void IRAM_ATTR vApplicationSleep( TickType_t xExpectedIdleTime )
{
bool result = false;
portENTER_CRITICAL(&s_switch_lock);
if (s_mode == PM_MODE_LIGHT_SLEEP && !s_is_switching) {
/* Calculate how much we can sleep */
@ -495,15 +516,10 @@ void IRAM_ATTR vApplicationSleep( TickType_t xExpectedIdleTime )
;
}
}
result = true;
s_entered_light_sleep[core_id] = true;
}
}
portEXIT_CRITICAL(&s_switch_lock);
/* Tick less idle was not successful, can block till next interrupt here */
if (!result) {
asm("waiti 0");
}
}
#endif //CONFIG_FREERTOS_USE_TICKLESS_IDLE

View file

@ -104,6 +104,10 @@ void esp_pm_impl_isr_hook();
*/
void esp_pm_impl_dump_stats(FILE* out);
/**
* @brief Hook function implementing `waiti` instruction, should be invoked from idle task context
*/
void esp_pm_impl_waiti();
#ifdef CONFIG_PM_PROFILING
#define WITH_PROFILING