esp32/machine_wdt: Allow feeding WDT from threads.

This changes the ESP32 WDT implementation to use a custom handle so that it
becomes possible to reset the WDT from a thread.

By default esp_task_wdt_add subscribes the task_id of the current task.
That means that if we're running in a different task we are unable to reset
the WDT, which prevents feeding the WDT from a thread directly, or even
from a timer (which may randomly run in a different task when there's
multiple threads).

As an added bonus, the name we set makes the error clearly specify that it
was the user-specified WDT that reset the chip.

Signed-off-by: Daniël van de Giessen <daniel@dvdgiessen.nl>
This commit is contained in:
Daniël van de Giessen 2023-07-04 15:35:29 +02:00 committed by Damien George
parent 1bde5f3316
commit 52dc48b2a0

View File

@ -37,9 +37,12 @@ const mp_obj_type_t machine_wdt_type;
typedef struct _machine_wdt_obj_t {
mp_obj_base_t base;
esp_task_wdt_user_handle_t twdt_user_handle;
} machine_wdt_obj_t;
STATIC machine_wdt_obj_t wdt_default = {{&machine_wdt_type}};
STATIC machine_wdt_obj_t wdt_default = {
{&machine_wdt_type}, 0
};
STATIC mp_obj_t machine_wdt_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
enum { ARG_id, ARG_timeout };
@ -68,14 +71,22 @@ STATIC mp_obj_t machine_wdt_make_new(const mp_obj_type_t *type_in, size_t n_args
mp_raise_OSError(rs_code);
}
esp_task_wdt_add(NULL);
if (wdt_default.twdt_user_handle == NULL) {
rs_code = esp_task_wdt_add_user("mpy_machine_wdt", &wdt_default.twdt_user_handle);
if (rs_code != ESP_OK) {
mp_raise_OSError(rs_code);
}
}
return &wdt_default;
}
STATIC mp_obj_t machine_wdt_feed(mp_obj_t self_in) {
(void)self_in;
esp_task_wdt_reset();
mp_int_t rs_code = esp_task_wdt_reset_user(wdt_default.twdt_user_handle);
if (rs_code != ESP_OK) {
mp_raise_OSError(rs_code);
}
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_wdt_feed_obj, machine_wdt_feed);