forked from espressif/esp-idf
fix(parlio): reenable parlio rx driver cache safe test
This commit is contained in:
@ -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
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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,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");
|
||||
#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;
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
--------------------
|
||||
|
@ -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
|
||||
^^^^^^^^^^^
|
||||
|
||||
|
@ -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`` 字节的内存用于保存寄存器上下文。
|
||||
|
||||
应用示例
|
||||
--------
|
||||
|
@ -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 的消耗。
|
||||
|
||||
关于性能
|
||||
^^^^^^^^
|
||||
|
||||
|
Reference in New Issue
Block a user