Skip to content

Commit f99cd07

Browse files
committed
esp32/machine_timer: Do not free interrupt from ISR.
esp_intr_free is not safe to call from the timer ISR because it requires the current task (the one the ISR interrupted) to be pinned to the same core as the interrupt was allocated on. Merely disabling the ISR however is safe since that only requires that we're currently running on the same core (which the ISR always is), regardless of the current task. This was causing deadlocks in machine_uart when the ISR happened to interrupt a task that was not pinned to a specific core. Signed-off-by: Daniël van de Giessen <daniel@dvdgiessen.nl>
1 parent 45e4deb commit f99cd07

File tree

1 file changed

+16
-5
lines changed

1 file changed

+16
-5
lines changed

ports/esp32/machine_timer.c

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,13 @@
5050
const mp_obj_type_t machine_timer_type;
5151

5252
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);
53+
static mp_obj_t machine_timer_deinit(mp_obj_t self_in);
5354

5455
void machine_timer_deinit_all(void) {
5556
// Disable, deallocate and remove all timers from list
5657
machine_timer_obj_t **t = &MP_STATE_PORT(machine_timer_obj_head);
5758
while (*t != NULL) {
58-
machine_timer_disable(*t);
59+
machine_timer_deinit(*t);
5960
machine_timer_obj_t *next = (*t)->next;
6061
m_del_obj(machine_timer_obj_t, *t);
6162
*t = next;
@@ -96,6 +97,7 @@ machine_timer_obj_t *machine_timer_create(mp_uint_t timer) {
9697
self = mp_obj_malloc(machine_timer_obj_t, &machine_timer_type);
9798
self->group = group;
9899
self->index = index;
100+
self->handle = NULL;
99101

100102
// Add the timer to the linked-list of timers
101103
self->next = MP_STATE_PORT(machine_timer_obj_head);
@@ -131,9 +133,8 @@ void machine_timer_disable(machine_timer_obj_t *self) {
131133
}
132134

133135
if (self->handle) {
134-
// Free the interrupt handler.
135-
esp_intr_free(self->handle);
136-
self->handle = NULL;
136+
// Disable the interrupt
137+
ESP_ERROR_CHECK(esp_intr_disable(self->handle));
137138
}
138139

139140
// We let the disabled timer stay in the list, as it might be
@@ -167,6 +168,10 @@ void machine_timer_enable(machine_timer_obj_t *self, void (*timer_isr)) {
167168
// Allocate and enable the alarm interrupt.
168169
timer_ll_enable_intr(self->hal_context.dev, TIMER_LL_EVENT_ALARM(self->index), false);
169170
timer_ll_clear_intr_status(self->hal_context.dev, TIMER_LL_EVENT_ALARM(self->index));
171+
if (self->handle) {
172+
ESP_ERROR_CHECK(esp_intr_free(self->handle));
173+
self->handle = NULL;
174+
}
170175
ESP_ERROR_CHECK(
171176
esp_intr_alloc(timer_group_periph_signals.groups[self->group].timer_irq_id[self->index],
172177
TIMER_FLAGS, timer_isr, self, &self->handle)
@@ -233,7 +238,13 @@ static mp_obj_t machine_timer_init_helper(machine_timer_obj_t *self, mp_uint_t n
233238
}
234239

235240
static mp_obj_t machine_timer_deinit(mp_obj_t self_in) {
236-
machine_timer_disable(self_in);
241+
machine_timer_obj_t *self = self_in;
242+
243+
machine_timer_disable(self);
244+
if (self->handle) {
245+
ESP_ERROR_CHECK(esp_intr_free(self->handle));
246+
self->handle = NULL;
247+
}
237248

238249
return mp_const_none;
239250
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy