From c94db04f2d3e6a0040b1cde8dc57ab7a15408af4 Mon Sep 17 00:00:00 2001 From: morris Date: Wed, 23 Apr 2025 10:38:04 +0800 Subject: [PATCH] fix(spi): allocate driver memory with caps explicitly --- components/esp_driver_spi/Kconfig | 2 ++ components/esp_driver_spi/src/gpspi/spi_common.c | 12 +++++++++--- components/esp_driver_spi/src/gpspi/spi_master.c | 8 +++++++- components/esp_driver_spi/src/gpspi/spi_slave.c | 3 ++- components/esp_hw_support/spi_bus_lock.c | 8 ++++---- 5 files changed, 24 insertions(+), 9 deletions(-) diff --git a/components/esp_driver_spi/Kconfig b/components/esp_driver_spi/Kconfig index da78416f8c..ee180564da 100644 --- a/components/esp_driver_spi/Kconfig +++ b/components/esp_driver_spi/Kconfig @@ -26,6 +26,7 @@ menu "ESP-Driver:SPI Configurations" select ESP_PERIPH_CTRL_FUNC_IN_IRAM select ESP_SPI_BUS_LOCK_ISR_FUNCS_IN_IRAM select GDMA_CTRL_FUNC_IN_IRAM if SOC_GDMA_SUPPORTED + select GDMA_ISR_HANDLER_IN_IRAM if SOC_GDMA_SUPPORTED help Place the SPI master ISR in to IRAM to avoid possible cache miss. @@ -54,6 +55,7 @@ menu "ESP-Driver:SPI Configurations" default y select ESP_PERIPH_CTRL_FUNC_IN_IRAM select GDMA_CTRL_FUNC_IN_IRAM if SOC_GDMA_SUPPORTED + select GDMA_ISR_HANDLER_IN_IRAM if SOC_GDMA_SUPPORTED help Place the SPI slave ISR in to IRAM to avoid possible cache miss. diff --git a/components/esp_driver_spi/src/gpspi/spi_common.c b/components/esp_driver_spi/src/gpspi/spi_common.c index c767559940..ce22e7cd4d 100644 --- a/components/esp_driver_spi/src/gpspi/spi_common.c +++ b/components/esp_driver_spi/src/gpspi/spi_common.c @@ -5,8 +5,8 @@ */ #include +#include #include "sdkconfig.h" -#include "stdatomic.h" #include "esp_types.h" #include "esp_attr.h" #include "esp_check.h" @@ -35,6 +35,12 @@ #define SPI_COMMON_ISR_ATTR #endif +#if CONFIG_SPI_MASTER_ISR_IN_IRAM || CONFIG_SPI_SLAVE_ISR_IN_IRAM +#define SPI_COMMON_MALLOC_CAPS (MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT) +#else +#define SPI_COMMON_MALLOC_CAPS (MALLOC_CAP_DEFAULT) +#endif + static const char *SPI_TAG = "spi"; #define SPI_CHECK(a, str, ret_val) ESP_RETURN_ON_FALSE(a, ret_val, SPI_TAG, str) @@ -270,7 +276,7 @@ esp_err_t spicommon_dma_chan_alloc(spi_host_device_t host_id, spi_dma_chan_t dma #endif esp_err_t ret = ESP_OK; - spi_dma_ctx_t *dma_ctx = (spi_dma_ctx_t *)calloc(1, sizeof(spi_dma_ctx_t)); + spi_dma_ctx_t *dma_ctx = (spi_dma_ctx_t *)heap_caps_calloc(1, sizeof(spi_dma_ctx_t), SPI_COMMON_MALLOC_CAPS); if (!dma_ctx) { ret = ESP_ERR_NO_MEM; goto cleanup; @@ -820,7 +826,7 @@ esp_err_t spi_bus_initialize(spi_host_device_t host_id, const spi_bus_config_t * SPI_CHECK(spi_chan_claimed, "host_id already in use", ESP_ERR_INVALID_STATE); //clean and initialize the context - ctx = (spicommon_bus_context_t *)calloc(1, sizeof(spicommon_bus_context_t)); + ctx = (spicommon_bus_context_t *)heap_caps_calloc(1, sizeof(spicommon_bus_context_t), SPI_COMMON_MALLOC_CAPS); if (!ctx) { err = ESP_ERR_NO_MEM; goto cleanup; diff --git a/components/esp_driver_spi/src/gpspi/spi_master.c b/components/esp_driver_spi/src/gpspi/spi_master.c index cb3e30ef09..daf953fb92 100644 --- a/components/esp_driver_spi/src/gpspi/spi_master.c +++ b/components/esp_driver_spi/src/gpspi/spi_master.c @@ -145,6 +145,12 @@ We have two bits to control the interrupt: #define SPI_MASTER_ATTR #endif +#if CONFIG_SPI_MASTER_IN_IRAM || CONFIG_SPI_MASTER_ISR_IN_IRAM +#define SPI_MASTER_MALLOC_CAPS (MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT) +#else +#define SPI_MASTER_MALLOC_CAPS (MALLOC_CAP_DEFAULT) +#endif + #if SOC_PERIPH_CLK_CTRL_SHARED #define SPI_MASTER_PERI_CLOCK_ATOMIC() PERIPH_RCC_ATOMIC() #else @@ -492,7 +498,7 @@ esp_err_t spi_bus_add_device(spi_host_device_t host_id, const spi_device_interfa } //Allocate memory for device - dev = malloc(sizeof(spi_device_t)); + dev = heap_caps_malloc(sizeof(spi_device_t), SPI_MASTER_MALLOC_CAPS); if (dev == NULL) { goto nomem; } diff --git a/components/esp_driver_spi/src/gpspi/spi_slave.c b/components/esp_driver_spi/src/gpspi/spi_slave.c index 561480004b..64b7d02f21 100644 --- a/components/esp_driver_spi/src/gpspi/spi_slave.c +++ b/components/esp_driver_spi/src/gpspi/spi_slave.c @@ -170,7 +170,8 @@ esp_err_t spi_slave_initialize(spi_host_device_t host, const spi_bus_config_t *b spi_chan_claimed = spicommon_periph_claim(host, "spi slave"); SPI_CHECK(spi_chan_claimed, "host already in use", ESP_ERR_INVALID_STATE); - spihost[host] = malloc(sizeof(spi_slave_t)); + // spi_slave_t contains atomic variable, memory must be allocated from internal memory + spihost[host] = heap_caps_malloc(sizeof(spi_slave_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); if (spihost[host] == NULL) { ret = ESP_ERR_NO_MEM; goto cleanup; diff --git a/components/esp_hw_support/spi_bus_lock.c b/components/esp_hw_support/spi_bus_lock.c index 0f5165c418..41a159c1c5 100644 --- a/components/esp_hw_support/spi_bus_lock.c +++ b/components/esp_hw_support/spi_bus_lock.c @@ -585,7 +585,7 @@ SPI_BUS_LOCK_ISR_ATTR static inline esp_err_t dev_wait(spi_bus_lock_dev_t *dev_h ******************************************************************************/ esp_err_t spi_bus_init_lock(spi_bus_lock_handle_t *out_lock, const spi_bus_lock_config_t *config) { - spi_bus_lock_t* lock = (spi_bus_lock_t*)calloc(1, sizeof(spi_bus_lock_t)); + spi_bus_lock_t* lock = (spi_bus_lock_t*)heap_caps_calloc(1, sizeof(spi_bus_lock_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); if (lock == NULL) { return ESP_ERR_NO_MEM; } @@ -648,7 +648,7 @@ esp_err_t spi_bus_lock_register_dev(spi_bus_lock_handle_t lock, spi_bus_lock_dev if (dev_lock == NULL) { return ESP_ERR_NO_MEM; } - dev_lock->semphr = xSemaphoreCreateBinary(); + dev_lock->semphr = xSemaphoreCreateBinaryWithCaps(MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); if (dev_lock->semphr == NULL) { free(dev_lock); atomic_store(&lock->dev[id], (intptr_t)NULL); @@ -676,7 +676,7 @@ void spi_bus_lock_unregister_dev(spi_bus_lock_dev_handle_t dev_handle) atomic_store(&lock->dev[id], (intptr_t)NULL); if (dev_handle->semphr) { - vSemaphoreDelete(dev_handle->semphr); + vSemaphoreDeleteWithCaps(dev_handle->semphr); } free(dev_handle); @@ -819,7 +819,7 @@ SPI_BUS_LOCK_ISR_ATTR bool spi_bus_lock_bg_clear_req(spi_bus_lock_dev_t *dev_han } SPI_BUS_LOCK_ISR_ATTR bool spi_bus_lock_bg_check_dev_acq(spi_bus_lock_t *lock, - spi_bus_lock_dev_handle_t *out_dev_lock) + spi_bus_lock_dev_handle_t *out_dev_lock) { BUS_LOCK_DEBUG_EXECUTE_CHECK(!lock->acquiring_dev); uint32_t status = lock_status_fetch(lock);