mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 03:00:34 +03:00
Merge branch 'feat/esp_async_memcpy_blocking_api' into 'master'
feat(esp_driver_dma): add blocking async memcpy API See merge request espressif/esp-idf!49295
This commit is contained in:
@@ -174,6 +174,25 @@ esp_err_t esp_async_memcpy_uninstall(async_memcpy_handle_t mcp);
|
||||
*/
|
||||
esp_err_t esp_async_memcpy(async_memcpy_handle_t mcp, void *dst, void *src, size_t n, async_memcpy_isr_cb_t cb_isr, void *cb_args);
|
||||
|
||||
/**
|
||||
* @brief Blocking memory copy function with timeout
|
||||
*
|
||||
* @note This function is blocking and should not be called from interrupt context.
|
||||
* @note Only `timeout_ms=-1` is supported, which means waiting indefinitely.
|
||||
*
|
||||
* @param[in] mcp Handle of async memcpy driver that returned from `esp_async_memcpy_install`
|
||||
* @param[in] dst Destination address (copy to)
|
||||
* @param[in] src Source address (copy from)
|
||||
* @param[in] n Number of bytes to copy
|
||||
* @param[in] timeout_ms Timeout in milliseconds. Only -1 is supported.
|
||||
* @return
|
||||
* - ESP_OK: Copy memory successfully
|
||||
* - ESP_ERR_INVALID_ARG: Copy memory failed because of invalid argument
|
||||
* - ESP_ERR_INVALID_STATE: Function called from ISR context or driver in invalid state
|
||||
* - ESP_FAIL: Copy memory failed because of other error
|
||||
*/
|
||||
esp_err_t esp_memcpy_blocking(async_memcpy_handle_t mcp, void *dst, void *src, size_t n, int32_t timeout_ms);
|
||||
|
||||
#if SOC_ETM_SUPPORTED
|
||||
/**
|
||||
* @brief Async memory copy specific events that supported by the ETM module
|
||||
|
||||
@@ -4,6 +4,9 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_check.h"
|
||||
#include "esp_async_memcpy.h"
|
||||
#include "esp_async_memcpy_priv.h"
|
||||
@@ -22,6 +25,38 @@ esp_err_t esp_async_memcpy(async_memcpy_handle_t asmcp, void *dst, void *src, si
|
||||
return asmcp->memcpy(asmcp, dst, src, n, cb_isr, cb_args);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
SemaphoreHandle_t semaphore;
|
||||
StaticSemaphore_t semaphore_buffer;
|
||||
} memcpy_blocking_context_t;
|
||||
|
||||
static bool memcpy_blocking_callback(async_memcpy_handle_t mcp_hdl, async_memcpy_event_t *event, void *user_data)
|
||||
{
|
||||
BaseType_t task_woken = pdFALSE;
|
||||
memcpy_blocking_context_t *ctx = (memcpy_blocking_context_t *)user_data;
|
||||
(void)mcp_hdl;
|
||||
(void)event;
|
||||
|
||||
xSemaphoreGiveFromISR(ctx->semaphore, &task_woken);
|
||||
|
||||
return task_woken == pdTRUE;
|
||||
}
|
||||
|
||||
esp_err_t esp_memcpy_blocking(async_memcpy_handle_t asmcp, void *dst, void *src, size_t n, int32_t timeout_ms)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(asmcp && dst && src && n, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
|
||||
ESP_RETURN_ON_FALSE(!xPortInIsrContext(), ESP_ERR_INVALID_STATE, TAG, "called from ISR context is not allowed");
|
||||
ESP_RETURN_ON_FALSE(timeout_ms == -1, ESP_ERR_INVALID_ARG, TAG, "only timeout_ms=-1 is supported");
|
||||
|
||||
memcpy_blocking_context_t ctx = {};
|
||||
ctx.semaphore = xSemaphoreCreateBinaryStatic(&ctx.semaphore_buffer);
|
||||
|
||||
ESP_RETURN_ON_ERROR(esp_async_memcpy(asmcp, dst, src, n, memcpy_blocking_callback, &ctx), TAG, "failed to start memory copy");
|
||||
|
||||
xSemaphoreTake(ctx.semaphore, portMAX_DELAY);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
#if SOC_ETM_SUPPORTED
|
||||
esp_err_t esp_async_memcpy_new_etm_event(async_memcpy_handle_t asmcp, async_memcpy_etm_event_t event_type, esp_etm_event_handle_t *out_event)
|
||||
{
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
#include "soc/soc_caps.h"
|
||||
#include "esp_heap_caps.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "ccomp_timer.h"
|
||||
#include "esp_async_memcpy.h"
|
||||
@@ -102,8 +101,7 @@ static void test_memory_copy_with_same_buffer(async_memcpy_handle_t driver, asyn
|
||||
TEST_ASSERT_NOT_NULL(dbuf);
|
||||
|
||||
for (int j = 0; j < 20; j++) {
|
||||
TEST_ESP_OK(esp_async_memcpy(driver, dbuf, sbuf, 256, NULL, NULL));
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
TEST_ESP_OK(esp_memcpy_blocking(driver, dbuf, sbuf, 256, -1));
|
||||
for (int i = 0; i < 256; i++) {
|
||||
if (sbuf[i] != dbuf[i]) {
|
||||
printf("location[%d]:s=%d,d=%d\r\n", i, sbuf[i], dbuf[i]);
|
||||
@@ -151,17 +149,8 @@ TEST_CASE("memory copy the same buffer with different content", "[async mcp]")
|
||||
#endif // SOC_HAS(LP_AHB_GDMA)
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
static void test_memory_copy_blocking(async_memcpy_handle_t driver)
|
||||
{
|
||||
SemaphoreHandle_t sem = xSemaphoreCreateBinary();
|
||||
const uint32_t test_buffer_size[] = {256, 512, 1024, 2048, 4096, 5008};
|
||||
memcpy_testbench_context_t test_context = {
|
||||
.align = 16,
|
||||
@@ -177,13 +166,11 @@ static void test_memory_copy_blocking(async_memcpy_handle_t driver)
|
||||
}
|
||||
async_memcpy_setup_testbench(&test_context);
|
||||
|
||||
TEST_ESP_OK(esp_async_memcpy(driver, test_context.to_addr, test_context.from_addr, test_context.copy_size, test_async_memcpy_cb_v1, sem));
|
||||
TEST_ASSERT_EQUAL(pdTRUE, xSemaphoreTake(sem, pdMS_TO_TICKS(10)));
|
||||
TEST_ESP_OK(esp_memcpy_blocking(driver, test_context.to_addr, test_context.from_addr, test_context.copy_size, -1));
|
||||
async_memcpy_verify_and_clear_testbench(test_context.copy_size, test_context.src_buf, test_context.dst_buf,
|
||||
test_context.from_addr, test_context.to_addr);
|
||||
}
|
||||
}
|
||||
vSemaphoreDelete(sem);
|
||||
}
|
||||
|
||||
TEST_CASE("memory copy by DMA (blocking)", "[async mcp]")
|
||||
@@ -225,7 +212,6 @@ TEST_CASE("memory copy by DMA (blocking)", "[async mcp]")
|
||||
|
||||
[[maybe_unused]] static void test_memcpy_with_dest_addr_unaligned(async_memcpy_handle_t driver, bool src_in_psram, bool dst_in_psram)
|
||||
{
|
||||
SemaphoreHandle_t sem = xSemaphoreCreateBinary();
|
||||
const uint32_t test_buffer_size[] = {256, 512, 1024, 2048, 4096, 5012};
|
||||
memcpy_testbench_context_t test_context = {
|
||||
.align = 4,
|
||||
@@ -241,13 +227,11 @@ TEST_CASE("memory copy by DMA (blocking)", "[async mcp]")
|
||||
test_context.dst_offset = off + 1;
|
||||
async_memcpy_setup_testbench(&test_context);
|
||||
|
||||
TEST_ESP_OK(esp_async_memcpy(driver, test_context.to_addr, test_context.from_addr, test_context.copy_size, test_async_memcpy_cb_v1, sem));
|
||||
TEST_ASSERT_EQUAL(pdTRUE, xSemaphoreTake(sem, pdMS_TO_TICKS(10)));
|
||||
TEST_ESP_OK(esp_memcpy_blocking(driver, test_context.to_addr, test_context.from_addr, test_context.copy_size, -1));
|
||||
async_memcpy_verify_and_clear_testbench(test_context.copy_size, test_context.src_buf, test_context.dst_buf,
|
||||
test_context.from_addr, test_context.to_addr);
|
||||
}
|
||||
}
|
||||
vSemaphoreDelete(sem);
|
||||
}
|
||||
|
||||
TEST_CASE("memory copy with dest address unaligned", "[async mcp]")
|
||||
|
||||
Reference in New Issue
Block a user