diff --git a/components/esp32/task_wdt.c b/components/esp32/task_wdt.c index fb10aac05..7e8883bdf 100644 --- a/components/esp32/task_wdt.c +++ b/components/esp32/task_wdt.c @@ -37,6 +37,8 @@ #include "esp_task_wdt.h" #include "esp_system_internal.h" +static const char *TAG = "task_wdt"; + //Assertion macro where, if 'cond' is false, will exit the critical section and return 'ret' #define ASSERT_EXIT_CRIT_RETURN(cond, ret) ({ \ if(!(cond)){ \ @@ -116,6 +118,17 @@ static void reset_hw_timer() } } +/* + * This function is called by task_wdt_isr function (ISR for when TWDT times out). + * It can be redefined in user code to handle twdt events. + * Note: It has the same limitations as the interrupt function. + * Do not use ESP_LOGI functions inside. + */ +void __attribute__((weak)) esp_task_wdt_isr_user_handler(void) +{ + +} + /* * ISR for when TWDT times out. Checks for which tasks have not reset. Also * triggers panic if configured to do so @@ -131,7 +144,7 @@ static void task_wdt_isr(void *arg) TIMERG0.wdt_wprotect=0; //Acknowledge interrupt TIMERG0.int_clr_timers.wdt=1; - //We are taking a spinlock while doing I/O (ets_printf) here. Normally, that is a pretty + //We are taking a spinlock while doing I/O (ESP_EARLY_LOGE) here. Normally, that is a pretty //bad thing, possibly (temporarily) hanging up the 2nd core and stopping FreeRTOS. In this case, //something bad already happened and reporting this is considered more important //than the badness caused by a spinlock here. @@ -140,21 +153,22 @@ static void task_wdt_isr(void *arg) ASSERT_EXIT_CRIT_RETURN((twdt_config->list != NULL), VOID_RETURN); //Watchdog got triggered because at least one task did not reset in time. - ets_printf("Task watchdog got triggered. The following tasks did not reset the watchdog in time:\n"); + ESP_EARLY_LOGE(TAG, "Task watchdog got triggered. The following tasks did not reset the watchdog in time:"); for (twdttask=twdt_config->list; twdttask!=NULL; twdttask=twdttask->next) { if (!twdttask->has_reset) { cpu=xTaskGetAffinity(twdttask->task_handle)==0?DRAM_STR("CPU 0"):DRAM_STR("CPU 1"); if (xTaskGetAffinity(twdttask->task_handle)==tskNO_AFFINITY) cpu=DRAM_STR("CPU 0/1"); - ets_printf(" - %s (%s)\n", pcTaskGetTaskName(twdttask->task_handle), cpu); + ESP_EARLY_LOGE(TAG, " - %s (%s)", pcTaskGetTaskName(twdttask->task_handle), cpu); } } - ets_printf(DRAM_STR("Tasks currently running:\n")); + ESP_EARLY_LOGE(TAG, "%s", DRAM_STR("Tasks currently running:")); for (int x=0; xpanic){ //Trigger Panic if configured to do so - ets_printf("Aborting.\n"); + ESP_EARLY_LOGE(TAG, "Aborting."); portEXIT_CRITICAL(&twdt_spinlock); esp_reset_reason_set_hint(ESP_RST_TASK_WDT); abort(); diff --git a/docs/en/api-reference/system/wdts.rst b/docs/en/api-reference/system/wdts.rst index e790a5df4..5a5252c22 100644 --- a/docs/en/api-reference/system/wdts.rst +++ b/docs/en/api-reference/system/wdts.rst @@ -44,7 +44,9 @@ elect to be watched by the TWDT. Each watched task must 'reset' the TWDT periodically to indicate that they have been allocated CPU time. If a task does not reset within the TWDT timeout period, a warning will be printed with information about which tasks failed to reset the TWDT in time and which -tasks are currently running on the ESP32 CPUs and. +tasks are currently running on the ESP32 CPUs. +And also there is a possibility to redefine the function `esp_task_wdt_isr_user_handler` +in the user code to receive this event. The TWDT is built around the Hardware Watchdog Timer in Timer Group 0. The TWDT can be initialized by calling :cpp:func:`esp_task_wdt_init` which will configure