mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
driver(interrupt): fix the issue that interrupt might be allocated and freed on different cores for release/v3.1
This commit is contained in:
parent
027e081622
commit
fb30315d01
@ -194,18 +194,19 @@ esp_err_t esp_intr_alloc_intrstatus(int source, int flags, uint32_t intrstatusre
|
||||
/**
|
||||
* @brief Disable and free an interrupt.
|
||||
*
|
||||
* Use an interrupt handle to disable the interrupt and release the resources
|
||||
* associated with it.
|
||||
* Use an interrupt handle to disable the interrupt and release the resources associated with it.
|
||||
* If the current core is not the core that registered this interrupt, this routine will be assigned to
|
||||
* the core that allocated this interrupt, blocking and waiting until the resource is successfully released.
|
||||
*
|
||||
* @note
|
||||
* When the handler shares its source with other handlers, the interrupt status
|
||||
* bits it's responsible for should be managed properly before freeing it. see
|
||||
* ``esp_intr_disable`` for more details.
|
||||
* ``esp_intr_disable`` for more details. Please do not call this function in ``esp_ipc_call_blocking``.
|
||||
*
|
||||
* @param handle The handle, as obtained by esp_intr_alloc or esp_intr_alloc_intrstatus
|
||||
*
|
||||
* @return ESP_ERR_INVALID_ARG if handle is invalid, or esp_intr_free runs on another core than
|
||||
* where the interrupt is allocated on.
|
||||
* @return ESP_ERR_INVALID_ARG the handle is NULL
|
||||
* ESP_FAIL failed to release this handle
|
||||
* ESP_OK otherwise
|
||||
*/
|
||||
esp_err_t esp_intr_free(intr_handle_t handle);
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "esp_intr.h"
|
||||
#include "esp_attr.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
#include "esp_ipc.h"
|
||||
#include <limits.h>
|
||||
#include <assert.h>
|
||||
|
||||
@ -709,9 +710,11 @@ esp_err_t esp_intr_free(intr_handle_t handle)
|
||||
{
|
||||
bool free_shared_vector=false;
|
||||
if (!handle) return ESP_ERR_INVALID_ARG;
|
||||
//This routine should be called from the interrupt the task is scheduled on.
|
||||
if (handle->vector_desc->cpu!=xPortGetCoreID()) return ESP_ERR_INVALID_ARG;
|
||||
|
||||
//Assign this routine to the core where this interrupt is allocated on.
|
||||
if (handle->vector_desc->cpu!=xPortGetCoreID()) {
|
||||
esp_err_t ret = esp_ipc_call_blocking(handle->vector_desc->cpu, (esp_ipc_func_t)&esp_intr_free, (void *)handle);
|
||||
return ret == ESP_OK ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
portENTER_CRITICAL(&spinlock);
|
||||
esp_intr_disable(handle);
|
||||
if (handle->vector_desc->flags&VECDESC_FL_SHARED) {
|
||||
|
@ -297,3 +297,41 @@ TEST_CASE("allocate 2 handlers for a same source and remove the later one","[esp
|
||||
TEST_ASSERT( ctx.flag3 && !ctx.flag4 );
|
||||
printf("test passed.\n");
|
||||
}
|
||||
|
||||
#ifndef CONFIG_FREERTOS_UNICORE
|
||||
|
||||
void isr_free_task(void *param)
|
||||
{
|
||||
esp_err_t ret = ESP_FAIL;
|
||||
intr_handle_t *test_handle = (intr_handle_t *)param;
|
||||
if(*test_handle != NULL) {
|
||||
ret = esp_intr_free(*test_handle);
|
||||
if(ret == ESP_OK) {
|
||||
*test_handle = NULL;
|
||||
}
|
||||
}
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
void isr_alloc_free_test(void)
|
||||
{
|
||||
intr_handle_t test_handle = NULL;
|
||||
esp_err_t ret = esp_intr_alloc(ETS_SPI2_INTR_SOURCE, 0, int_handler1, NULL, &test_handle);
|
||||
if(ret != ESP_OK) {
|
||||
printf("alloc isr handle fail\n");
|
||||
} else {
|
||||
printf("alloc isr handle on core %d\n",esp_intr_get_cpu(test_handle));
|
||||
}
|
||||
TEST_ASSERT(ret == ESP_OK);
|
||||
xTaskCreatePinnedToCore(isr_free_task, "isr_free_task", 1024*2, (void *)&test_handle, 10, NULL, !xPortGetCoreID());
|
||||
vTaskDelay(1000/portTICK_RATE_MS);
|
||||
TEST_ASSERT(test_handle == NULL);
|
||||
printf("test passed\n");
|
||||
}
|
||||
|
||||
TEST_CASE("alloc and free isr handle on different core", "[esp32]")
|
||||
{
|
||||
isr_alloc_free_test();
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user