[SOLVED] Best practice to avoid wdt trigger
Posted: Sun Dec 18, 2022 3:14 pm
Hello! I'm working with a simple piece of code.
Pressing a button I'm able to toggle a led, with task_led().
The pressure of the button is made by polling the status of the pin made by task_debounce (), and there is also a debounce strategy.
Running this piece of code on an ESP32, I get this error message:
What I ask is: what is the best practice to avoid this type of error? I don't want to increase the WDT time, neither insert delays or interrupts. I want simply polling the button.
I thought that taskYIELD() suffices, but it doesn't...
Thank you
Pressing a button I'm able to toggle a led, with task_led().
The pressure of the button is made by polling the status of the pin made by task_debounce (), and there is also a debounce strategy.
Code: Select all
#include <freertos/FreeRTOS.h>
#include <freertos/queue.h>
#include <freertos/task.h>
#include <stdint.h>
#include "driver/gpio.h"
#define GPIO_LED 15
#define GPIO_BUTTON 21
static QueueHandle_t queue = NULL;
static void
task_debounce (void * argp)
{
uint32_t level = 0;
uint32_t state = 0;
uint32_t last = 0xFFFFFFFF;
uint32_t mask = 0x7FFFFFFF;
bool event = false;
for (;;)
{
level = gpio_get_level(GPIO_BUTTON);
state = (state << 1) | level;
if (((state & mask) == mask) || ((state & mask) == 0))
{
if (level != last)
{
event = (bool) level;
if (pdPASS == xQueueSendToBack(queue, &event, 1))
{
last = level;
}
}
}
taskYIELD();
}
}
static void
task_led (void * argp)
{
BaseType_t st;
bool event;
bool led = false;
(void) gpio_set_level(GPIO_LED, led);
for (;;)
{
st = xQueueReceive(queue, &event, portMAX_DELAY);
assert(pdPASS == st);
if (true == event)
{
led ^= true;
gpio_set_level(GPIO_LED, led);
}
}
}
void
app_main (void)
{
int app_cpu = xPortGetCoreID();
TaskHandle_t h_task = NULL;
BaseType_t rc = 0;
vTaskDelay(pdMS_TO_TICKS(2000));
queue = xQueueCreate(40, sizeof(bool));
assert(queue);
gpio_pad_select_gpio(GPIO_LED);
(void) gpio_set_direction(GPIO_LED, GPIO_MODE_OUTPUT);
gpio_pad_select_gpio(GPIO_BUTTON);
(void) gpio_set_direction(GPIO_BUTTON, GPIO_MODE_INPUT);
(void) gpio_set_pull_mode(GPIO_BUTTON, GPIO_PULLUP_ONLY);
rc = xTaskCreatePinnedToCore(task_debounce, "debounce", 2048, NULL, 1, &h_task, app_cpu);
assert(pdPASS == rc);
assert(h_task);
rc = xTaskCreatePinnedToCore(task_led, "led", 2048, NULL, 1, &h_task, app_cpu);
assert(pdPASS == rc);
assert(h_task);
}
Code: Select all
E (269269) task_wdt: Print CPU 1 backtrace
Backtrace:0x40084031:0x3FFB11800x40082665:0x3FFB11A0 0x40085174:0x3FFB7960 0x400D4BF9:0x3FFB7980 0x40087ACD:0x3FFB79B0
0x40084031: esp_crosscore_isr at C:/esp/esp-idf/components/esp_system/crosscore_int.c:92
0x40082665: _xt_lowint1 at C:/esp/esp-idf/components/freertos/port/xtensa/xtensa_vectors.S:1111
0x40085174: _frxt_dispatch at C:/esp/esp-idf/components/freertos/port/xtensa/portasm.S:465
0x400d4bf9: task_debounce at C:\Users\Filippo\Documents\Espressif\ch3_queue_press\build/../main/main.c:39
0x40087acd: vPortTaskWrapper at C:/esp/esp-idf/components/freertos/port/xtensa/port.c:131
E (274269) task_wdt: Task watchdog got triggered. The following tasks did not reset the watchdog in time:
E (274269) task_wdt: - IDLE (CPU 1)
E (274269) task_wdt: Tasks currently running:
E (274269) task_wdt: CPU 0: IDLE
E (274269) task_wdt: CPU 1: debounce
E (274269) task_wdt: Print CPU 0 (current core) backtrace
Backtrace:0x400D74AF:0x3FFB0B800x40082665:0x3FFB0BA0 0x400E5087:0x3FFB69C0 0x400D1923:0x3FFB69E0 0x40086566:0x3FFB6A00 0x40087ACD:0x3FFB6A20
0x400d74af: task_wdt_isr at C:/esp/esp-idf/components/esp_system/task_wdt.c:183 (discriminator 3)
0x40082665: _xt_lowint1 at C:/esp/esp-idf/components/freertos/port/xtensa/xtensa_vectors.S:1111
0x400e5087: cpu_ll_waiti at C:/esp/esp-idf/components/hal/esp32/include/hal/cpu_ll.h:183
(inlined by) esp_pm_impl_waiti at C:/esp/esp-idf/components/esp_pm/pm_impl.c:837
0x400d1923: esp_vApplicationIdleHook at C:/esp/esp-idf/components/esp_system/freertos_hooks.c:63
0x40086566: prvIdleTask at C:/esp/esp-idf/components/freertos/tasks.c:3974 (discriminator 1)
0x40087acd: vPortTaskWrapper at C:/esp/esp-idf/components/freertos/port/xtensa/port.c:131
E (274269) task_wdt: Print CPU 1 backtrace
Backtrace:0x40084031:0x3FFB11800x40082665:0x3FFB11A0 0x40085174:0x3FFB7960 0x400D4BF9:0x3FFB7980 0x40087ACD:0x3FFB79B0
0x40084031: esp_crosscore_isr at C:/esp/esp-idf/components/esp_system/crosscore_int.c:92
0x40082665: _xt_lowint1 at C:/esp/esp-idf/components/freertos/port/xtensa/xtensa_vectors.S:1111
0x40085174: _frxt_dispatch at C:/esp/esp-idf/components/freertos/port/xtensa/portasm.S:465
0x400d4bf9: task_debounce at C:\Users\Filippo\Documents\Espressif\ch3_queue_press\build/../main/main.c:39
0x40087acd: vPortTaskWrapper at C:/esp/esp-idf/components/freertos/port/xtensa/port.c:131
I thought that taskYIELD() suffices, but it doesn't...
Thank you