Просмотр исходного кода

Merge branch 'bugfix/share_intr' into 'master'

intr_alloc: fixed freed interrupt sources not being able to be allocated again with different flags

See merge request espressif/esp-idf!20936
Zim Kalinowski 3 лет назад
Родитель
Сommit
94c0e3bbe2

+ 1 - 0
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
 
 /**@}*/
 

+ 2 - 0
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));
     }

+ 29 - 0
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;