forked from espressif/esp-idf
fix(esp_hw_support): Fix esp_intr_free when taks has no core affinity
Closes https://github.com/espressif/esp-idf/issues/12608
This commit is contained in:
committed by
BOT
parent
01bc97ab04
commit
eeeebdf1cd
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@@ -97,6 +97,8 @@ struct non_shared_isr_arg_t {
|
|||||||
int source;
|
int source;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static esp_err_t intr_free_for_current_cpu(intr_handle_t handle);
|
||||||
|
|
||||||
//Linked list of vector descriptions, sorted by cpu.intno value
|
//Linked list of vector descriptions, sorted by cpu.intno value
|
||||||
static vector_desc_t *vector_desc_head = NULL;
|
static vector_desc_t *vector_desc_head = NULL;
|
||||||
|
|
||||||
@@ -686,27 +688,45 @@ esp_err_t IRAM_ATTR esp_intr_set_in_iram(intr_handle_t handle, bool is_in_iram)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if !CONFIG_FREERTOS_UNICORE
|
#if !CONFIG_FREERTOS_UNICORE
|
||||||
static void esp_intr_free_cb(void *arg)
|
static void intr_free_for_other_cpu(void *arg)
|
||||||
{
|
{
|
||||||
(void)esp_intr_free((intr_handle_t)arg);
|
(void)intr_free_for_current_cpu((intr_handle_t)arg);
|
||||||
}
|
}
|
||||||
#endif /* !CONFIG_FREERTOS_UNICORE */
|
#endif /* !CONFIG_FREERTOS_UNICORE */
|
||||||
|
|
||||||
esp_err_t esp_intr_free(intr_handle_t handle)
|
esp_err_t esp_intr_free(intr_handle_t handle)
|
||||||
{
|
{
|
||||||
bool free_shared_vector=false;
|
|
||||||
if (!handle) {
|
if (!handle) {
|
||||||
return ESP_ERR_INVALID_ARG;
|
return ESP_ERR_INVALID_ARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !CONFIG_FREERTOS_UNICORE
|
#if !CONFIG_FREERTOS_UNICORE
|
||||||
//Assign this routine to the core where this interrupt is allocated on.
|
//Assign this routine to the core where this interrupt is allocated on.
|
||||||
if (handle->vector_desc->cpu != esp_cpu_get_core_id()) {
|
|
||||||
esp_err_t ret = esp_ipc_call_blocking(handle->vector_desc->cpu, &esp_intr_free_cb, (void *)handle);
|
bool task_can_be_run_on_any_core;
|
||||||
|
#if CONFIG_FREERTOS_SMP
|
||||||
|
UBaseType_t core_affinity = vTaskCoreAffinityGet(NULL);
|
||||||
|
task_can_be_run_on_any_core = (__builtin_popcount(core_affinity) > 1);
|
||||||
|
#else
|
||||||
|
UBaseType_t core_affinity = xTaskGetCoreID(NULL);
|
||||||
|
task_can_be_run_on_any_core = (core_affinity == tskNO_AFFINITY);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (task_can_be_run_on_any_core || handle->vector_desc->cpu != esp_cpu_get_core_id()) {
|
||||||
|
// If the task can be run on any core then we can not rely on the current CPU id (in case if task switching occurs).
|
||||||
|
// It is safer to call intr_free_for_current_cpu() from a pinned to a certain CPU task. It is done through the IPC call.
|
||||||
|
esp_err_t ret = esp_ipc_call_blocking(handle->vector_desc->cpu, &intr_free_for_other_cpu, (void *)handle);
|
||||||
return ret == ESP_OK ? ESP_OK : ESP_FAIL;
|
return ret == ESP_OK ? ESP_OK : ESP_FAIL;
|
||||||
}
|
}
|
||||||
#endif /* !CONFIG_FREERTOS_UNICORE */
|
#endif /* !CONFIG_FREERTOS_UNICORE */
|
||||||
|
|
||||||
|
return intr_free_for_current_cpu(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
static esp_err_t intr_free_for_current_cpu(intr_handle_t handle)
|
||||||
|
{
|
||||||
|
bool free_shared_vector = false;
|
||||||
|
|
||||||
portENTER_CRITICAL(&spinlock);
|
portENTER_CRITICAL(&spinlock);
|
||||||
esp_intr_disable(handle);
|
esp_intr_disable(handle);
|
||||||
if (handle->vector_desc->flags & VECDESC_FL_SHARED) {
|
if (handle->vector_desc->flags & VECDESC_FL_SHARED) {
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@@ -287,7 +287,7 @@ void isr_free_task(void *param)
|
|||||||
vTaskDelete(NULL);
|
vTaskDelete(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void isr_alloc_free_test(void)
|
void isr_alloc_free_test(bool isr_free_task_no_affinity)
|
||||||
{
|
{
|
||||||
intr_handle_t test_handle = NULL;
|
intr_handle_t test_handle = NULL;
|
||||||
esp_err_t ret = esp_intr_alloc(spi_periph_signal[1].irq, 0, int_handler1, NULL, &test_handle);
|
esp_err_t ret = esp_intr_alloc(spi_periph_signal[1].irq, 0, int_handler1, NULL, &test_handle);
|
||||||
@@ -296,16 +296,27 @@ void isr_alloc_free_test(void)
|
|||||||
} else {
|
} else {
|
||||||
printf("alloc isr handle on core %d\n", esp_intr_get_cpu(test_handle));
|
printf("alloc isr handle on core %d\n", esp_intr_get_cpu(test_handle));
|
||||||
}
|
}
|
||||||
TEST_ASSERT(ret == ESP_OK);
|
TEST_ESP_OK(ret);
|
||||||
|
if (isr_free_task_no_affinity) {
|
||||||
|
xTaskCreate(isr_free_task, "isr_free_task", 1024 * 2, (void *)&test_handle, 3, NULL);
|
||||||
|
esp_rom_delay_us(500);
|
||||||
|
vTaskDelay(500 / portTICK_PERIOD_MS);
|
||||||
|
} else {
|
||||||
xTaskCreatePinnedToCore(isr_free_task, "isr_free_task", 1024 * 2, (void *)&test_handle, 10, NULL, !xPortGetCoreID());
|
xTaskCreatePinnedToCore(isr_free_task, "isr_free_task", 1024 * 2, (void *)&test_handle, 10, NULL, !xPortGetCoreID());
|
||||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||||
TEST_ASSERT(test_handle == NULL);
|
}
|
||||||
|
TEST_ASSERT_NULL(test_handle);
|
||||||
printf("test passed\n");
|
printf("test passed\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("alloc and free isr handle on different core", "[intr_alloc]")
|
TEST_CASE("alloc and free isr handle on different core", "[intr_alloc]")
|
||||||
{
|
{
|
||||||
isr_alloc_free_test();
|
isr_alloc_free_test(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("alloc and free isr handle on different core when isr_free_task is NO_AFFINITY", "[intr_alloc]")
|
||||||
|
{
|
||||||
|
isr_alloc_free_test(true);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user