Перейти к содержанию

Почему ESP32 пишет «Task watchdog got triggered»?

Обновлено Редакция GAW

У ESP-IDF два программных сторожа. Сторож прерываний (IWDT) следит, чтобы обработчики прерываний не блокировались надолго. Сторож задач (TWDT) по умолчанию наблюдает за задачами простоя IDLE каждого ядра: если IDLE долго не получает процессор, значит, какая-то задача крутится, не уступая его.

Два сторожа ESP-IDF

Сторож задач (TWDT)Сторож прерываний (IWDT)
Что ловитзадача не уступает процессорзаблокированы прерывания
Тайм-аут по умолчанию5 с300 мс (800 мс с PSRAM)
СообщениеTask watchdog got triggeredGuru Meditation… Interrupt wdt timeout on CPU0
Действие (ESP-IDF по умолчанию)предупреждение и трассировка; паника — с CONFIG_ESP_TASK_WDT_PANICпаника, дальше — по CONFIG_ESP_SYSTEM_PANIC

Типичная ошибка

// The task spins and never yields: the IDLE task starves
while (!data_ready) { }

// Fixed: give the CPU away while waiting
while (!data_ready) { vTaskDelay(pdMS_TO_TICKS(10)); }

Пустой цикл ожидания флага, долгий опрос периферии или тяжёлый расчёт без пауз держат ядро. Задача с приоритетом выше IDLE не даёт ей выполниться, и через 5 секунд сторож печатает предупреждение и трассировку вызовов.

Как исправить

  1. Ожидание — через vTaskDelay(), очереди или семафоры, а не пустой цикл.
  2. Долгий расчёт — разбить на части с паузами или выполнять в задаче с низким приоритетом.
  3. Если задача должна работать долго, подпишите её на сторож esp_task_wdt_add() и вызывайте esp_task_wdt_reset() из неё самой.

Зачем вообще нужен сторожевой таймер, разобрано в словаре, где его сбрасывать — в статье «Стратегии сторожевого таймера», а разбор других аварийных сообщений — в ответе «Guru Meditation Error на ESP32».

Похожие вопросы

Можно ли просто увеличить тайм-аут?

Можно, Espressif так и советует для долгих операций вроде стирания большой области флеш-памяти: CONFIG_ESP_TASK_WDT_TIMEOUT_S настраивается от 1 до 60 с. Но если задача висит в бесконечном цикле, больший тайм-аут лишь отсрочит сообщение.

Чем «Interrupt wdt timeout» отличается от Task watchdog?

Сторож прерываний срабатывает, когда прерывания заблокированы дольше 300 мс по умолчанию: слишком длинная критическая секция, запрет прерываний или тяжёлый обработчик. Это паника, а что будет дальше — перезагрузка, остановка или запуск GDB Stub, — задаёт CONFIG_ESP_SYSTEM_PANIC (по умолчанию печать регистров и перезагрузка). Task watchdog следит за задачами и с настройками ESP-IDF по умолчанию только предупреждает.

Почему под отладчиком сторож не срабатывает?

OpenOCD при каждой точке останова отключает аппаратные таймеры обоих сторожей и не включает их обратно. Поэтому под JTAG предупреждений нет, а без отладчика они появляются.

Источники

  1. Espressif. ESP-IDF Programming Guide v5.4 (ESP32): Watchdogs — IWDT следит, чтобы прерывания не блокировались (запрет прерываний, длинные критические секции, ISR), при срабатывании — паника «Interrupt wdt timeout on CPU0/CPU1»; TWDT следит за задачами IDLE каждого ядра и подписанными задачами, выявляет задачи, которые долго не уступают процессор; esp_task_wdt_add/reset/delete; по умолчанию при срабатывании TWDT печатаются предупреждение и трассировка, паника и сброс — с CONFIG_ESP_TASK_WDT_PANIC; стирание больших областей флеш-памяти может вызвать срабатывание — увеличить тайм-аут; OpenOCD при отладке отключает оба сторожа
  2. Espressif. ESP-IDF v5.4, components/esp_system/Kconfig — ESP_TASK_WDT_TIMEOUT_S — 1–60 с, по умолчанию 5; ESP_TASK_WDT_PANIC — по умолчанию выключен; ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0 — по умолчанию включён; ESP_INT_WDT_TIMEOUT_MS — по умолчанию 300 мс (800 мс с PSRAM на ESP32), 10–10000 мс; ESP_SYSTEM_PANIC — по умолчанию PRINT_REBOOT

Нашли ошибку?