|
@@ -1,5 +1,5 @@
|
|
|
/*
|
|
/*
|
|
|
- * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
|
|
|
|
|
|
+ * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
|
|
|
*
|
|
*
|
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
|
*/
|
|
*/
|
|
@@ -28,6 +28,7 @@
|
|
|
typedef struct {
|
|
typedef struct {
|
|
|
uint32_t seed;
|
|
uint32_t seed;
|
|
|
size_t buffer_size;
|
|
size_t buffer_size;
|
|
|
|
|
+ size_t copy_size;
|
|
|
uint8_t *src_buf;
|
|
uint8_t *src_buf;
|
|
|
uint8_t *dst_buf;
|
|
uint8_t *dst_buf;
|
|
|
uint8_t *from_addr;
|
|
uint8_t *from_addr;
|
|
@@ -43,62 +44,56 @@ static void async_memcpy_setup_testbench(memcpy_testbench_context_t *test_contex
|
|
|
srand(test_context->seed);
|
|
srand(test_context->seed);
|
|
|
printf("allocating memory buffer...\r\n");
|
|
printf("allocating memory buffer...\r\n");
|
|
|
size_t buffer_size = test_context->buffer_size;
|
|
size_t buffer_size = test_context->buffer_size;
|
|
|
|
|
+ size_t copy_size = buffer_size;
|
|
|
uint8_t *src_buf = NULL;
|
|
uint8_t *src_buf = NULL;
|
|
|
uint8_t *dst_buf = NULL;
|
|
uint8_t *dst_buf = NULL;
|
|
|
uint8_t *from_addr = NULL;
|
|
uint8_t *from_addr = NULL;
|
|
|
uint8_t *to_addr = NULL;
|
|
uint8_t *to_addr = NULL;
|
|
|
#if CONFIG_SPIRAM && SOC_AHB_GDMA_SUPPORT_PSRAM
|
|
#if CONFIG_SPIRAM && SOC_AHB_GDMA_SUPPORT_PSRAM
|
|
|
if (test_context->src_in_psram) {
|
|
if (test_context->src_in_psram) {
|
|
|
- src_buf = heap_caps_malloc(buffer_size, MALLOC_CAP_SPIRAM);
|
|
|
|
|
|
|
+ src_buf = heap_caps_aligned_alloc(test_context->align, buffer_size, MALLOC_CAP_SPIRAM);
|
|
|
} else {
|
|
} else {
|
|
|
- src_buf = heap_caps_malloc(buffer_size, MALLOC_CAP_8BIT | MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL);
|
|
|
|
|
|
|
+ src_buf = heap_caps_aligned_alloc(test_context->align, buffer_size, MALLOC_CAP_8BIT | MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL);
|
|
|
}
|
|
}
|
|
|
if (test_context->dst_in_psram) {
|
|
if (test_context->dst_in_psram) {
|
|
|
- dst_buf = heap_caps_calloc(1, buffer_size, MALLOC_CAP_SPIRAM);
|
|
|
|
|
|
|
+ dst_buf = heap_caps_aligned_alloc(test_context->align, buffer_size, MALLOC_CAP_SPIRAM);
|
|
|
} else {
|
|
} else {
|
|
|
- dst_buf = heap_caps_calloc(1, buffer_size, MALLOC_CAP_8BIT | MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL);
|
|
|
|
|
|
|
+ dst_buf = heap_caps_aligned_alloc(test_context->align, buffer_size, MALLOC_CAP_8BIT | MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL);
|
|
|
}
|
|
}
|
|
|
#else
|
|
#else
|
|
|
- src_buf = heap_caps_malloc(buffer_size, MALLOC_CAP_8BIT | MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL);
|
|
|
|
|
- dst_buf = heap_caps_calloc(1, buffer_size, MALLOC_CAP_8BIT | MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL);
|
|
|
|
|
|
|
+ src_buf = heap_caps_aligned_alloc(test_context->align, buffer_size, MALLOC_CAP_8BIT | MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL);
|
|
|
|
|
+ dst_buf = heap_caps_aligned_alloc(test_context->align, buffer_size, MALLOC_CAP_8BIT | MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL);
|
|
|
#endif
|
|
#endif
|
|
|
TEST_ASSERT_NOT_NULL_MESSAGE(src_buf, "allocate source buffer failed");
|
|
TEST_ASSERT_NOT_NULL_MESSAGE(src_buf, "allocate source buffer failed");
|
|
|
TEST_ASSERT_NOT_NULL_MESSAGE(dst_buf, "allocate destination buffer failed");
|
|
TEST_ASSERT_NOT_NULL_MESSAGE(dst_buf, "allocate destination buffer failed");
|
|
|
- // address alignment
|
|
|
|
|
- from_addr = (uint8_t *)ALIGN_UP((uint32_t)(src_buf), test_context->align);
|
|
|
|
|
- to_addr = (uint8_t *)ALIGN_UP((uint32_t)(dst_buf), test_context->align);
|
|
|
|
|
- uint8_t gap = MAX(from_addr - src_buf, to_addr - dst_buf);
|
|
|
|
|
- buffer_size -= gap;
|
|
|
|
|
- // size alignment
|
|
|
|
|
- buffer_size = ALIGN_DOWN(buffer_size, test_context->align);
|
|
|
|
|
// adding extra offset
|
|
// adding extra offset
|
|
|
- from_addr += test_context->offset;
|
|
|
|
|
- to_addr += test_context->offset;
|
|
|
|
|
- buffer_size -= test_context->offset;
|
|
|
|
|
|
|
+ from_addr = src_buf + test_context->offset;
|
|
|
|
|
+ to_addr = dst_buf + test_context->offset;
|
|
|
|
|
+ copy_size -= test_context->offset;
|
|
|
|
|
|
|
|
- printf("...size %zu Bytes, src@%p, dst@%p\r\n", buffer_size, from_addr, to_addr);
|
|
|
|
|
|
|
+ printf("...to copy size %zu Bytes, from @%p, to @%p\r\n", copy_size, from_addr, to_addr);
|
|
|
printf("fill src buffer with random data\r\n");
|
|
printf("fill src buffer with random data\r\n");
|
|
|
- for (int i = 0; i < buffer_size; i++) {
|
|
|
|
|
|
|
+ for (int i = 0; i < copy_size; i++) {
|
|
|
from_addr[i] = rand() % 256;
|
|
from_addr[i] = rand() % 256;
|
|
|
}
|
|
}
|
|
|
- // return value
|
|
|
|
|
- test_context->buffer_size = buffer_size;
|
|
|
|
|
|
|
+
|
|
|
|
|
+ // save context
|
|
|
|
|
+ test_context->copy_size = copy_size;
|
|
|
test_context->src_buf = src_buf;
|
|
test_context->src_buf = src_buf;
|
|
|
test_context->dst_buf = dst_buf;
|
|
test_context->dst_buf = dst_buf;
|
|
|
test_context->from_addr = from_addr;
|
|
test_context->from_addr = from_addr;
|
|
|
test_context->to_addr = to_addr;
|
|
test_context->to_addr = to_addr;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-static void async_memcpy_verify_and_clear_testbench(uint32_t seed, uint32_t buffer_size, uint8_t *src_buf, uint8_t *dst_buf, uint8_t *from_addr, uint8_t *to_addr)
|
|
|
|
|
|
|
+static void async_memcpy_verify_and_clear_testbench(uint32_t seed, uint32_t copy_size, uint8_t *src_buf, uint8_t *dst_buf, uint8_t *from_addr, uint8_t *to_addr)
|
|
|
{
|
|
{
|
|
|
srand(seed);
|
|
srand(seed);
|
|
|
- for (int i = 0; i < buffer_size; i++) {
|
|
|
|
|
- // check if source date has been copied to destination and source data not broken
|
|
|
|
|
- TEST_ASSERT_EQUAL_MESSAGE(rand() % 256, to_addr[i], "destination data doesn't match generator data");
|
|
|
|
|
|
|
+ // check if source date has been copied to destination and source data not broken
|
|
|
|
|
+ for (int i = 0; i < copy_size; i++) {
|
|
|
|
|
+ TEST_ASSERT_EQUAL_MESSAGE(rand() % 256, from_addr[i], "source data doesn't match generator data");
|
|
|
}
|
|
}
|
|
|
srand(seed);
|
|
srand(seed);
|
|
|
- for (int i = 0; i < buffer_size; i++) {
|
|
|
|
|
- // check if source data has been copied to destination
|
|
|
|
|
|
|
+ for (int i = 0; i < copy_size; i++) {
|
|
|
TEST_ASSERT_EQUAL_MESSAGE(rand() % 256, to_addr[i], "destination data doesn't match source data");
|
|
TEST_ASSERT_EQUAL_MESSAGE(rand() % 256, to_addr[i], "destination data doesn't match source data");
|
|
|
}
|
|
}
|
|
|
free(src_buf);
|
|
free(src_buf);
|
|
@@ -108,13 +103,13 @@ static void async_memcpy_verify_and_clear_testbench(uint32_t seed, uint32_t buff
|
|
|
TEST_CASE("memory copy the same buffer with different content", "[async mcp]")
|
|
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();
|
|
|
- config.backlog = 1;
|
|
|
|
|
- async_memcpy_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[256] = {0};
|
|
|
|
|
- uint8_t dbuf[256] = {0};
|
|
|
|
|
|
|
+ uint8_t *sbuf = heap_caps_malloc(256, MALLOC_CAP_8BIT | MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL);
|
|
|
|
|
+ uint8_t *dbuf = heap_caps_malloc(256, MALLOC_CAP_8BIT | MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL);
|
|
|
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));
|
|
|
for (int i = 0; i < 256; i++) {
|
|
for (int i = 0; i < 256; i++) {
|
|
|
if (sbuf[i] != dbuf[i]) {
|
|
if (sbuf[i] != dbuf[i]) {
|
|
|
printf("location[%d]:s=%d,d=%d\r\n", i, sbuf[i], dbuf[i]);
|
|
printf("location[%d]:s=%d,d=%d\r\n", i, sbuf[i], dbuf[i]);
|
|
@@ -125,15 +120,12 @@ TEST_CASE("memory copy the same buffer with different content", "[async mcp]")
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
TEST_ESP_OK(esp_async_memcpy_uninstall(driver));
|
|
TEST_ESP_OK(esp_async_memcpy_uninstall(driver));
|
|
|
|
|
+ free(sbuf);
|
|
|
|
|
+ free(dbuf);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-TEST_CASE("memory copy by DMA one by one", "[async mcp]")
|
|
|
|
|
|
|
+static void test_memory_copy_one_by_one(async_memcpy_handle_t driver)
|
|
|
{
|
|
{
|
|
|
- async_memcpy_config_t config = ASYNC_MEMCPY_DEFAULT_CONFIG();
|
|
|
|
|
- config.backlog = 4;
|
|
|
|
|
- async_memcpy_t driver = NULL;
|
|
|
|
|
- TEST_ESP_OK(esp_async_memcpy_install(&config, &driver));
|
|
|
|
|
-
|
|
|
|
|
uint32_t test_buffer_len[] = {256, 512, 1024, 2048, 4096, 5011};
|
|
uint32_t test_buffer_len[] = {256, 512, 1024, 2048, 4096, 5011};
|
|
|
memcpy_testbench_context_t test_context = {
|
|
memcpy_testbench_context_t test_context = {
|
|
|
.align = 4,
|
|
.align = 4,
|
|
@@ -144,20 +136,79 @@ TEST_CASE("memory copy by DMA one by one", "[async mcp]")
|
|
|
for (int off = 0; off < 4; off++) {
|
|
for (int off = 0; off < 4; off++) {
|
|
|
test_context.buffer_size = test_buffer_len[i];
|
|
test_context.buffer_size = test_buffer_len[i];
|
|
|
test_context.seed = i;
|
|
test_context.seed = i;
|
|
|
|
|
+ test_context.offset = off;
|
|
|
async_memcpy_setup_testbench(&test_context);
|
|
async_memcpy_setup_testbench(&test_context);
|
|
|
- TEST_ESP_OK(esp_async_memcpy(driver, test_context.to_addr, test_context.from_addr, test_context.buffer_size, NULL, NULL));
|
|
|
|
|
- async_memcpy_verify_and_clear_testbench(test_context.seed, test_context.buffer_size, test_context.src_buf, test_context.dst_buf, test_context.from_addr, test_context.to_addr);
|
|
|
|
|
- vTaskDelay(pdMS_TO_TICKS(100));
|
|
|
|
|
|
|
+
|
|
|
|
|
+ TEST_ESP_OK(esp_async_memcpy(driver, test_context.to_addr, test_context.from_addr, test_context.copy_size, NULL, NULL));
|
|
|
|
|
+ vTaskDelay(pdMS_TO_TICKS(10));
|
|
|
|
|
+ async_memcpy_verify_and_clear_testbench(test_context.seed, test_context.copy_size, test_context.src_buf,
|
|
|
|
|
+ test_context.dst_buf, test_context.from_addr, test_context.to_addr);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+TEST_CASE("memory copy by DMA one by one", "[async mcp]")
|
|
|
|
|
+{
|
|
|
|
|
+ async_memcpy_config_t config = {
|
|
|
|
|
+ .backlog = 4,
|
|
|
|
|
+ };
|
|
|
|
|
+ async_memcpy_handle_t driver = NULL;
|
|
|
|
|
|
|
|
|
|
+#if SOC_AHB_GDMA_SUPPORTED
|
|
|
|
|
+ printf("Testing memory by AHB GDMA\r\n");
|
|
|
|
|
+ TEST_ESP_OK(esp_async_memcpy_install_gdma_ahb(&config, &driver));
|
|
|
|
|
+ test_memory_copy_one_by_one(driver);
|
|
|
TEST_ESP_OK(esp_async_memcpy_uninstall(driver));
|
|
TEST_ESP_OK(esp_async_memcpy_uninstall(driver));
|
|
|
|
|
+#endif // SOC_AHB_GDMA_SUPPORTED
|
|
|
|
|
+
|
|
|
|
|
+#if SOC_AXI_GDMA_SUPPORTED
|
|
|
|
|
+ printf("Testing memory by AXI GDMA\r\n");
|
|
|
|
|
+ TEST_ESP_OK(esp_async_memcpy_install_gdma_axi(&config, &driver));
|
|
|
|
|
+ test_memory_copy_one_by_one(driver);
|
|
|
|
|
+ TEST_ESP_OK(esp_async_memcpy_uninstall(driver));
|
|
|
|
|
+#endif // SOC_AXI_GDMA_SUPPORTED
|
|
|
|
|
+
|
|
|
|
|
+#if SOC_CP_DMA_SUPPORTED
|
|
|
|
|
+ printf("Testing memory by CP DMA\r\n");
|
|
|
|
|
+ TEST_ESP_OK(esp_async_memcpy_install_cpdma(&config, &driver));
|
|
|
|
|
+ test_memory_copy_one_by_one(driver);
|
|
|
|
|
+ TEST_ESP_OK(esp_async_memcpy_uninstall(driver));
|
|
|
|
|
+#endif // SOC_CP_DMA_SUPPORTED
|
|
|
|
|
+
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+static bool test_async_memcpy_cb_v1(async_memcpy_handle_t mcp_hdl, async_memcpy_event_t *event, void *cb_args)
|
|
|
|
|
+{
|
|
|
|
|
+ SemaphoreHandle_t sem = (SemaphoreHandle_t)cb_args;
|
|
|
|
|
+ BaseType_t high_task_wakeup = pdFALSE;
|
|
|
|
|
+ xSemaphoreGiveFromISR(sem, &high_task_wakeup);
|
|
|
|
|
+ return high_task_wakeup == pdTRUE;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+TEST_CASE("memory copy done callback", "[async mcp]")
|
|
|
|
|
+{
|
|
|
|
|
+ async_memcpy_config_t config = {
|
|
|
|
|
+ // all default
|
|
|
|
|
+ };
|
|
|
|
|
+ async_memcpy_handle_t driver = NULL;
|
|
|
|
|
+ TEST_ESP_OK(esp_async_memcpy_install(&config, &driver));
|
|
|
|
|
+
|
|
|
|
|
+ uint8_t *src_buf = heap_caps_malloc(256, MALLOC_CAP_8BIT | MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL);
|
|
|
|
|
+ uint8_t *dst_buf = heap_caps_malloc(256, MALLOC_CAP_8BIT | MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL);
|
|
|
|
|
+
|
|
|
|
|
+ SemaphoreHandle_t sem = xSemaphoreCreateBinary();
|
|
|
|
|
+ TEST_ESP_OK(esp_async_memcpy(driver, dst_buf, src_buf, 256, test_async_memcpy_cb_v1, sem));
|
|
|
|
|
+ TEST_ASSERT_EQUAL(pdTRUE, xSemaphoreTake(sem, pdMS_TO_TICKS(1000)));
|
|
|
|
|
+ TEST_ESP_OK(esp_async_memcpy_uninstall(driver));
|
|
|
|
|
+ free(src_buf);
|
|
|
|
|
+ free(dst_buf);
|
|
|
|
|
+ vSemaphoreDelete(sem);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
TEST_CASE("memory copy by DMA on the fly", "[async mcp]")
|
|
TEST_CASE("memory copy by DMA on the fly", "[async mcp]")
|
|
|
{
|
|
{
|
|
|
async_memcpy_config_t config = ASYNC_MEMCPY_DEFAULT_CONFIG();
|
|
async_memcpy_config_t config = ASYNC_MEMCPY_DEFAULT_CONFIG();
|
|
|
- async_memcpy_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));
|
|
|
|
|
|
|
|
uint32_t test_buffer_len[] = {512, 1024, 2048, 4096, 5011};
|
|
uint32_t test_buffer_len[] = {512, 1024, 2048, 4096, 5011};
|
|
@@ -172,10 +223,10 @@ TEST_CASE("memory copy by DMA on the fly", "[async mcp]")
|
|
|
async_memcpy_setup_testbench(&test_context[i]);
|
|
async_memcpy_setup_testbench(&test_context[i]);
|
|
|
}
|
|
}
|
|
|
for (int i = 0; i < sizeof(test_buffer_len) / sizeof(test_buffer_len[0]); i++) {
|
|
for (int i = 0; i < sizeof(test_buffer_len) / sizeof(test_buffer_len[0]); i++) {
|
|
|
- TEST_ESP_OK(esp_async_memcpy(driver, test_context[i].to_addr, test_context[i].from_addr, test_context[i].buffer_size, NULL, NULL));
|
|
|
|
|
|
|
+ TEST_ESP_OK(esp_async_memcpy(driver, test_context[i].to_addr, test_context[i].from_addr, test_context[i].copy_size, NULL, NULL));
|
|
|
}
|
|
}
|
|
|
for (int i = 0; i < sizeof(test_buffer_len) / sizeof(test_buffer_len[0]); i++) {
|
|
for (int i = 0; i < sizeof(test_buffer_len) / sizeof(test_buffer_len[0]); i++) {
|
|
|
- async_memcpy_verify_and_clear_testbench(i, test_context[i].buffer_size, test_context[i].src_buf, test_context[i].dst_buf, test_context[i].from_addr, test_context[i].to_addr);
|
|
|
|
|
|
|
+ async_memcpy_verify_and_clear_testbench(i, test_context[i].copy_size, test_context[i].src_buf, test_context[i].dst_buf, test_context[i].from_addr, test_context[i].to_addr);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Non-aligned case
|
|
// Non-aligned case
|
|
@@ -186,10 +237,10 @@ TEST_CASE("memory copy by DMA on the fly", "[async mcp]")
|
|
|
async_memcpy_setup_testbench(&test_context[i]);
|
|
async_memcpy_setup_testbench(&test_context[i]);
|
|
|
}
|
|
}
|
|
|
for (int i = 0; i < sizeof(test_buffer_len) / sizeof(test_buffer_len[0]); i++) {
|
|
for (int i = 0; i < sizeof(test_buffer_len) / sizeof(test_buffer_len[0]); i++) {
|
|
|
- TEST_ESP_OK(esp_async_memcpy(driver, test_context[i].to_addr, test_context[i].from_addr, test_context[i].buffer_size, NULL, NULL));
|
|
|
|
|
|
|
+ TEST_ESP_OK(esp_async_memcpy(driver, test_context[i].to_addr, test_context[i].from_addr, test_context[i].copy_size, NULL, NULL));
|
|
|
}
|
|
}
|
|
|
for (int i = 0; i < sizeof(test_buffer_len) / sizeof(test_buffer_len[0]); i++) {
|
|
for (int i = 0; i < sizeof(test_buffer_len) / sizeof(test_buffer_len[0]); i++) {
|
|
|
- async_memcpy_verify_and_clear_testbench(i, test_context[i].buffer_size, test_context[i].src_buf, test_context[i].dst_buf, test_context[i].from_addr, test_context[i].to_addr);
|
|
|
|
|
|
|
+ async_memcpy_verify_and_clear_testbench(i, test_context[i].copy_size, test_context[i].src_buf, test_context[i].dst_buf, test_context[i].from_addr, test_context[i].to_addr);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
TEST_ESP_OK(esp_async_memcpy_uninstall(driver));
|
|
TEST_ESP_OK(esp_async_memcpy_uninstall(driver));
|
|
@@ -198,7 +249,7 @@ TEST_CASE("memory copy by DMA on the fly", "[async mcp]")
|
|
|
#define TEST_ASYNC_MEMCPY_BENCH_COUNTS (16)
|
|
#define TEST_ASYNC_MEMCPY_BENCH_COUNTS (16)
|
|
|
static int s_count = 0;
|
|
static int s_count = 0;
|
|
|
|
|
|
|
|
-static IRAM_ATTR bool test_async_memcpy_isr_cb(async_memcpy_t mcp_hdl, async_memcpy_event_t *event, void *cb_args)
|
|
|
|
|
|
|
+static IRAM_ATTR bool test_async_memcpy_isr_cb(async_memcpy_handle_t mcp_hdl, async_memcpy_event_t *event, void *cb_args)
|
|
|
{
|
|
{
|
|
|
SemaphoreHandle_t sem = (SemaphoreHandle_t)cb_args;
|
|
SemaphoreHandle_t sem = (SemaphoreHandle_t)cb_args;
|
|
|
BaseType_t high_task_wakeup = pdFALSE;
|
|
BaseType_t high_task_wakeup = pdFALSE;
|
|
@@ -217,7 +268,7 @@ static void memcpy_performance_test(uint32_t buffer_size)
|
|
|
config.backlog = (buffer_size / DMA_DESCRIPTOR_BUFFER_MAX_SIZE + 1) * TEST_ASYNC_MEMCPY_BENCH_COUNTS;
|
|
config.backlog = (buffer_size / DMA_DESCRIPTOR_BUFFER_MAX_SIZE + 1) * TEST_ASYNC_MEMCPY_BENCH_COUNTS;
|
|
|
config.sram_trans_align = 4; // at least 4 bytes aligned for SRAM transfer
|
|
config.sram_trans_align = 4; // at least 4 bytes aligned for SRAM transfer
|
|
|
config.psram_trans_align = 64; // at least 64 bytes aligned for PSRAM transfer
|
|
config.psram_trans_align = 64; // at least 64 bytes aligned for PSRAM transfer
|
|
|
- async_memcpy_t driver = NULL;
|
|
|
|
|
|
|
+ async_memcpy_handle_t driver = NULL;
|
|
|
int64_t elapse_us = 0;
|
|
int64_t elapse_us = 0;
|
|
|
float throughput = 0.0;
|
|
float throughput = 0.0;
|
|
|
TEST_ESP_OK(esp_async_memcpy_install(&config, &driver));
|
|
TEST_ESP_OK(esp_async_memcpy_install(&config, &driver));
|
|
@@ -233,7 +284,7 @@ static void memcpy_performance_test(uint32_t buffer_size)
|
|
|
s_count = 0;
|
|
s_count = 0;
|
|
|
ccomp_timer_start();
|
|
ccomp_timer_start();
|
|
|
for (int i = 0; i < TEST_ASYNC_MEMCPY_BENCH_COUNTS; i++) {
|
|
for (int i = 0; i < TEST_ASYNC_MEMCPY_BENCH_COUNTS; i++) {
|
|
|
- TEST_ESP_OK(esp_async_memcpy(driver, test_context.to_addr, test_context.from_addr, test_context.buffer_size, test_async_memcpy_isr_cb, sem));
|
|
|
|
|
|
|
+ TEST_ESP_OK(esp_async_memcpy(driver, test_context.to_addr, test_context.from_addr, test_context.copy_size, test_async_memcpy_isr_cb, sem));
|
|
|
}
|
|
}
|
|
|
// wait for done semaphore
|
|
// wait for done semaphore
|
|
|
TEST_ASSERT_EQUAL(pdTRUE, xSemaphoreTake(sem, pdMS_TO_TICKS(1000)));
|
|
TEST_ASSERT_EQUAL(pdTRUE, xSemaphoreTake(sem, pdMS_TO_TICKS(1000)));
|
|
@@ -247,7 +298,7 @@ static void memcpy_performance_test(uint32_t buffer_size)
|
|
|
elapse_us = ccomp_timer_stop();
|
|
elapse_us = ccomp_timer_stop();
|
|
|
throughput = (float)test_context.buffer_size * 1e6 * TEST_ASYNC_MEMCPY_BENCH_COUNTS / 1024 / 1024 / elapse_us;
|
|
throughput = (float)test_context.buffer_size * 1e6 * TEST_ASYNC_MEMCPY_BENCH_COUNTS / 1024 / 1024 / elapse_us;
|
|
|
IDF_LOG_PERFORMANCE("CPU_COPY", "%.2f MB/s, dir: SRAM->SRAM, size: %zu Bytes", throughput, test_context.buffer_size);
|
|
IDF_LOG_PERFORMANCE("CPU_COPY", "%.2f MB/s, dir: SRAM->SRAM, size: %zu Bytes", throughput, test_context.buffer_size);
|
|
|
- async_memcpy_verify_and_clear_testbench(test_context.seed, test_context.buffer_size, test_context.src_buf, test_context.dst_buf, test_context.from_addr, test_context.to_addr);
|
|
|
|
|
|
|
+ async_memcpy_verify_and_clear_testbench(test_context.seed, test_context.copy_size, test_context.src_buf, test_context.dst_buf, test_context.from_addr, test_context.to_addr);
|
|
|
|
|
|
|
|
#if CONFIG_SPIRAM && SOC_AHB_GDMA_SUPPORT_PSRAM
|
|
#if CONFIG_SPIRAM && SOC_AHB_GDMA_SUPPORT_PSRAM
|
|
|
// 2. PSRAM->PSRAM
|
|
// 2. PSRAM->PSRAM
|
|
@@ -257,7 +308,7 @@ static void memcpy_performance_test(uint32_t buffer_size)
|
|
|
s_count = 0;
|
|
s_count = 0;
|
|
|
ccomp_timer_start();
|
|
ccomp_timer_start();
|
|
|
for (int i = 0; i < TEST_ASYNC_MEMCPY_BENCH_COUNTS; i++) {
|
|
for (int i = 0; i < TEST_ASYNC_MEMCPY_BENCH_COUNTS; i++) {
|
|
|
- TEST_ESP_OK(esp_async_memcpy(driver, test_context.to_addr, test_context.from_addr, test_context.buffer_size, test_async_memcpy_isr_cb, sem));
|
|
|
|
|
|
|
+ TEST_ESP_OK(esp_async_memcpy(driver, test_context.to_addr, test_context.from_addr, test_context.copy_size, test_async_memcpy_isr_cb, sem));
|
|
|
}
|
|
}
|
|
|
// wait for done semaphore
|
|
// wait for done semaphore
|
|
|
TEST_ASSERT_EQUAL(pdTRUE, xSemaphoreTake(sem, pdMS_TO_TICKS(1000)));
|
|
TEST_ASSERT_EQUAL(pdTRUE, xSemaphoreTake(sem, pdMS_TO_TICKS(1000)));
|
|
@@ -271,7 +322,7 @@ static void memcpy_performance_test(uint32_t buffer_size)
|
|
|
elapse_us = ccomp_timer_stop();
|
|
elapse_us = ccomp_timer_stop();
|
|
|
throughput = (float)test_context.buffer_size * 1e6 * TEST_ASYNC_MEMCPY_BENCH_COUNTS / 1024 / 1024 / elapse_us;
|
|
throughput = (float)test_context.buffer_size * 1e6 * TEST_ASYNC_MEMCPY_BENCH_COUNTS / 1024 / 1024 / elapse_us;
|
|
|
IDF_LOG_PERFORMANCE("CPU_COPY", "%.2f MB/s, dir: PSRAM->PSRAM, size: %zu Bytes", throughput, test_context.buffer_size);
|
|
IDF_LOG_PERFORMANCE("CPU_COPY", "%.2f MB/s, dir: PSRAM->PSRAM, size: %zu Bytes", throughput, test_context.buffer_size);
|
|
|
- async_memcpy_verify_and_clear_testbench(test_context.seed, test_context.buffer_size, test_context.src_buf, test_context.dst_buf, test_context.from_addr, test_context.to_addr);
|
|
|
|
|
|
|
+ async_memcpy_verify_and_clear_testbench(test_context.seed, test_context.copy_size, test_context.src_buf, test_context.dst_buf, test_context.from_addr, test_context.to_addr);
|
|
|
|
|
|
|
|
// 3. PSRAM->SRAM
|
|
// 3. PSRAM->SRAM
|
|
|
test_context.src_in_psram = true;
|
|
test_context.src_in_psram = true;
|
|
@@ -280,7 +331,7 @@ static void memcpy_performance_test(uint32_t buffer_size)
|
|
|
s_count = 0;
|
|
s_count = 0;
|
|
|
ccomp_timer_start();
|
|
ccomp_timer_start();
|
|
|
for (int i = 0; i < TEST_ASYNC_MEMCPY_BENCH_COUNTS; i++) {
|
|
for (int i = 0; i < TEST_ASYNC_MEMCPY_BENCH_COUNTS; i++) {
|
|
|
- TEST_ESP_OK(esp_async_memcpy(driver, test_context.to_addr, test_context.from_addr, test_context.buffer_size, test_async_memcpy_isr_cb, sem));
|
|
|
|
|
|
|
+ TEST_ESP_OK(esp_async_memcpy(driver, test_context.to_addr, test_context.from_addr, test_context.copy_size, test_async_memcpy_isr_cb, sem));
|
|
|
}
|
|
}
|
|
|
// wait for done semaphore
|
|
// wait for done semaphore
|
|
|
TEST_ASSERT_EQUAL(pdTRUE, xSemaphoreTake(sem, pdMS_TO_TICKS(1000)));
|
|
TEST_ASSERT_EQUAL(pdTRUE, xSemaphoreTake(sem, pdMS_TO_TICKS(1000)));
|
|
@@ -294,7 +345,7 @@ static void memcpy_performance_test(uint32_t buffer_size)
|
|
|
elapse_us = ccomp_timer_stop();
|
|
elapse_us = ccomp_timer_stop();
|
|
|
throughput = (float)test_context.buffer_size * 1e6 * TEST_ASYNC_MEMCPY_BENCH_COUNTS / 1024 / 1024 / elapse_us;
|
|
throughput = (float)test_context.buffer_size * 1e6 * TEST_ASYNC_MEMCPY_BENCH_COUNTS / 1024 / 1024 / elapse_us;
|
|
|
IDF_LOG_PERFORMANCE("CPU_COPY", "%.2f MB/s, dir: PSRAM->SRAM, size: %zu Bytes", throughput, test_context.buffer_size);
|
|
IDF_LOG_PERFORMANCE("CPU_COPY", "%.2f MB/s, dir: PSRAM->SRAM, size: %zu Bytes", throughput, test_context.buffer_size);
|
|
|
- async_memcpy_verify_and_clear_testbench(test_context.seed, test_context.buffer_size, test_context.src_buf, test_context.dst_buf, test_context.from_addr, test_context.to_addr);
|
|
|
|
|
|
|
+ async_memcpy_verify_and_clear_testbench(test_context.seed, test_context.copy_size, test_context.src_buf, test_context.dst_buf, test_context.from_addr, test_context.to_addr);
|
|
|
|
|
|
|
|
// 4. SRAM->PSRAM
|
|
// 4. SRAM->PSRAM
|
|
|
test_context.src_in_psram = false;
|
|
test_context.src_in_psram = false;
|
|
@@ -303,7 +354,7 @@ static void memcpy_performance_test(uint32_t buffer_size)
|
|
|
s_count = 0;
|
|
s_count = 0;
|
|
|
ccomp_timer_start();
|
|
ccomp_timer_start();
|
|
|
for (int i = 0; i < TEST_ASYNC_MEMCPY_BENCH_COUNTS; i++) {
|
|
for (int i = 0; i < TEST_ASYNC_MEMCPY_BENCH_COUNTS; i++) {
|
|
|
- TEST_ESP_OK(esp_async_memcpy(driver, test_context.to_addr, test_context.from_addr, test_context.buffer_size, test_async_memcpy_isr_cb, sem));
|
|
|
|
|
|
|
+ TEST_ESP_OK(esp_async_memcpy(driver, test_context.to_addr, test_context.from_addr, test_context.copy_size, test_async_memcpy_isr_cb, sem));
|
|
|
}
|
|
}
|
|
|
// wait for done semaphore
|
|
// wait for done semaphore
|
|
|
TEST_ASSERT_EQUAL(pdTRUE, xSemaphoreTake(sem, pdMS_TO_TICKS(1000)));
|
|
TEST_ASSERT_EQUAL(pdTRUE, xSemaphoreTake(sem, pdMS_TO_TICKS(1000)));
|
|
@@ -317,7 +368,7 @@ static void memcpy_performance_test(uint32_t buffer_size)
|
|
|
elapse_us = ccomp_timer_stop();
|
|
elapse_us = ccomp_timer_stop();
|
|
|
throughput = (float)test_context.buffer_size * 1e6 * TEST_ASYNC_MEMCPY_BENCH_COUNTS / 1024 / 1024 / elapse_us;
|
|
throughput = (float)test_context.buffer_size * 1e6 * TEST_ASYNC_MEMCPY_BENCH_COUNTS / 1024 / 1024 / elapse_us;
|
|
|
IDF_LOG_PERFORMANCE("CPU_COPY", "%.2f MB/s, dir: SRAM->PSRAM, size: %zu Bytes", throughput, test_context.buffer_size);
|
|
IDF_LOG_PERFORMANCE("CPU_COPY", "%.2f MB/s, dir: SRAM->PSRAM, size: %zu Bytes", throughput, test_context.buffer_size);
|
|
|
- async_memcpy_verify_and_clear_testbench(test_context.seed, test_context.buffer_size, test_context.src_buf, test_context.dst_buf, test_context.from_addr, test_context.to_addr);
|
|
|
|
|
|
|
+ async_memcpy_verify_and_clear_testbench(test_context.seed, test_context.copy_size, test_context.src_buf, test_context.dst_buf, test_context.from_addr, test_context.to_addr);
|
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
TEST_ESP_OK(esp_async_memcpy_uninstall(driver));
|
|
TEST_ESP_OK(esp_async_memcpy_uninstall(driver));
|