wdts.rst 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. Watchdogs
  2. =========
  3. Overview
  4. --------
  5. The ESP-IDF has support for two types of watchdogs: The Interrupt Watchdog Timer
  6. and the Task Watchdog Timer (TWDT). The Interrupt Watchdog Timer and the TWDT
  7. can both be enabled using :ref:`project-configuration-menu`, however the TWDT can also be
  8. enabled during runtime. The Interrupt Watchdog is responsible for detecting
  9. instances where FreeRTOS task switching is blocked for a prolonged period of
  10. time. The TWDT is responsible for detecting instances of tasks running without
  11. yielding for a prolonged period.
  12. Interrupt watchdog
  13. ^^^^^^^^^^^^^^^^^^
  14. The interrupt watchdog makes sure the FreeRTOS task switching interrupt isn't blocked for a long time. This
  15. is bad because no other tasks, including potentially important ones like the WiFi task and the idle task,
  16. can't get any CPU runtime. A blocked task switching interrupt can happen because a program runs into an
  17. infinite loop with interrupts disabled or hangs in an interrupt.
  18. The default action of the interrupt watchdog is to invoke the panic handler. causing a register dump and an opportunity
  19. for the programmer to find out, using either OpenOCD or gdbstub, what bit of code is stuck with interrupts
  20. disabled. Depending on the configuration of the panic handler, it can also blindly reset the CPU, which may be
  21. preferred in a production environment.
  22. The interrupt watchdog is built around the hardware watchdog in timer group 1. If this watchdog for some reason
  23. cannot execute the NMI handler that invokes the panic handler (e.g. because IRAM is overwritten by garbage),
  24. it will hard-reset the SOC.
  25. Task Watchdog Timer
  26. ^^^^^^^^^^^^^^^^^^^
  27. The Task Watchdog Timer (TWDT) is responsible for detecting instances of tasks
  28. running for a prolonged period of time without yielding. This is a symptom of
  29. CPU starvation and is usually caused by a higher priority task looping without
  30. yielding to a lower-priority task thus starving the lower priority task from
  31. CPU time. This can be an indicator of poorly written code that spinloops on a
  32. peripheral, or a task that is stuck in an infinite loop.
  33. By default the TWDT will watch the Idle Tasks of each CPU, however any task can
  34. elect to be watched by the TWDT. Each watched task must 'reset' the TWDT
  35. periodically to indicate that they have been allocated CPU time. If a task does
  36. not reset within the TWDT timeout period, a warning will be printed with
  37. information about which tasks failed to reset the TWDT in time and which
  38. tasks are currently running on the ESP32 CPUs.
  39. And also there is a possibility to redefine the function `esp_task_wdt_isr_user_handler`
  40. in the user code to receive this event.
  41. The TWDT is built around the Hardware Watchdog Timer in Timer Group 0. The TWDT
  42. can be initialized by calling :cpp:func:`esp_task_wdt_init` which will configure
  43. the hardware timer. A task can then subscribe to the TWDT using
  44. :cpp:func:`esp_task_wdt_add` in order to be watched. Each subscribed task must
  45. periodically call :cpp:func:`esp_task_wdt_reset` to reset the TWDT. Failure by
  46. any subscribed tasks to periodically call :cpp:func:`esp_task_wdt_reset`
  47. indicates that one or more tasks have been starved of CPU time or are stuck in a
  48. loop somewhere.
  49. A watched task can be unsubscribed from the TWDT using
  50. :cpp:func:`esp_task_wdt_delete()`. A task that has been unsubscribed should no
  51. longer call :cpp:func:`esp_task_wdt_reset`. Once all tasks have unsubscribed
  52. form the TWDT, the TWDT can be deinitialized by calling
  53. :cpp:func:`esp_task_wdt_deinit()`.
  54. By default :ref:`CONFIG_ESP_TASK_WDT` in :ref:`project-configuration-menu` be enabled causing
  55. the TWDT to be initialized automatically during startup. Likewise
  56. :ref:`CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0` and
  57. :ref:`CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1` are also enabled by default causing
  58. the two Idle Tasks to be subscribed to the TWDT during startup.
  59. JTAG and watchdogs
  60. ^^^^^^^^^^^^^^^^^^
  61. While debugging using OpenOCD, the CPUs will be halted every time a breakpoint
  62. is reached. However if the watchdog timers continue to run when a breakpoint is
  63. encountered, they will eventually trigger a reset making it very difficult to
  64. debug code. Therefore OpenOCD will disable the hardware timers of both the
  65. interrupt and task watchdogs at every breakpoint. Moreover, OpenOCD will not
  66. reenable them upon leaving the breakpoint. This means that interrupt watchdog
  67. and task watchdog functionality will essentially be disabled. No warnings or
  68. panics from either watchdogs will be generated when the ESP32 is connected to
  69. OpenOCD via JTAG.
  70. Interrupt Watchdog API Reference
  71. --------------------------------
  72. Header File
  73. ^^^^^^^^^^^
  74. * :component_file:`esp32/include/esp_int_wdt.h`
  75. Functions
  76. ---------
  77. .. doxygenfunction:: esp_int_wdt_init
  78. Task Watchdog API Reference
  79. ----------------------------
  80. A full example using the Task Watchdog is available in esp-idf: :example:`system/task_watchdog`
  81. .. include:: /_build/inc/esp_task_wdt.inc