From f81772210976dc1ffbaaff6218b7edcb6b06162f Mon Sep 17 00:00:00 2001 From: songruojing Date: Wed, 17 Nov 2021 12:07:00 +0800 Subject: [PATCH] gpio: Bugfix - Move esp_intr_free() out of the critical section in gpio_uninstall_isr_service() Closes https://github.com/espressif/esp-idf/issues/5571 Fix the bug that if the API was called from one core to free the interrupt source on the other core, it would trigger interrupt watchdog. (cherry picked from commit 0e8286c57b33ca76183151c677f3880c6485db79) --- components/driver/gpio.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/components/driver/gpio.c b/components/driver/gpio.c index 3054bdaf96..bfab495634 100644 --- a/components/driver/gpio.c +++ b/components/driver/gpio.c @@ -502,15 +502,21 @@ esp_err_t gpio_isr_handler_remove(gpio_num_t gpio_num) void gpio_uninstall_isr_service(void) { + gpio_isr_func_t *gpio_isr_func_free = NULL; + gpio_isr_handle_t gpio_isr_handle_free = NULL; + portENTER_CRITICAL(&gpio_context.gpio_spinlock); if (gpio_context.gpio_isr_func == NULL) { + portEXIT_CRITICAL(&gpio_context.gpio_spinlock); return; } - portENTER_CRITICAL(&gpio_context.gpio_spinlock); - esp_intr_free(gpio_context.gpio_isr_handle); - free(gpio_context.gpio_isr_func); + gpio_isr_func_free = gpio_context.gpio_isr_func; gpio_context.gpio_isr_func = NULL; + gpio_isr_handle_free = gpio_context.gpio_isr_handle; + gpio_context.gpio_isr_handle = NULL; gpio_context.isr_core_id = GPIO_ISR_CORE_ID_UNINIT; portEXIT_CRITICAL(&gpio_context.gpio_spinlock); + esp_intr_free(gpio_isr_handle_free); + free(gpio_isr_func_free); return; } @@ -543,7 +549,12 @@ esp_err_t gpio_isr_register(void (*fn)(void *), void *arg, int intr_alloc_flags, #else /* CONFIG_FREERTOS_UNICORE */ ret = esp_ipc_call_blocking(gpio_context.isr_core_id, gpio_isr_register_on_core_static, (void *)&p); #endif /* !CONFIG_FREERTOS_UNICORE */ - if(ret != ESP_OK || p.ret != ESP_OK) { + if (ret != ESP_OK) { + ESP_LOGE(GPIO_TAG, "esp_ipc_call_blocking failed (0x%x)", ret); + return ESP_ERR_NOT_FOUND; + } + if (p.ret != ESP_OK) { + ESP_LOGE(GPIO_TAG, "esp_intr_alloc failed (0x%x)", p.ret); return ESP_ERR_NOT_FOUND; } return ESP_OK;