add soft solution for esp32 eco3 live lock issue

This commit is contained in:
Li Shuai
2020-05-29 14:53:30 +08:00
committed by bot
parent 55b319e1ae
commit 72f583dfa7
6 changed files with 345 additions and 3 deletions
+30 -1
View File
@@ -34,7 +34,7 @@
#if CONFIG_ESP_INT_WDT
#define WDT_INT_NUM 24
#define WDT_INT_NUM ETS_T1_WDT_INUM
#define IWDT_INSTANCE WDT_MWDT1
#define IWDT_PRESCALER MWDT1_TICK_PRESCALER //Tick period of 500us if WDT source clock is 80MHz
@@ -42,6 +42,16 @@
#define IWDT_INITIAL_TIMEOUT_S 5
static wdt_hal_context_t iwdt_context;
#if CONFIG_ESP32_ECO3_CACHE_LOCK_FIX
/*
* This parameter is indicates the response time of Interrupt watchdog to
* identify the live lock.
*/
#define IWDT_LIVELOCK_TIMEOUT_MS (20)
extern uint32_t _l4_intr_livelock_counter, _l4_intr_livelock_max;
#endif
//Take care: the tick hook can also be called before esp_int_wdt_init() is called.
#if CONFIG_ESP_INT_WDT_CHECK_CPU1
//Not static; the ISR assembly checks this.
@@ -56,7 +66,13 @@ static void IRAM_ATTR tick_hook(void) {
//Todo: Check if there's a way to avoid reconfiguring the stages on each feed.
wdt_hal_write_protect_disable(&iwdt_context);
//Reconfigure stage timeouts
#if CONFIG_ESP32_ECO3_CACHE_LOCK_FIX
_l4_intr_livelock_counter = 0;
wdt_hal_config_stage(&iwdt_context, WDT_STAGE0,
CONFIG_ESP_INT_WDT_TIMEOUT_MS*1000/IWDT_TICKS_PER_US/(_l4_intr_livelock_max+1), WDT_STAGE_ACTION_INT); //Set timeout before interrupt
#else
wdt_hal_config_stage(&iwdt_context, WDT_STAGE0, CONFIG_ESP_INT_WDT_TIMEOUT_MS*1000/IWDT_TICKS_PER_US, WDT_STAGE_ACTION_INT); //Set timeout before interrupt
#endif
wdt_hal_config_stage(&iwdt_context, WDT_STAGE1, 2*CONFIG_ESP_INT_WDT_TIMEOUT_MS*1000/IWDT_TICKS_PER_US, WDT_STAGE_ACTION_RESET_SYSTEM); //Set timeout before reset
wdt_hal_feed(&iwdt_context);
wdt_hal_write_protect_enable(&iwdt_context);
@@ -101,9 +117,22 @@ void esp_int_wdt_init(void) {
void esp_int_wdt_cpu_init(void)
{
assert((CONFIG_ESP_INT_WDT_TIMEOUT_MS >= (portTICK_PERIOD_MS<<1)) && "Interrupt watchdog timeout needs to meet twice the RTOS tick period!");
esp_register_freertos_tick_hook_for_cpu(tick_hook, xPortGetCoreID());
ESP_INTR_DISABLE(WDT_INT_NUM);
intr_matrix_set(xPortGetCoreID(), ETS_TG1_WDT_LEVEL_INTR_SOURCE, WDT_INT_NUM);
#if CONFIG_ESP32_ECO3_CACHE_LOCK_FIX
/*
* This is a workaround for issue 3.15 in "ESP32 ECO and workarounds for
* Bugs" document.
*/
_l4_intr_livelock_counter = 0;
if (soc_has_cache_lock_bug()) {
assert((portTICK_PERIOD_MS<<1) <= IWDT_LIVELOCK_TIMEOUT_MS);
assert(CONFIG_ESP_INT_WDT_TIMEOUT_MS >= (IWDT_LIVELOCK_TIMEOUT_MS*3));
_l4_intr_livelock_max = CONFIG_ESP_INT_WDT_TIMEOUT_MS/IWDT_LIVELOCK_TIMEOUT_MS - 1;
}
#endif
//We do not register a handler for the interrupt because it is interrupt level 4 which
//is not servicable from C. Instead, xtensa_vectors.S has a call to the panic handler for
//this interrupt.