From 9ac9aa989c89a1d6310160dd408820d1164d4dd7 Mon Sep 17 00:00:00 2001 From: Damien George Date: Mon, 28 Jan 2019 16:16:03 +1100 Subject: [PATCH] esp32/machine_timer: Deinit all active timers on soft reset. Otherwise they will keep triggering the callback and access invalid data on the heap. --- ports/esp32/machine_timer.c | 23 +++++++++++++++++++++++ ports/esp32/main.c | 2 ++ ports/esp32/modmachine.h | 1 + ports/esp32/mpconfigport.h | 3 +++ 4 files changed, 29 insertions(+) diff --git a/ports/esp32/machine_timer.c b/ports/esp32/machine_timer.c index 7dca9e0143..081a46b9c1 100644 --- a/ports/esp32/machine_timer.c +++ b/ports/esp32/machine_timer.c @@ -56,10 +56,14 @@ typedef struct _machine_timer_obj_t { mp_obj_t callback; intr_handle_t handle; + + struct _machine_timer_obj_t *next; } machine_timer_obj_t; const mp_obj_type_t machine_timer_type; +STATIC void machine_timer_disable(machine_timer_obj_t *self); + STATIC esp_err_t check_esp_err(esp_err_t code) { if (code) { mp_raise_OSError(code); @@ -68,6 +72,12 @@ STATIC esp_err_t check_esp_err(esp_err_t code) { return code; } +void machine_timer_deinit_all(void) { + while (MP_STATE_PORT(machine_timer_obj_head) != NULL) { + machine_timer_disable(MP_STATE_PORT(machine_timer_obj_head)); + } +} + STATIC void machine_timer_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { machine_timer_obj_t *self = self_in; @@ -88,6 +98,7 @@ STATIC mp_obj_t machine_timer_make_new(const mp_obj_type_t *type, size_t n_args, self->group = (mp_obj_get_int(args[0]) >> 1) & 1; self->index = mp_obj_get_int(args[0]) & 1; + self->next = NULL; return self; } @@ -98,6 +109,14 @@ STATIC void machine_timer_disable(machine_timer_obj_t *self) { esp_intr_free(self->handle); self->handle = NULL; } + + // Remove the timer from the linked-list of active timers + for (machine_timer_obj_t **t = &MP_STATE_PORT(machine_timer_obj_head); *t; t = &(*t)->next) { + if (*t == self) { + *t = (*t)->next; + break; + } + } } STATIC void machine_timer_isr(void *self_in) { @@ -131,6 +150,10 @@ STATIC void machine_timer_enable(machine_timer_obj_t *self) { check_esp_err(timer_enable_intr(self->group, self->index)); check_esp_err(timer_isr_register(self->group, self->index, machine_timer_isr, (void*)self, TIMER_FLAGS, &self->handle)); check_esp_err(timer_start(self->group, self->index)); + + // Add the timer to the linked-list of active timers + self->next = MP_STATE_PORT(machine_timer_obj_head); + MP_STATE_PORT(machine_timer_obj_head) = self; } STATIC mp_obj_t machine_timer_init_helper(machine_timer_obj_t *self, mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { diff --git a/ports/esp32/main.c b/ports/esp32/main.c index 9ca88699d2..01d22d3e75 100644 --- a/ports/esp32/main.c +++ b/ports/esp32/main.c @@ -109,6 +109,8 @@ soft_reset: } } + machine_timer_deinit_all(); + #if MICROPY_PY_THREAD mp_thread_deinit(); #endif diff --git a/ports/esp32/modmachine.h b/ports/esp32/modmachine.h index c8513a4711..b65b427b4e 100644 --- a/ports/esp32/modmachine.h +++ b/ports/esp32/modmachine.h @@ -22,5 +22,6 @@ extern const mp_obj_type_t machine_rtc_type; void machine_pins_init(void); void machine_pins_deinit(void); +void machine_timer_deinit_all(void); #endif // MICROPY_INCLUDED_ESP32_MODMACHINE_H diff --git a/ports/esp32/mpconfigport.h b/ports/esp32/mpconfigport.h index 0f8deb11c3..a70f6d3180 100644 --- a/ports/esp32/mpconfigport.h +++ b/ports/esp32/mpconfigport.h @@ -210,9 +210,12 @@ extern const struct _mp_obj_module_t mp_module_onewire; #define MP_STATE_PORT MP_STATE_VM +struct _machine_timer_obj_t; + #define MICROPY_PORT_ROOT_POINTERS \ const char *readline_hist[8]; \ mp_obj_t machine_pin_irq_handler[40]; \ + struct _machine_timer_obj_t *machine_timer_obj_head; \ // type definitions for the specific machine