fix(parlio): reenable parlio rx driver cache safe test

This commit is contained in:
morris
2025-04-08 17:35:04 +08:00
parent c94db04f2d
commit 3fc566caf1
10 changed files with 58 additions and 109 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
*/
#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 "soc/rtc.h"
#include "soc/parlio_periph.h"
#include "hal/parlio_ll.h"
#include "esp_private/esp_clk.h"
#include "esp_private/sleep_retention.h"
#include "parlio_priv.h"
static const char *TAG = "parlio";
typedef struct parlio_platform_t {
_lock_t mutex; // platform level mutex lock
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);
}
#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
#include <stdlib.h>
#include <string.h>
#include <stdatomic.h>
#include <sys/cdefs.h>
#include <sys/param.h>
#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 "esp_attr.h"
#include "esp_err.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/gdma_channel.h"
#include "soc/io_mux_reg.h"
#include "soc/parlio_periph.h"
#include "hal/parlio_types.h"
#include "hal/parlio_hal.h"
#include "hal/parlio_ll.h"
#include "hal/dma_types.h"
#include "hal/cache_hal.h"
#include "hal/cache_ll.h"
#include "rom/cache.h"
#include "esp_heap_caps.h"
#include "driver/parlio_types.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/esp_gpio_reserve.h"
#include "esp_private/gpio.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
#define PARLIO_MEM_ALLOC_CAPS (MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT)
@ -32,8 +57,6 @@
#define PARLIO_MEM_ALLOC_CAPS MALLOC_CAP_DEFAULT
#endif
#define PARLIO_DMA_MEM_ALLOC_CAPS (MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA)
#if SOC_PARLIO_TX_RX_SHARE_INTERRUPT
#define PARLIO_INTR_ALLOC_FLAG_SHARED ESP_INTR_FLAG_SHARED
#else
@ -49,13 +72,13 @@
// 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_DMA_DESCRIPTOR_BUFFER_MAX_SIZE 4095
#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)
typedef dma_descriptor_align4_t parlio_dma_desc_t;
#define PARLIO_DMA_DESC_ALIGNMENT 4
#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)
typedef dma_descriptor_align8_t parlio_dma_desc_t;
#define PARLIO_DMA_DESC_ALIGNMENT 8
#define PARLIO_GDMA_NEW_CHANNEL gdma_new_axi_channel
#endif
@ -79,6 +102,9 @@ typedef dma_descriptor_align8_t parlio_dma_desc_t;
#define PARLIO_PM_LOCK_NAME_LEN_MAX 16
///!< Logging settings
#define TAG "parlio"
#ifdef __cplusplus
extern "C" {
#endif

View File

@ -4,40 +4,12 @@
* 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_pm.h"
#include "soc/parlio_periph.h"
#include "soc/soc_caps.h"
#include "hal/parlio_ll.h"
#include "hal/dma_types.h"
#include "hal/hal_utils.h"
#include "driver/gpio.h"
#include "driver/parlio_rx.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))
@ -47,6 +19,14 @@ static const char *TAG = "parlio-rx";
#define PARLIO_MAX_ALIGNED_DMA_BUF_SIZE DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED
#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
*/
@ -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)
{
#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");
/* 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,

View File

@ -4,43 +4,11 @@
* 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 "soc/gpio_sig_map.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/parlio_tx.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 {
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
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 = {
.buffer_alignment = buffer_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)
{
#if CONFIG_PARLIO_ENABLE_DEBUG_LOG
esp_log_level_set(TAG, ESP_LOG_DEBUG);
#endif
esp_err_t ret = ESP_OK;
parlio_tx_unit_t *unit = NULL;
ESP_RETURN_ON_FALSE(config && ret_unit, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
@ -345,15 +310,14 @@ 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");
#endif // SOC_PARLIO_SUPPORT_SLEEP_RETENTION
// malloc unit memory
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, mem_caps);
// allocate unit from internal memory because it contains atomic member
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);
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->base.dir = PARLIO_DIR_TX;
unit->data_width = data_width;
//create transaction queue
// create transaction queue
ESP_GOTO_ON_ERROR(parlio_tx_create_trans_queue(unit, config), err, TAG, "create transaction queue failed");
// register the unit to a group

View File

@ -2,11 +2,6 @@ set(srcs "test_app_main.c"
"test_parlio_rx.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)
list(APPEND srcs "test_parlio_sleep.c")
endif()

View File

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

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 |
+------------------+------------+-------+------+-------+-------+------------+-------+------------+---------+
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
--------------------

View File

@ -329,22 +329,18 @@ When the file system performs Flash read/write operations, the system temporaril
.. 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
.. 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::
:SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND: - :ref:`CONFIG_SPI_FLASH_AUTO_SUSPEND`
: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
^^^^^^^^^^^

View File

@ -382,7 +382,7 @@ GPTimer 驱动支持在中断回调函数中调用 :cpp:func:`gptimer_set_alarm_
| 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::
启用以下选项
启用以下选项时,系统在进行 Flash 读写操作时不会自动禁用 Cache, 因此无需启用 :ref:`CONFIG_PARLIO_TX_ISR_CACHE_SAFE`
.. list::
:SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND: - :ref:`CONFIG_SPI_FLASH_AUTO_SUSPEND`
:SOC_SPIRAM_XIP_SUPPORTED: - :ref:`CONFIG_SPIRAM_XIP_FROM_PSRAM`
可以让 Cache 不被自动禁用, CPU 在擦写文件系统的同时访问 Cache 是安全的,此时 :ref:`CONFIG_PARLIO_TX_ISR_CACHE_SAFE` 选项可以不用打开。
这样,在 Cache 被禁用时,中断也可运行,但是这也会增加 IRAM 的消耗。
关于性能
^^^^^^^^