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
1 changed files with 14 additions and 3 deletions

View File

@ -37,9 +37,12 @@ const mp_obj_type_t machine_wdt_type;
typedef struct _machine_wdt_obj_t { typedef struct _machine_wdt_obj_t {
mp_obj_base_t base; mp_obj_base_t base;
esp_task_wdt_user_handle_t twdt_user_handle;
} machine_wdt_obj_t; } 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) { 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 }; 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); 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; return &wdt_default;
} }
STATIC mp_obj_t machine_wdt_feed(mp_obj_t self_in) { STATIC mp_obj_t machine_wdt_feed(mp_obj_t self_in) {
(void)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; return mp_const_none;
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_wdt_feed_obj, machine_wdt_feed); STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_wdt_feed_obj, machine_wdt_feed);