mirror of
https://github.com/espressif/esp-idf
synced 2025-04-01 12:20:11 -04:00
Merge branch 'refactor/async_memcpy_allocate_dma_memory_v5.3' into 'release/v5.3'
refactor(async_memcpy): clean up memory allocation code (v5.3) See merge request espressif/esp-idf!31429
This commit is contained in:
commit
f215c2fd41
@ -68,7 +68,6 @@ typedef struct async_memcpy_transaction_t {
|
|||||||
/// @note - Number of transaction objects are determined by the backlog parameter
|
/// @note - Number of transaction objects are determined by the backlog parameter
|
||||||
typedef struct {
|
typedef struct {
|
||||||
async_memcpy_context_t parent; // Parent IO interface
|
async_memcpy_context_t parent; // Parent IO interface
|
||||||
size_t descriptor_align; // DMA descriptor alignment
|
|
||||||
size_t rx_int_mem_alignment; // DMA buffer alignment (both in size and address) for internal RX memory
|
size_t rx_int_mem_alignment; // DMA buffer alignment (both in size and address) for internal RX memory
|
||||||
size_t rx_ext_mem_alignment; // DMA buffer alignment (both in size and address) for external RX memory
|
size_t rx_ext_mem_alignment; // DMA buffer alignment (both in size and address) for external RX memory
|
||||||
size_t tx_int_mem_alignment; // DMA buffer alignment (both in size and address) for internal TX memory
|
size_t tx_int_mem_alignment; // DMA buffer alignment (both in size and address) for internal TX memory
|
||||||
@ -119,13 +118,10 @@ static esp_err_t esp_async_memcpy_install_gdma_template(const async_memcpy_confi
|
|||||||
mcp_gdma = heap_caps_calloc(1, sizeof(async_memcpy_gdma_context_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
|
mcp_gdma = heap_caps_calloc(1, sizeof(async_memcpy_gdma_context_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
|
||||||
ESP_GOTO_ON_FALSE(mcp_gdma, ESP_ERR_NO_MEM, err, TAG, "no mem for driver context");
|
ESP_GOTO_ON_FALSE(mcp_gdma, ESP_ERR_NO_MEM, err, TAG, "no mem for driver context");
|
||||||
uint32_t trans_queue_len = config->backlog ? config->backlog : DEFAULT_TRANSACTION_QUEUE_LENGTH;
|
uint32_t trans_queue_len = config->backlog ? config->backlog : DEFAULT_TRANSACTION_QUEUE_LENGTH;
|
||||||
// allocate memory for transaction pool
|
// allocate memory for transaction pool from internal memory because transaction structure contains DMA descriptor
|
||||||
uint32_t data_cache_line_size = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_INT_MEM, CACHE_TYPE_DATA);
|
mcp_gdma->transaction_pool = heap_caps_aligned_calloc(MCP_DMA_DESC_ALIGN, trans_queue_len, sizeof(async_memcpy_transaction_t),
|
||||||
uint32_t alignment = MAX(data_cache_line_size, MCP_DMA_DESC_ALIGN);
|
|
||||||
mcp_gdma->transaction_pool = heap_caps_aligned_calloc(alignment, trans_queue_len, sizeof(async_memcpy_transaction_t),
|
|
||||||
MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT | MALLOC_CAP_DMA);
|
MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT | MALLOC_CAP_DMA);
|
||||||
ESP_GOTO_ON_FALSE(mcp_gdma->transaction_pool, ESP_ERR_NO_MEM, err, TAG, "no mem for transaction pool");
|
ESP_GOTO_ON_FALSE(mcp_gdma->transaction_pool, ESP_ERR_NO_MEM, err, TAG, "no mem for transaction pool");
|
||||||
mcp_gdma->descriptor_align = alignment;
|
|
||||||
|
|
||||||
// create TX channel and RX channel, they should reside in the same DMA pair
|
// create TX channel and RX channel, they should reside in the same DMA pair
|
||||||
gdma_channel_alloc_config_t tx_alloc_config = {
|
gdma_channel_alloc_config_t tx_alloc_config = {
|
||||||
@ -382,14 +378,14 @@ static esp_err_t mcp_gdma_memcpy(async_memcpy_context_t *ctx, void *dst, void *s
|
|||||||
// calculate how many descriptors we want
|
// calculate how many descriptors we want
|
||||||
size_t max_single_dma_buffer = mcp_gdma->max_single_dma_buffer;
|
size_t max_single_dma_buffer = mcp_gdma->max_single_dma_buffer;
|
||||||
uint32_t num_desc_per_path = (n + max_single_dma_buffer - 1) / max_single_dma_buffer;
|
uint32_t num_desc_per_path = (n + max_single_dma_buffer - 1) / max_single_dma_buffer;
|
||||||
// allocate DMA descriptors, descriptors need a strict alignment
|
// allocate DMA descriptors from internal memory
|
||||||
trans->tx_desc_link = heap_caps_aligned_calloc(mcp_gdma->descriptor_align, num_desc_per_path, sizeof(mcp_dma_descriptor_t),
|
trans->tx_desc_link = heap_caps_aligned_calloc(MCP_DMA_DESC_ALIGN, num_desc_per_path, sizeof(mcp_dma_descriptor_t),
|
||||||
MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT | MALLOC_CAP_DMA);
|
MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT | MALLOC_CAP_DMA);
|
||||||
ESP_GOTO_ON_FALSE(trans->tx_desc_link, ESP_ERR_NO_MEM, err, TAG, "no mem for DMA descriptors");
|
ESP_GOTO_ON_FALSE(trans->tx_desc_link, ESP_ERR_NO_MEM, err, TAG, "no mem for DMA descriptors");
|
||||||
trans->tx_desc_nc = (mcp_dma_descriptor_t *)MCP_GET_NON_CACHE_ADDR(trans->tx_desc_link);
|
trans->tx_desc_nc = (mcp_dma_descriptor_t *)MCP_GET_NON_CACHE_ADDR(trans->tx_desc_link);
|
||||||
// don't have to allocate the EOF descriptor, we will use trans->eof_node as the RX EOF descriptor
|
// don't have to allocate the EOF descriptor, we will use trans->eof_node as the RX EOF descriptor
|
||||||
if (num_desc_per_path > 1) {
|
if (num_desc_per_path > 1) {
|
||||||
trans->rx_desc_link = heap_caps_aligned_calloc(mcp_gdma->descriptor_align, num_desc_per_path - 1, sizeof(mcp_dma_descriptor_t),
|
trans->rx_desc_link = heap_caps_aligned_calloc(MCP_DMA_DESC_ALIGN, num_desc_per_path - 1, sizeof(mcp_dma_descriptor_t),
|
||||||
MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT | MALLOC_CAP_DMA);
|
MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT | MALLOC_CAP_DMA);
|
||||||
ESP_GOTO_ON_FALSE(trans->rx_desc_link, ESP_ERR_NO_MEM, err, TAG, "no mem for DMA descriptors");
|
ESP_GOTO_ON_FALSE(trans->rx_desc_link, ESP_ERR_NO_MEM, err, TAG, "no mem for DMA descriptors");
|
||||||
trans->rx_desc_nc = (mcp_dma_descriptor_t *)MCP_GET_NON_CACHE_ADDR(trans->rx_desc_link);
|
trans->rx_desc_nc = (mcp_dma_descriptor_t *)MCP_GET_NON_CACHE_ADDR(trans->rx_desc_link);
|
||||||
|
@ -18,7 +18,6 @@
|
|||||||
#include "esp_async_memcpy.h"
|
#include "esp_async_memcpy.h"
|
||||||
#include "soc/soc_caps.h"
|
#include "soc/soc_caps.h"
|
||||||
#include "hal/dma_types.h"
|
#include "hal/dma_types.h"
|
||||||
#include "esp_dma_utils.h"
|
|
||||||
|
|
||||||
#define IDF_LOG_PERFORMANCE(item, value_fmt, value, ...) \
|
#define IDF_LOG_PERFORMANCE(item, value_fmt, value, ...) \
|
||||||
printf("[Performance][%s]: " value_fmt "\n", item, value, ##__VA_ARGS__)
|
printf("[Performance][%s]: " value_fmt "\n", item, value, ##__VA_ARGS__)
|
||||||
@ -55,21 +54,13 @@ static void async_memcpy_setup_testbench(memcpy_testbench_context_t *test_contex
|
|||||||
uint8_t *from_addr = NULL;
|
uint8_t *from_addr = NULL;
|
||||||
uint8_t *to_addr = NULL;
|
uint8_t *to_addr = NULL;
|
||||||
|
|
||||||
esp_dma_mem_info_t mem_info = {
|
uint32_t mem_caps = test_context->src_in_psram ? MALLOC_CAP_SPIRAM | MALLOC_CAP_DMA | MALLOC_CAP_8BIT : MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA | MALLOC_CAP_8BIT ;
|
||||||
.dma_alignment_bytes = test_context->align,
|
src_buf = heap_caps_aligned_calloc(test_context->align, 1, buffer_size, mem_caps);
|
||||||
};
|
TEST_ASSERT_NOT_NULL(src_buf);
|
||||||
if (test_context->src_in_psram) {
|
|
||||||
mem_info.extra_heap_caps = MALLOC_CAP_SPIRAM;
|
mem_caps = test_context->dst_in_psram ? MALLOC_CAP_SPIRAM | MALLOC_CAP_DMA | MALLOC_CAP_8BIT : MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA | MALLOC_CAP_8BIT ;
|
||||||
} else {
|
dst_buf = heap_caps_aligned_calloc(test_context->align, 1, buffer_size, mem_caps);
|
||||||
mem_info.extra_heap_caps = 0;
|
TEST_ASSERT_NOT_NULL(dst_buf);
|
||||||
}
|
|
||||||
TEST_ESP_OK(esp_dma_capable_calloc(1, buffer_size, &mem_info, (void **)&src_buf, NULL));
|
|
||||||
if (test_context->dst_in_psram) {
|
|
||||||
mem_info.extra_heap_caps = MALLOC_CAP_SPIRAM;
|
|
||||||
} else {
|
|
||||||
mem_info.extra_heap_caps = 0;
|
|
||||||
}
|
|
||||||
TEST_ESP_OK(esp_dma_capable_calloc(1, buffer_size, &mem_info, (void **)&dst_buf, NULL));
|
|
||||||
|
|
||||||
// adding extra offset
|
// adding extra offset
|
||||||
from_addr = src_buf + test_context->offset;
|
from_addr = src_buf + test_context->offset;
|
||||||
@ -111,13 +102,11 @@ TEST_CASE("memory copy the same buffer with different content", "[async mcp]")
|
|||||||
async_memcpy_config_t config = ASYNC_MEMCPY_DEFAULT_CONFIG();
|
async_memcpy_config_t config = ASYNC_MEMCPY_DEFAULT_CONFIG();
|
||||||
async_memcpy_handle_t driver = NULL;
|
async_memcpy_handle_t driver = NULL;
|
||||||
TEST_ESP_OK(esp_async_memcpy_install(&config, &driver));
|
TEST_ESP_OK(esp_async_memcpy_install(&config, &driver));
|
||||||
uint8_t *sbuf = NULL;
|
uint8_t *sbuf = heap_caps_aligned_calloc(4, 1, 256, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
|
||||||
uint8_t *dbuf = NULL;
|
uint8_t *dbuf = heap_caps_aligned_calloc(4, 1, 256, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
|
||||||
esp_dma_mem_info_t mem_info = {
|
TEST_ASSERT_NOT_NULL(sbuf);
|
||||||
.dma_alignment_bytes = 4,
|
TEST_ASSERT_NOT_NULL(dbuf);
|
||||||
};
|
|
||||||
TEST_ESP_OK(esp_dma_capable_calloc(1, 256, &mem_info, (void **)&sbuf, NULL));
|
|
||||||
TEST_ESP_OK(esp_dma_capable_calloc(1, 256, &mem_info, (void **)&dbuf, NULL));
|
|
||||||
for (int j = 0; j < 20; j++) {
|
for (int j = 0; j < 20; j++) {
|
||||||
TEST_ESP_OK(esp_async_memcpy(driver, dbuf, sbuf, 256, NULL, NULL));
|
TEST_ESP_OK(esp_async_memcpy(driver, dbuf, sbuf, 256, NULL, NULL));
|
||||||
vTaskDelay(pdMS_TO_TICKS(10));
|
vTaskDelay(pdMS_TO_TICKS(10));
|
||||||
@ -219,13 +208,10 @@ TEST_CASE("memory copy done callback", "[async mcp]")
|
|||||||
async_memcpy_handle_t driver = NULL;
|
async_memcpy_handle_t driver = NULL;
|
||||||
TEST_ESP_OK(esp_async_memcpy_install(&config, &driver));
|
TEST_ESP_OK(esp_async_memcpy_install(&config, &driver));
|
||||||
|
|
||||||
uint8_t *src_buf = NULL;
|
uint8_t *src_buf = heap_caps_aligned_calloc(4, 1, 256, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
|
||||||
uint8_t *dst_buf = NULL;
|
uint8_t *dst_buf = heap_caps_aligned_calloc(4, 1, 256, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
|
||||||
esp_dma_mem_info_t mem_info = {
|
TEST_ASSERT_NOT_NULL(src_buf);
|
||||||
.dma_alignment_bytes = 4,
|
TEST_ASSERT_NOT_NULL(dst_buf);
|
||||||
};
|
|
||||||
TEST_ESP_OK(esp_dma_capable_calloc(1, 256, &mem_info, (void **)&src_buf, NULL));
|
|
||||||
TEST_ESP_OK(esp_dma_capable_calloc(1, 256, &mem_info, (void **)&dst_buf, NULL));
|
|
||||||
|
|
||||||
SemaphoreHandle_t sem = xSemaphoreCreateBinary();
|
SemaphoreHandle_t sem = xSemaphoreCreateBinary();
|
||||||
TEST_ESP_OK(esp_async_memcpy(driver, dst_buf, src_buf, 256, test_async_memcpy_cb_v1, sem));
|
TEST_ESP_OK(esp_async_memcpy(driver, dst_buf, src_buf, 256, test_async_memcpy_cb_v1, sem));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user