1 /*
2  * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #pragma once
8 
9 #include <stdbool.h>
10 #include "freertos/FreeRTOS.h"
11 #include "freertos/task.h"
12 #include "esp_err.h"
13 
14 #ifdef __cplusplus
15 extern "C" {
16 #endif
17 
18 /**
19  * @brief Task Watchdog Timer (TWDT) configuration structure
20  */
21 typedef struct {
22     uint32_t timeout_ms;        /**< TWDT timeout duration in milliseconds */
23     uint32_t idle_core_mask;    /**< Mask of the cores who's idle task should be subscribed on initialization */
24     bool trigger_panic;         /**< Trigger panic when timeout occurs */
25 } esp_task_wdt_config_t;
26 
27 /**
28  * @brief Task Watchdog Timer (TWDT) user handle
29  */
30 typedef struct esp_task_wdt_user_handle_s * esp_task_wdt_user_handle_t;
31 
32 /**
33  * @brief  Initialize the Task Watchdog Timer (TWDT)
34  *
35  * This function configures and initializes the TWDT. This function will subscribe the idle tasks if
36  * configured to do so. For other tasks, users can subscribe them using esp_task_wdt_add() or esp_task_wdt_add_user().
37  * This function won't start the timer if no task have been registered yet.
38  *
39  * @note esp_task_wdt_init() must only be called after the scheduler is started. Moreover, it must not be called by
40  *       multiple tasks simultaneously.
41  * @param[in] config Configuration structure
42  * @return
43  *  - ESP_OK: Initialization was successful
44  *  - ESP_ERR_INVALID_STATE: Already initialized
45  *  - Other: Failed to initialize TWDT
46  */
47 esp_err_t esp_task_wdt_init(const esp_task_wdt_config_t *config);
48 
49 /**
50  * @brief Reconfigure the Task Watchdog Timer (TWDT)
51  *
52  * The function reconfigures the running TWDT. It must already be initialized when this function is called.
53  *
54  * @note esp_task_wdt_reconfigure() must not be called by multiple tasks simultaneously.
55  *
56  * @param[in] config Configuration structure
57  *
58  * @return
59  *  - ESP_OK: Reconfiguring was successful
60  *  - ESP_ERR_INVALID_STATE: TWDT not initialized yet
61  *  - Other: Failed to initialize TWDT
62  */
63 esp_err_t esp_task_wdt_reconfigure(const esp_task_wdt_config_t *config);
64 
65 /**
66  * @brief   Deinitialize the Task Watchdog Timer (TWDT)
67  *
68  * This function will deinitialize the TWDT, and unsubscribe any idle tasks. Calling this function whilst other tasks
69  * are still subscribed to the TWDT, or when the TWDT is already deinitialized, will result in an error code being
70  * returned.
71  *
72  * @note esp_task_wdt_deinit() must not be called by multiple tasks simultaneously.
73  * @return
74  *  - ESP_OK: TWDT successfully deinitialized
75  *  - Other: Failed to deinitialize TWDT
76  */
77 esp_err_t esp_task_wdt_deinit(void);
78 
79 /**
80  * @brief Subscribe a task to the Task Watchdog Timer (TWDT)
81  *
82  * This function subscribes a task to the TWDT. Each subscribed task must periodically call esp_task_wdt_reset() to
83  * prevent the TWDT from elapsing its timeout period. Failure to do so will result in a TWDT timeout.
84  *
85  * @param task_handle Handle of the task. Input NULL to subscribe the current running task to the TWDT
86  * @return
87  *  - ESP_OK: Successfully subscribed the task to the TWDT
88  *  - Other: Failed to subscribe task
89  */
90 esp_err_t esp_task_wdt_add(TaskHandle_t task_handle);
91 
92 /**
93  * @brief Subscribe a user to the Task Watchdog Timer (TWDT)
94  *
95  * This function subscribes a user to the TWDT. A user of the TWDT is usually a function that needs to run
96  * periodically. Each subscribed user must periodically call esp_task_wdt_reset_user() to prevent the TWDT from elapsing
97  * its timeout period. Failure to do so will result in a TWDT timeout.
98  *
99  * @param[in] user_name String to identify the user
100  * @param[out] user_handle_ret Handle of the user
101  * @return
102  *  - ESP_OK: Successfully subscribed the user to the TWDT
103  *  - Other: Failed to subscribe user
104  */
105 esp_err_t esp_task_wdt_add_user(const char *user_name, esp_task_wdt_user_handle_t *user_handle_ret);
106 
107 /**
108  * @brief Reset the Task Watchdog Timer (TWDT) on behalf of the currently running task
109  *
110  * This function will reset the TWDT on behalf of the currently running task. Each subscribed task must periodically
111  * call this function to prevent the TWDT from timing out. If one or more subscribed tasks fail to reset the TWDT on
112  * their own behalf, a TWDT timeout will occur.
113  *
114  * @return
115  *  - ESP_OK: Successfully reset the TWDT on behalf of the currently running task
116  *  - Other: Failed to reset
117  */
118 esp_err_t esp_task_wdt_reset(void);
119 
120 /**
121  * @brief Reset the Task Watchdog Timer (TWDT) on behalf of a user
122  *
123  * This function will reset the TWDT on behalf of a user. Each subscribed user must periodically call this function to
124  * prevent the TWDT from timing out. If one or more subscribed users fail to reset the TWDT on their own behalf, a TWDT
125  * timeout will occur.
126  *
127  * @param[in] user_handle User handle
128  *  - ESP_OK: Successfully reset the TWDT on behalf of the user
129  *  - Other: Failed to reset
130  */
131 esp_err_t esp_task_wdt_reset_user(esp_task_wdt_user_handle_t user_handle);
132 
133 /**
134  * @brief Unsubscribes a task from the Task Watchdog Timer (TWDT)
135  *
136  * This function will unsubscribe a task from the TWDT. After being unsubscribed, the task should no longer call
137  * esp_task_wdt_reset().
138  *
139  * @param[in] task_handle Handle of the task. Input NULL to unsubscribe the current running task.
140  * @return
141  *  - ESP_OK: Successfully unsubscribed the task from the TWDT
142  *  - Other: Failed to unsubscribe task
143  */
144 esp_err_t esp_task_wdt_delete(TaskHandle_t task_handle);
145 
146 /**
147  * @brief Unsubscribes a user from the Task Watchdog Timer (TWDT)
148  *
149  * This function will unsubscribe a user from the TWDT. After being unsubscribed, the user should no longer call
150  * esp_task_wdt_reset_user().
151  *
152  * @param[in] user_handle User handle
153  * @return
154  *  - ESP_OK: Successfully unsubscribed the user from the TWDT
155  *  - Other: Failed to unsubscribe user
156  */
157 esp_err_t esp_task_wdt_delete_user(esp_task_wdt_user_handle_t user_handle);
158 
159 /**
160  * @brief Query whether a task is subscribed to the Task Watchdog Timer (TWDT)
161  *
162  * This function will query whether a task is currently subscribed to the TWDT, or whether the TWDT is initialized.
163  *
164  * @param[in] task_handle Handle of the task. Input NULL to query the current running task.
165  * @return:
166  *  - ESP_OK: The task is currently subscribed to the TWDT
167  *  - ESP_ERR_NOT_FOUND: The task is not subscribed
168  *  - ESP_ERR_INVALID_STATE: TWDT was never initialized
169  */
170 esp_err_t esp_task_wdt_status(TaskHandle_t task_handle);
171 
172 /**
173  * @brief User ISR callback placeholder
174  *
175  * This function is called by task_wdt_isr function (ISR for when TWDT times out). It can be defined in user code to
176  * handle TWDT events.
177  *
178  * @note It has the same limitations as the interrupt function. Do not use ESP_LOGx functions inside.
179  */
180 void __attribute__((weak)) esp_task_wdt_isr_user_handler(void);
181 
182 #ifdef __cplusplus
183 }
184 #endif
185