diff --git a/components/esp_hw_support/include/esp_intr_alloc.h b/components/esp_hw_support/include/esp_intr_alloc.h index a26fde9394f..a800c94fe86 100644 --- a/components/esp_hw_support/include/esp_intr_alloc.h +++ b/components/esp_hw_support/include/esp_intr_alloc.h @@ -64,6 +64,7 @@ extern "C" { #define ETS_INTERNAL_SW0_INTR_SOURCE -4 ///< Software int source 1 #define ETS_INTERNAL_SW1_INTR_SOURCE -5 ///< Software int source 2 #define ETS_INTERNAL_PROFILING_INTR_SOURCE -6 ///< Int source for profiling +#define ETS_INTERNAL_UNUSED_INTR_SOURCE -99 ///< Interrupt is not assigned to any source /**@}*/ diff --git a/components/esp_hw_support/intr_alloc.c b/components/esp_hw_support/intr_alloc.c index 314fe9db7de..c3fc56b0d8e 100644 --- a/components/esp_hw_support/intr_alloc.c +++ b/components/esp_hw_support/intr_alloc.c @@ -753,6 +753,8 @@ esp_err_t esp_intr_free(intr_handle_t handle) //we save.(We can also not use the same exit path for empty shared ints anymore if we delete //the desc.) For now, just mark it as free. handle->vector_desc->flags &= ~(VECDESC_FL_NONSHARED|VECDESC_FL_RESERVED|VECDESC_FL_SHARED); + handle->vector_desc->source = ETS_INTERNAL_UNUSED_INTR_SOURCE; + //Also kill non_iram mask bit. non_iram_int_mask[handle->vector_desc->cpu] &= ~(1<<(handle->vector_desc->intno)); } diff --git a/components/esp_hw_support/test/test_intr_alloc.c b/components/esp_hw_support/test/test_intr_alloc.c index 34435a3176c..7b4bb9b4b74 100644 --- a/components/esp_hw_support/test/test_intr_alloc.c +++ b/components/esp_hw_support/test/test_intr_alloc.c @@ -65,6 +65,14 @@ static void timer_test(int flags) printf("Interrupts allocated: %d\r\n", esp_intr_get_intno(inth[i])); } + if ((flags & ESP_INTR_FLAG_SHARED)) { + /* Check that the allocated interrupts are acutally shared */ + int intr_num = esp_intr_get_intno(inth[0]); + for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) { + TEST_ASSERT_EQUAL(intr_num, esp_intr_get_intno(inth[i])); + } + } + vTaskDelay(1000 / portTICK_PERIOD_MS); printf("Timer values after 1 sec:"); for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) { @@ -109,6 +117,27 @@ TEST_CASE("Intr_alloc test, shared ints", "[intr_alloc]") timer_test(ESP_INTR_FLAG_SHARED); } +void static test_isr(void*arg) +{ + /* ISR should never be called */ + abort(); +} + + +TEST_CASE("Allocate previously freed interrupt, with different flags", "[intr_alloc]") +{ + intr_handle_t intr; + int test_intr_source = ETS_GPIO_INTR_SOURCE; + int isr_flags = ESP_INTR_FLAG_LEVEL2; + + TEST_ESP_OK(esp_intr_alloc(test_intr_source, isr_flags, test_isr, NULL, &intr)); + TEST_ESP_OK(esp_intr_free(intr)); + + isr_flags = ESP_INTR_FLAG_LEVEL3; + TEST_ESP_OK(esp_intr_alloc(test_intr_source, isr_flags, test_isr, NULL, &intr)); + TEST_ESP_OK(esp_intr_free(intr)); +} + typedef struct { bool flag1; bool flag2;