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

Interrupt Watchdog Timer (IWDT) в ESP-IDF

«Interrupt wdt timeout on CPU0» в логе ESP32 означает не зависшую задачу, а заблокированные прерывания: кто-то слишком долго сидел в критической секции или в обработчике, и тик FreeRTOS не смог выполниться. Это ловит Interrupt Watchdog.

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

Interrupt Watchdog Timer (IWDT, сторожевой таймер прерываний) — таймер ESP-IDF, который проверяет, что на каждом ядре ESP32 вовремя выполняется прерывание тика FreeRTOS. Если тик на ядре не выполнился дольше таймаута, значит, прерывания на этом ядре заблокированы: кто-то их запретил, слишком долго сидит в критической секции или в обработчике. По умолчанию IWDT вызывает обработчик паники с причиной «Interrupt wdt timeout on CPU0» (или CPU1); если обработчик паники не смог выполниться, вторая стадия таймера делает аппаратный сброс.

Что ловит

По ESP-IDF выполнение обработчиков прерываний блокируют три вещи:

  • запрет прерываний;
  • критические секции — они тоже запрещают прерывания;
  • другие обработчики того же или более высокого приоритета, которые не дают выполниться прерываниям ниже.

Заблокированные прерывания не только увеличивают задержку обработки, но и останавливают переключение задач — оно выполняется из прерывания. Отсюда и выбор «кормушки»: IWDT сбрасывается самим прерыванием тика FreeRTOS на каждом ядре, аппаратно это MWDT группы таймеров 1.

Параметры

ПараметрЗначениеОпция
Включёнда, по умолчаниюCONFIG_ESP_INT_WDT
Таймаут10–10000 мс; с PSRAM по умолчанию 800 мсCONFIG_ESP_INT_WDT_TIMEOUT_MS
Минимумне меньше двух периодов тика: при тике 10 мс — больше 20 мсзависит от CONFIG_FREERTOS_HZ
Второе ядроследить за тиком на CPU1CONFIG_ESP_INT_WDT_CHECK_CPU1
При срабатыванииобработчик паники, затем аппаратный сброс второй стадиейCONFIG_ESP_SYSTEM_PANIC

С поддержкой PSRAM таймаут по умолчанию выше, потому что критическая секция или прерывание, перебирающие большой объём внешней памяти, длятся дольше. Справочник опций ESP-IDF v6.1 для ESP32 приводит значение по умолчанию только для этого случая — 800 мс при CONFIG_SPIRAM.

Как лечить таймаут

ESP-IDF советует сначала править код и лишь потом трогать таймаут:

  1. Критические секции — как можно короче, всё некритичное выносить наружу.
  2. В обработчике прерывания — минимум вычислений; данные отдавать задаче через очередь и обрабатывать там.
  3. Ни в критической секции, ни в обработчике не ждать другого события.
  4. Если ускорить код невозможно — увеличить CONFIG_ESP_INT_WDT_TIMEOUT_MS.

В логе паники при таймауте IWDT, помимо обычного дампа регистров, могут печататься регистры EPC1–EPC4 и регистры с backtrace кода, выполнявшегося на другом ядре. При отладке через OpenOCD таймер не сработает: на первой точке останова OpenOCD отключает IWDT вместе с Task Watchdog и обратно не включает. Общие принципы — что сторожевой таймер ловит, а что нет, и где его сбрасывать — в термине watchdog и статье «Сторожевой таймер: где его сбрасывать».

Частые вопросы

Чем Interrupt Watchdog отличается от Task Watchdog?

Они ловят разные вещи. Task Watchdog замечает задачу, которая не уступает процессор, — прерывания при этом работают, тик идёт, просто idle-задача не получает времени; по умолчанию это предупреждение через 5 с. Interrupt Watchdog замечает, что на ядре не выполняется сам тик FreeRTOS, то есть прерывания запрещены или обработчик не возвращается; таймаут измеряется миллисекундами, а по умолчанию срабатывание ведёт в обработчик паники и перезагрузку. Аппаратно это два разных таймера: TWDT — группа 0, IWDT — группа 1.

Почему Interrupt wdt timeout появляется при работе с PSRAM?

ESP-IDF поясняет, что критическая секция или прерывание, которые обращаются к большому объёму PSRAM, могут длиться дольше обычного, поэтому с включённой поддержкой PSRAM таймаут по умолчанию выше: по справочнику опций CONFIG_ESP_INT_WDT_TIMEOUT_MS при CONFIG_SPIRAM равен 800 мс. Если срабатывания всё равно есть, документация советует сначала укоротить критические секции и обработчики, а уже потом поднимать таймаут.

Какой таймаут IWDT можно ставить?

Диапазон опции CONFIG_ESP_INT_WDT_TIMEOUT_MS — от 10 до 10000 мс, но ESP-IDF требует, чтобы значение было как минимум вдвое больше периода тика FreeRTOS: при тике 10 мс (CONFIG_FREERTOS_HZ = 100) — больше 20 мс. Иначе таймер будет срабатывать от обычных задержек между тиками.

Источники

  1. Espressif. ESP-IDF Programming Guide v6.1, ESP32: Watchdogs — Interrupt Watchdog Timer: следит, что обработчики прерываний не блокируются дольше таймаута; блокировать ISR могут запрет прерываний, критические секции (тоже запрещают прерывания), другие ISR того же или более высокого приоритета; блокировка прерываний увеличивает задержку ISR и мешает переключению задач, так как оно выполняется из прерывания; аппаратно — MWDT_WDT группы таймеров 1, кормится прерыванием тика FreeRTOS на каждом ядре: если тик на ядре не выполнился за таймаут, что-то блокирует прерывания на этом ядре; при срабатывании по умолчанию вызывается обработчик паники с причиной «Interrupt wdt timeout on CPU0» или «CPU1»; если обработчик паники не смог выполниться, вторая стадия IWDT делает аппаратный сброс; Configuration: включён по умолчанию (CONFIG_ESP_INT_WDT), таймаут CONFIG_ESP_INT_WDT_TIMEOUT_MS, с поддержкой PSRAM по умолчанию выше, так как критическая секция или прерывание с большим объёмом обращений к PSRAM длится дольше; таймаут должен быть минимум вдвое больше периода тика: при тике 10 мс — больше 20 мс (CONFIG_FREERTOS_HZ); Tuning: критические секции короче, в ISR минимум вычислений, остальное — в задачу через очередь, не ждать событий в ISR и критической секции, иначе увеличить таймаут; JTAG & Watchdogs: OpenOCD отключает IWDT и TWDT на точках останова; Common Error Logs: «Guru Meditation Error: Core 0 panic'ed (Interrupt wdt timeout on CPU0)» с backtrace — сократить ISR или критические секции либо увеличить таймаут
  2. Espressif. ESP-IDF Programming Guide v6.1, ESP32: Configuration Options Reference; Fatal Errors — CONFIG_ESP_INT_WDT: обнаруживает, что прерывание тика FreeRTOS не вызывалось заданное время — задача выключила прерывания и долго не включала или обработчик не вернулся; сначала вызывает обработчик паники, при неудаче сбрасывает SoC; по умолчанию включён; CONFIG_ESP_INT_WDT_TIMEOUT_MS: диапазон 10–10000 мс, значение по умолчанию 800 при CONFIG_SPIRAM; CONFIG_ESP_INT_WDT_CHECK_CPU1 — следить и за тиком на CPU1; Fatal Errors: при таймауте IWDT обработчик паники может дополнительно печатать регистры EPC1–EPC4 и регистры с backtrace кода на другом ядре; причина «Interrupt Watchdog Timeout on CPU0/CPU1» в списке Guru Meditation Errors
Страница помогла?

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