fix(spi): allocate driver memory with caps explicitly

This commit is contained in:
morris
2025-04-23 10:38:04 +08:00
parent 672db2b297
commit c94db04f2d
5 changed files with 24 additions and 9 deletions

View File

@@ -26,6 +26,7 @@ menu "ESP-Driver:SPI Configurations"
select ESP_PERIPH_CTRL_FUNC_IN_IRAM select ESP_PERIPH_CTRL_FUNC_IN_IRAM
select ESP_SPI_BUS_LOCK_ISR_FUNCS_IN_IRAM select ESP_SPI_BUS_LOCK_ISR_FUNCS_IN_IRAM
select GDMA_CTRL_FUNC_IN_IRAM if SOC_GDMA_SUPPORTED select GDMA_CTRL_FUNC_IN_IRAM if SOC_GDMA_SUPPORTED
select GDMA_ISR_HANDLER_IN_IRAM if SOC_GDMA_SUPPORTED
help help
Place the SPI master ISR in to IRAM to avoid possible cache miss. Place the SPI master ISR in to IRAM to avoid possible cache miss.
@@ -54,6 +55,7 @@ menu "ESP-Driver:SPI Configurations"
default y default y
select ESP_PERIPH_CTRL_FUNC_IN_IRAM select ESP_PERIPH_CTRL_FUNC_IN_IRAM
select GDMA_CTRL_FUNC_IN_IRAM if SOC_GDMA_SUPPORTED select GDMA_CTRL_FUNC_IN_IRAM if SOC_GDMA_SUPPORTED
select GDMA_ISR_HANDLER_IN_IRAM if SOC_GDMA_SUPPORTED
help help
Place the SPI slave ISR in to IRAM to avoid possible cache miss. Place the SPI slave ISR in to IRAM to avoid possible cache miss.

View File

@@ -5,8 +5,8 @@
*/ */
#include <string.h> #include <string.h>
#include <stdatomic.h>
#include "sdkconfig.h" #include "sdkconfig.h"
#include "stdatomic.h"
#include "esp_types.h" #include "esp_types.h"
#include "esp_attr.h" #include "esp_attr.h"
#include "esp_check.h" #include "esp_check.h"
@@ -35,6 +35,12 @@
#define SPI_COMMON_ISR_ATTR #define SPI_COMMON_ISR_ATTR
#endif #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"; static const char *SPI_TAG = "spi";
#define SPI_CHECK(a, str, ret_val) ESP_RETURN_ON_FALSE(a, ret_val, SPI_TAG, str) #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 #endif
esp_err_t ret = ESP_OK; 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) { if (!dma_ctx) {
ret = ESP_ERR_NO_MEM; ret = ESP_ERR_NO_MEM;
goto cleanup; 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); SPI_CHECK(spi_chan_claimed, "host_id already in use", ESP_ERR_INVALID_STATE);
//clean and initialize the context //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) { if (!ctx) {
err = ESP_ERR_NO_MEM; err = ESP_ERR_NO_MEM;
goto cleanup; goto cleanup;

View File

@@ -145,6 +145,12 @@ We have two bits to control the interrupt:
#define SPI_MASTER_ATTR #define SPI_MASTER_ATTR
#endif #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 #if SOC_PERIPH_CLK_CTRL_SHARED
#define SPI_MASTER_PERI_CLOCK_ATOMIC() PERIPH_RCC_ATOMIC() #define SPI_MASTER_PERI_CLOCK_ATOMIC() PERIPH_RCC_ATOMIC()
#else #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 //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) { if (dev == NULL) {
goto nomem; goto nomem;
} }

View File

@@ -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_chan_claimed = spicommon_periph_claim(host, "spi slave");
SPI_CHECK(spi_chan_claimed, "host already in use", ESP_ERR_INVALID_STATE); 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) { if (spihost[host] == NULL) {
ret = ESP_ERR_NO_MEM; ret = ESP_ERR_NO_MEM;
goto cleanup; goto cleanup;

View File

@@ -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) 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) { if (lock == NULL) {
return ESP_ERR_NO_MEM; 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) { if (dev_lock == NULL) {
return ESP_ERR_NO_MEM; return ESP_ERR_NO_MEM;
} }
dev_lock->semphr = xSemaphoreCreateBinary(); dev_lock->semphr = xSemaphoreCreateBinaryWithCaps(MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
if (dev_lock->semphr == NULL) { if (dev_lock->semphr == NULL) {
free(dev_lock); free(dev_lock);
atomic_store(&lock->dev[id], (intptr_t)NULL); 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); atomic_store(&lock->dev[id], (intptr_t)NULL);
if (dev_handle->semphr) { if (dev_handle->semphr) {
vSemaphoreDelete(dev_handle->semphr); vSemaphoreDeleteWithCaps(dev_handle->semphr);
} }
free(dev_handle); free(dev_handle);