mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-02 12:14:32 +02:00
Merge branch 'feature/task_wdt_add_timestamp' into 'master'
esp32/task_wdt: Add timestamp to message isr_twdt See merge request idf/esp-idf!3053
This commit is contained in:
@@ -37,6 +37,8 @@
|
|||||||
#include "esp_task_wdt.h"
|
#include "esp_task_wdt.h"
|
||||||
#include "esp_system_internal.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'
|
//Assertion macro where, if 'cond' is false, will exit the critical section and return 'ret'
|
||||||
#define ASSERT_EXIT_CRIT_RETURN(cond, ret) ({ \
|
#define ASSERT_EXIT_CRIT_RETURN(cond, ret) ({ \
|
||||||
if(!(cond)){ \
|
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
|
* ISR for when TWDT times out. Checks for which tasks have not reset. Also
|
||||||
* triggers panic if configured to do so
|
* triggers panic if configured to do so
|
||||||
@@ -131,7 +144,7 @@ static void task_wdt_isr(void *arg)
|
|||||||
TIMERG0.wdt_wprotect=0;
|
TIMERG0.wdt_wprotect=0;
|
||||||
//Acknowledge interrupt
|
//Acknowledge interrupt
|
||||||
TIMERG0.int_clr_timers.wdt=1;
|
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,
|
//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
|
//something bad already happened and reporting this is considered more important
|
||||||
//than the badness caused by a spinlock here.
|
//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);
|
ASSERT_EXIT_CRIT_RETURN((twdt_config->list != NULL), VOID_RETURN);
|
||||||
|
|
||||||
//Watchdog got triggered because at least one task did not reset in time.
|
//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) {
|
for (twdttask=twdt_config->list; twdttask!=NULL; twdttask=twdttask->next) {
|
||||||
if (!twdttask->has_reset) {
|
if (!twdttask->has_reset) {
|
||||||
cpu=xTaskGetAffinity(twdttask->task_handle)==0?DRAM_STR("CPU 0"):DRAM_STR("CPU 1");
|
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");
|
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; x<portNUM_PROCESSORS; x++) {
|
for (int x=0; x<portNUM_PROCESSORS; x++) {
|
||||||
ets_printf("CPU %d: %s\n", x, pcTaskGetTaskName(xTaskGetCurrentTaskHandleForCPU(x)));
|
ESP_EARLY_LOGE(TAG, "CPU %d: %s", x, pcTaskGetTaskName(xTaskGetCurrentTaskHandleForCPU(x)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
esp_task_wdt_isr_user_handler();
|
||||||
if (twdt_config->panic){ //Trigger Panic if configured to do so
|
if (twdt_config->panic){ //Trigger Panic if configured to do so
|
||||||
ets_printf("Aborting.\n");
|
ESP_EARLY_LOGE(TAG, "Aborting.");
|
||||||
portEXIT_CRITICAL(&twdt_spinlock);
|
portEXIT_CRITICAL(&twdt_spinlock);
|
||||||
esp_reset_reason_set_hint(ESP_RST_TASK_WDT);
|
esp_reset_reason_set_hint(ESP_RST_TASK_WDT);
|
||||||
abort();
|
abort();
|
||||||
|
@@ -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
|
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
|
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
|
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
|
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
|
can be initialized by calling :cpp:func:`esp_task_wdt_init` which will configure
|
||||||
|
Reference in New Issue
Block a user