From 4fc84306a25d7b51aeb5b08de4940ca6bd42ba2e Mon Sep 17 00:00:00 2001 From: Konstantin Kondrashov Date: Mon, 3 Sep 2018 13:33:12 +0800 Subject: [PATCH 1/2] esp32/task_wdt: Add esp_task_wdt_isr_user_handler function Added esp_task_wdt_isr_user_handler function to receive twdt events in the user code. Closes https://github.com/espressif/esp-idf/issues/2270 --- components/esp32/task_wdt.c | 12 ++++++++++++ docs/en/api-reference/system/wdts.rst | 4 +++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/components/esp32/task_wdt.c b/components/esp32/task_wdt.c index fb10aac05..2da2156ac 100644 --- a/components/esp32/task_wdt.c +++ b/components/esp32/task_wdt.c @@ -116,6 +116,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 @@ -153,6 +164,7 @@ static void task_wdt_isr(void *arg) ets_printf("CPU %d: %s\n", x, pcTaskGetTaskName(xTaskGetCurrentTaskHandleForCPU(x))); } + esp_task_wdt_isr_user_handler(); if (twdt_config->panic){ //Trigger Panic if configured to do so ets_printf("Aborting.\n"); portEXIT_CRITICAL(&twdt_spinlock); 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 From 26ee0f5203cb84e1a566226fb31c5437a2a19476 Mon Sep 17 00:00:00 2001 From: Konstantin Kondrashov Date: Tue, 21 Aug 2018 19:47:21 +0800 Subject: [PATCH 2/2] esp32/task_wdt: Add timestamp to message isr_twdt Closes https://github.com/espressif/esp-idf/issues/2270 --- components/esp32/task_wdt.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/components/esp32/task_wdt.c b/components/esp32/task_wdt.c index 2da2156ac..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)){ \ @@ -142,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. @@ -151,22 +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();