Merge branch 'test/parlio_rx_cache_safe' into 'master'

Reenable parlio rx cache safe test

Closes IDF-7840

See merge request espressif/esp-idf!38635
This commit is contained in:
morris
2025-04-23 21:23:41 +08:00
15 changed files with 82 additions and 118 deletions

View File

@@ -1,28 +1,14 @@
/* /*
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
#include <sys/lock.h>
#include "sdkconfig.h"
#if CONFIG_PARLIO_ENABLE_DEBUG_LOG
// The local log level must be defined before including esp_log.h
// Set the maximum log level for this source file
#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG
#endif
#include "esp_log.h"
#include "esp_check.h"
#include "clk_ctrl_os.h" #include "clk_ctrl_os.h"
#include "soc/rtc.h"
#include "soc/parlio_periph.h"
#include "hal/parlio_ll.h"
#include "esp_private/esp_clk.h" #include "esp_private/esp_clk.h"
#include "esp_private/sleep_retention.h" #include "esp_private/sleep_retention.h"
#include "parlio_priv.h" #include "parlio_priv.h"
static const char *TAG = "parlio";
typedef struct parlio_platform_t { typedef struct parlio_platform_t {
_lock_t mutex; // platform level mutex lock _lock_t mutex; // platform level mutex lock
parlio_group_t *groups[SOC_PARLIO_GROUPS]; // array of parallel IO group instances parlio_group_t *groups[SOC_PARLIO_GROUPS]; // array of parallel IO group instances
@@ -204,3 +190,11 @@ void parlio_create_retention_module(parlio_group_t *group)
_lock_release(&s_platform.mutex); _lock_release(&s_platform.mutex);
} }
#endif // PARLIO_USE_RETENTION_LINK #endif // PARLIO_USE_RETENTION_LINK
#if CONFIG_PARLIO_ENABLE_DEBUG_LOG
__attribute__((constructor))
static void parlio_override_default_log_level(void)
{
esp_log_level_set(TAG, ESP_LOG_VERBOSE);
}
#endif

View File

@@ -6,25 +6,50 @@
#pragma once #pragma once
#include <stdlib.h>
#include <string.h>
#include <stdatomic.h>
#include <sys/cdefs.h>
#include <sys/param.h>
#include <sys/lock.h>
#include "sdkconfig.h" #include "sdkconfig.h"
#if CONFIG_PARLIO_ENABLE_DEBUG_LOG
// The local log level must be defined before including esp_log.h
// Set the maximum log level for this source file
#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG
#endif
#include "esp_log.h"
#include "esp_check.h"
#include "esp_attr.h"
#include "esp_err.h"
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "freertos/idf_additions.h"
#include "soc/soc_caps.h" #include "soc/soc_caps.h"
#include "soc/gdma_channel.h" #include "soc/gdma_channel.h"
#include "soc/io_mux_reg.h" #include "soc/io_mux_reg.h"
#include "soc/parlio_periph.h"
#include "hal/parlio_types.h" #include "hal/parlio_types.h"
#include "hal/parlio_hal.h" #include "hal/parlio_hal.h"
#include "hal/parlio_ll.h" #include "hal/parlio_ll.h"
#include "hal/dma_types.h"
#include "hal/cache_hal.h" #include "hal/cache_hal.h"
#include "hal/cache_ll.h" #include "hal/cache_ll.h"
#include "rom/cache.h" #include "rom/cache.h"
#include "esp_heap_caps.h" #include "esp_heap_caps.h"
#include "driver/parlio_types.h" #include "driver/parlio_types.h"
#include "esp_cache.h" #include "esp_cache.h"
#include "esp_clk_tree.h"
#include "esp_pm.h"
#include "esp_memory_utils.h"
#include "esp_private/periph_ctrl.h" #include "esp_private/periph_ctrl.h"
#include "esp_private/esp_gpio_reserve.h" #include "esp_private/esp_gpio_reserve.h"
#include "esp_private/gpio.h" #include "esp_private/gpio.h"
#include "esp_private/sleep_retention.h" #include "esp_private/sleep_retention.h"
#include "esp_private/esp_clk_tree_common.h"
#include "esp_private/gdma.h"
#include "esp_private/gdma_link.h"
#include "esp_private/esp_dma_utils.h"
#if CONFIG_PARLIO_OBJ_CACHE_SAFE #if CONFIG_PARLIO_OBJ_CACHE_SAFE
#define PARLIO_MEM_ALLOC_CAPS (MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT) #define PARLIO_MEM_ALLOC_CAPS (MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT)
@@ -32,8 +57,6 @@
#define PARLIO_MEM_ALLOC_CAPS MALLOC_CAP_DEFAULT #define PARLIO_MEM_ALLOC_CAPS MALLOC_CAP_DEFAULT
#endif #endif
#define PARLIO_DMA_MEM_ALLOC_CAPS (MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA)
#if SOC_PARLIO_TX_RX_SHARE_INTERRUPT #if SOC_PARLIO_TX_RX_SHARE_INTERRUPT
#define PARLIO_INTR_ALLOC_FLAG_SHARED ESP_INTR_FLAG_SHARED #define PARLIO_INTR_ALLOC_FLAG_SHARED ESP_INTR_FLAG_SHARED
#else #else
@@ -49,13 +72,13 @@
// Use retention link only when the target supports sleep retention is enabled // Use retention link only when the target supports sleep retention is enabled
#define PARLIO_USE_RETENTION_LINK (SOC_PARLIO_SUPPORT_SLEEP_RETENTION && CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP) #define PARLIO_USE_RETENTION_LINK (SOC_PARLIO_SUPPORT_SLEEP_RETENTION && CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP)
#define PARLIO_DMA_DESCRIPTOR_BUFFER_MAX_SIZE 4095
#if defined(SOC_GDMA_TRIG_PERIPH_PARLIO0_BUS) // Parlio uses GDMA #if defined(SOC_GDMA_TRIG_PERIPH_PARLIO0_BUS) // Parlio uses GDMA
#if defined(SOC_GDMA_BUS_AHB) && (SOC_GDMA_TRIG_PERIPH_PARLIO0_BUS == SOC_GDMA_BUS_AHB) #if defined(SOC_GDMA_BUS_AHB) && (SOC_GDMA_TRIG_PERIPH_PARLIO0_BUS == SOC_GDMA_BUS_AHB)
typedef dma_descriptor_align4_t parlio_dma_desc_t;
#define PARLIO_DMA_DESC_ALIGNMENT 4 #define PARLIO_DMA_DESC_ALIGNMENT 4
#define PARLIO_GDMA_NEW_CHANNEL gdma_new_ahb_channel #define PARLIO_GDMA_NEW_CHANNEL gdma_new_ahb_channel
#elif defined(SOC_GDMA_BUS_AXI) && (SOC_GDMA_TRIG_PERIPH_PARLIO0_BUS == SOC_GDMA_BUS_AXI) #elif defined(SOC_GDMA_BUS_AXI) && (SOC_GDMA_TRIG_PERIPH_PARLIO0_BUS == SOC_GDMA_BUS_AXI)
typedef dma_descriptor_align8_t parlio_dma_desc_t;
#define PARLIO_DMA_DESC_ALIGNMENT 8 #define PARLIO_DMA_DESC_ALIGNMENT 8
#define PARLIO_GDMA_NEW_CHANNEL gdma_new_axi_channel #define PARLIO_GDMA_NEW_CHANNEL gdma_new_axi_channel
#endif #endif
@@ -79,6 +102,9 @@ typedef dma_descriptor_align8_t parlio_dma_desc_t;
#define PARLIO_PM_LOCK_NAME_LEN_MAX 16 #define PARLIO_PM_LOCK_NAME_LEN_MAX 16
///!< Logging settings
#define TAG "parlio"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif

View File

@@ -4,40 +4,12 @@
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
#include <stdlib.h>
#include <string.h>
#include <sys/cdefs.h>
#include <sys/param.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/idf_additions.h"
#if CONFIG_PARLIO_ENABLE_DEBUG_LOG
// The local log level must be defined before including esp_log.h
// Set the maximum log level for this source file
#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG
#endif
#include "esp_log.h"
#include "esp_check.h"
#include "esp_attr.h"
#include "esp_err.h"
#include "esp_rom_gpio.h" #include "esp_rom_gpio.h"
#include "esp_pm.h"
#include "soc/parlio_periph.h"
#include "soc/soc_caps.h"
#include "hal/parlio_ll.h"
#include "hal/dma_types.h" #include "hal/dma_types.h"
#include "hal/hal_utils.h" #include "hal/hal_utils.h"
#include "driver/gpio.h" #include "driver/gpio.h"
#include "driver/parlio_rx.h" #include "driver/parlio_rx.h"
#include "parlio_priv.h" #include "parlio_priv.h"
#include "esp_memory_utils.h"
#include "esp_clk_tree.h"
#include "esp_attr.h"
#include "esp_private/esp_clk_tree_common.h"
#include "esp_private/gdma.h"
#include "esp_cache.h"
static const char *TAG = "parlio-rx";
#define ALIGN_UP(num, align) (((num) + ((align) - 1)) & ~((align) - 1)) #define ALIGN_UP(num, align) (((num) + ((align) - 1)) & ~((align) - 1))
@@ -47,6 +19,14 @@ static const char *TAG = "parlio-rx";
#define PARLIO_MAX_ALIGNED_DMA_BUF_SIZE DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED #define PARLIO_MAX_ALIGNED_DMA_BUF_SIZE DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED
#endif #endif
#if defined(SOC_GDMA_BUS_AHB) && (SOC_GDMA_TRIG_PERIPH_PARLIO0_BUS == SOC_GDMA_BUS_AHB)
typedef dma_descriptor_align4_t parlio_dma_desc_t;
#elif defined(SOC_GDMA_BUS_AXI) && (SOC_GDMA_TRIG_PERIPH_PARLIO0_BUS == SOC_GDMA_BUS_AXI)
typedef dma_descriptor_align8_t parlio_dma_desc_t;
#endif
#define PARLIO_DMA_MEM_ALLOC_CAPS (MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT | MALLOC_CAP_DMA)
/** /**
* @brief Parlio RX transaction * @brief Parlio RX transaction
*/ */
@@ -622,9 +602,6 @@ static esp_err_t parlio_destroy_rx_unit(parlio_rx_unit_handle_t rx_unit)
esp_err_t parlio_new_rx_unit(const parlio_rx_unit_config_t *config, parlio_rx_unit_handle_t *ret_unit) esp_err_t parlio_new_rx_unit(const parlio_rx_unit_config_t *config, parlio_rx_unit_handle_t *ret_unit)
{ {
#if CONFIG_PARLIO_ENABLE_DEBUG_LOG
esp_log_level_set(TAG, ESP_LOG_DEBUG);
#endif
ESP_RETURN_ON_FALSE(config && ret_unit, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); ESP_RETURN_ON_FALSE(config && ret_unit, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
/* Check the data width to be the the power of 2 */ /* Check the data width to be the the power of 2 */
ESP_RETURN_ON_FALSE(__builtin_popcount(config->data_width) == 1, ESP_ERR_INVALID_ARG, TAG, ESP_RETURN_ON_FALSE(__builtin_popcount(config->data_width) == 1, ESP_ERR_INVALID_ARG, TAG,

View File

@@ -4,43 +4,11 @@
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
#include <stdlib.h>
#include <string.h>
#include <stdatomic.h>
#include <sys/cdefs.h>
#include <sys/param.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "freertos/idf_additions.h"
#if CONFIG_PARLIO_ENABLE_DEBUG_LOG
// The local log level must be defined before including esp_log.h
// Set the maximum log level for this source file
#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG
#endif
#include "esp_log.h"
#include "esp_check.h"
#include "esp_attr.h"
#include "esp_err.h"
#include "esp_rom_gpio.h" #include "esp_rom_gpio.h"
#include "soc/gpio_sig_map.h"
#include "esp_intr_alloc.h" #include "esp_intr_alloc.h"
#include "esp_pm.h"
#include "soc/parlio_periph.h"
#include "soc/soc_caps.h"
#include "hal/parlio_ll.h"
#include "driver/gpio.h" #include "driver/gpio.h"
#include "driver/parlio_tx.h" #include "driver/parlio_tx.h"
#include "parlio_priv.h" #include "parlio_priv.h"
#include "esp_memory_utils.h"
#include "esp_clk_tree.h"
#include "esp_private/esp_clk_tree_common.h"
#include "esp_private/gdma.h"
#include "esp_private/gdma_link.h"
#include "esp_private/esp_dma_utils.h"
static const char *TAG = "parlio-tx";
typedef struct { typedef struct {
uint32_t idle_value; // Parallel IO bus idle value uint32_t idle_value; // Parallel IO bus idle value
@@ -229,7 +197,7 @@ static esp_err_t parlio_tx_unit_init_dma(parlio_tx_unit_t *tx_unit, const parlio
// create DMA link list // create DMA link list
size_t buffer_alignment = MAX(tx_unit->int_mem_align, tx_unit->ext_mem_align); size_t buffer_alignment = MAX(tx_unit->int_mem_align, tx_unit->ext_mem_align);
size_t num_dma_nodes = esp_dma_calculate_node_count(config->max_transfer_size, buffer_alignment, DMA_DESCRIPTOR_BUFFER_MAX_SIZE); size_t num_dma_nodes = esp_dma_calculate_node_count(config->max_transfer_size, buffer_alignment, PARLIO_DMA_DESCRIPTOR_BUFFER_MAX_SIZE);
gdma_link_list_config_t dma_link_config = { gdma_link_list_config_t dma_link_config = {
.buffer_alignment = buffer_alignment, .buffer_alignment = buffer_alignment,
.item_alignment = PARLIO_DMA_DESC_ALIGNMENT, .item_alignment = PARLIO_DMA_DESC_ALIGNMENT,
@@ -320,9 +288,6 @@ static esp_err_t parlio_select_periph_clock(parlio_tx_unit_t *tx_unit, const par
esp_err_t parlio_new_tx_unit(const parlio_tx_unit_config_t *config, parlio_tx_unit_handle_t *ret_unit) esp_err_t parlio_new_tx_unit(const parlio_tx_unit_config_t *config, parlio_tx_unit_handle_t *ret_unit)
{ {
#if CONFIG_PARLIO_ENABLE_DEBUG_LOG
esp_log_level_set(TAG, ESP_LOG_DEBUG);
#endif
esp_err_t ret = ESP_OK; esp_err_t ret = ESP_OK;
parlio_tx_unit_t *unit = NULL; parlio_tx_unit_t *unit = NULL;
ESP_RETURN_ON_FALSE(config && ret_unit, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); ESP_RETURN_ON_FALSE(config && ret_unit, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
@@ -345,9 +310,8 @@ esp_err_t parlio_new_tx_unit(const parlio_tx_unit_config_t *config, parlio_tx_un
ESP_RETURN_ON_FALSE(config->flags.allow_pd == 0, ESP_ERR_NOT_SUPPORTED, TAG, "register back up is not supported"); ESP_RETURN_ON_FALSE(config->flags.allow_pd == 0, ESP_ERR_NOT_SUPPORTED, TAG, "register back up is not supported");
#endif // SOC_PARLIO_SUPPORT_SLEEP_RETENTION #endif // SOC_PARLIO_SUPPORT_SLEEP_RETENTION
// malloc unit memory // allocate unit from internal memory because it contains atomic member
uint32_t mem_caps = PARLIO_MEM_ALLOC_CAPS; unit = heap_caps_calloc(1, sizeof(parlio_tx_unit_t) + sizeof(parlio_tx_trans_desc_t) * config->trans_queue_depth, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
unit = heap_caps_calloc(1, sizeof(parlio_tx_unit_t) + sizeof(parlio_tx_trans_desc_t) * config->trans_queue_depth, mem_caps);
ESP_GOTO_ON_FALSE(unit, ESP_ERR_NO_MEM, err, TAG, "no memory for tx unit"); ESP_GOTO_ON_FALSE(unit, ESP_ERR_NO_MEM, err, TAG, "no memory for tx unit");
unit->max_transfer_bits = config->max_transfer_size * 8; unit->max_transfer_bits = config->max_transfer_size * 8;

View File

@@ -2,11 +2,6 @@ set(srcs "test_app_main.c"
"test_parlio_rx.c" "test_parlio_rx.c"
"test_parlio_tx.c") "test_parlio_tx.c")
# TODO: IDF-7840, semaphore in 'spi_bus_lock.c' is not IRAM safe
if(CONFIG_PARLIO_RX_ISR_CACHE_SAFE)
list(REMOVE_ITEM srcs "test_parlio_rx.c")
endif()
if(CONFIG_SOC_LIGHT_SLEEP_SUPPORTED AND CONFIG_PM_ENABLE) if(CONFIG_SOC_LIGHT_SLEEP_SUPPORTED AND CONFIG_PM_ENABLE)
list(APPEND srcs "test_parlio_sleep.c") list(APPEND srcs "test_parlio_sleep.c")
endif() endif()

View File

@@ -2,3 +2,4 @@ CONFIG_IDF_EXPERIMENTAL_FEATURES=y
CONFIG_SPIRAM=y CONFIG_SPIRAM=y
CONFIG_SPIRAM_MODE_HEX=y CONFIG_SPIRAM_MODE_HEX=y
CONFIG_SPIRAM_SPEED_200M=y CONFIG_SPIRAM_SPEED_200M=y
CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=0

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);

View File

@@ -382,7 +382,7 @@ Use the :doc:`/api-guides/tools/idf-size` tool to check the code and data consum
| driver | 4251 | 12 | 12 | 0 | 0 | 4046 | 4046 | 193 | 193 | | driver | 4251 | 12 | 12 | 0 | 0 | 4046 | 4046 | 193 | 193 |
+------------------+------------+-------+------+-------+-------+------------+-------+------------+---------+ +------------------+------------+-------+------+-------+-------+------------+-------+------------+---------+
Additionally, each GPTimer handle dynamically allocates about ``90`` bytes of memory from the heap. If the :cpp:member:`gptimer_config_t::flags::allow_pd` option is enabled, each timer will also consume approximately ``30`` extra bytes of memory during sleep to store the register context. Additionally, each GPTimer handle dynamically allocates about ``100`` bytes of memory from the heap. If the :cpp:member:`gptimer_config_t::flags::allow_pd` option is enabled, each timer will also consume approximately ``30`` extra bytes of memory during sleep to store the register context.
Application Examples Application Examples
-------------------- --------------------

View File

@@ -329,22 +329,18 @@ When the file system performs Flash read/write operations, the system temporaril
.. note:: .. note::
Note that after enabling this option, all interrupt callback functions and their context data **must be stored in internal memory**. Because when the Cache is disabled, the system cannot load data and instructions from Flash. Note that after enabling this option, all interrupt callback functions and their context data **must reside in internal memory**. Because when the Cache is disabled, the system cannot load data and instructions from external memory.
.. only:: SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND or SOC_SPIRAM_XIP_SUPPORTED .. only:: SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND or SOC_SPIRAM_XIP_SUPPORTED
.. note:: .. note::
Enable the following options: When the following options are enabled, the Cache will not be disabled automatically during Flash read/write operations. You don't have to enable the :ref:`CONFIG_PARLIO_TX_ISR_CACHE_SAFE`.
.. list:: .. list::
:SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND: - :ref:`CONFIG_SPI_FLASH_AUTO_SUSPEND` :SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND: - :ref:`CONFIG_SPI_FLASH_AUTO_SUSPEND`
:SOC_SPIRAM_XIP_SUPPORTED: - :ref:`CONFIG_SPIRAM_XIP_FROM_PSRAM` :SOC_SPIRAM_XIP_SUPPORTED: - :ref:`CONFIG_SPIRAM_XIP_FROM_PSRAM`
The Cache will not to be automatically disabled. And it is safe for the CPU to access the Cache while erasing the filesystem. :ref:`CONFIG_PARLIO_TX_ISR_CACHE_SAFE` option has no need to be enabled.
This way, interrupts can run while the Cache is disabled, but it will also increase IRAM consumption.
Performance Performance
^^^^^^^^^^^ ^^^^^^^^^^^

View File

@@ -382,7 +382,7 @@ GPTimer 驱动支持在中断回调函数中调用 :cpp:func:`gptimer_set_alarm_
| driver | 4251 | 12 | 12 | 0 | 0 | 4046 | 4046 | 193 | 193 | | driver | 4251 | 12 | 12 | 0 | 0 | 4046 | 4046 | 193 | 193 |
+------------------+------------+-------+------+-------+-------+------------+-------+------------+---------+ +------------------+------------+-------+------+-------+-------+------------+-------+------------+---------+
此外,每一个 GPTimer 句柄会从 heap 中动态申请约 ``90`` 字节的内存。如果还使能了 :cpp:member:`gptimer_config_t::flags::allow_pd` 选项,那么每个定时器还会在睡眠期间额外消耗约 ``30`` 字节的内存用于保存寄存器上下文。 此外,每一个 GPTimer 句柄会从 heap 中动态申请约 ``100`` 字节的内存。如果还使能了 :cpp:member:`gptimer_config_t::flags::allow_pd` 选项,那么每个定时器还会在睡眠期间额外消耗约 ``30`` 字节的内存用于保存寄存器上下文。
应用示例 应用示例
-------- --------

View File

@@ -335,16 +335,12 @@ TX 单元可以选择各种不同的时钟源,其中外部时钟源较为特
.. note:: .. note::
启用以下选项 启用以下选项时,系统在进行 Flash 读写操作时不会自动禁用 Cache, 因此无需启用 :ref:`CONFIG_PARLIO_TX_ISR_CACHE_SAFE`
.. list:: .. list::
:SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND: - :ref:`CONFIG_SPI_FLASH_AUTO_SUSPEND` :SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND: - :ref:`CONFIG_SPI_FLASH_AUTO_SUSPEND`
:SOC_SPIRAM_XIP_SUPPORTED: - :ref:`CONFIG_SPIRAM_XIP_FROM_PSRAM` :SOC_SPIRAM_XIP_SUPPORTED: - :ref:`CONFIG_SPIRAM_XIP_FROM_PSRAM`
可以让 Cache 不被自动禁用, CPU 在擦写文件系统的同时访问 Cache 是安全的,此时 :ref:`CONFIG_PARLIO_TX_ISR_CACHE_SAFE` 选项可以不用打开。
这样,在 Cache 被禁用时,中断也可运行,但是这也会增加 IRAM 的消耗。
关于性能 关于性能
^^^^^^^^ ^^^^^^^^