Merge branch 'refactor/remove_gdma_deprecated_functions' into 'master'

refactor(dma)!: remove deprecated functions

Closes IDF-10942

See merge request espressif/esp-idf!39372
This commit is contained in:
morris
2025-06-12 15:51:15 +08:00
30 changed files with 101 additions and 882 deletions

View File

@@ -210,19 +210,14 @@ esp_err_t bitscrambler_loopback_run(bitscrambler_handle_t bs, void *buffer_in, s
return ESP_ERR_INVALID_SIZE;
}
int int_mem_cache_line_size = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_INT_MEM, CACHE_TYPE_DATA);
int ext_mem_cache_line_size = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_DATA);
bool need_cache_sync = esp_ptr_internal(buffer_in) ? (int_mem_cache_line_size > 0) : (ext_mem_cache_line_size > 0);
if (need_cache_sync) {
if (esp_cache_get_line_size_by_addr(buffer_in) > 0) {
//Note: we add the ESP_CACHE_MSYNC_FLAG_UNALIGNED flag for now as otherwise esp_cache_msync will complain about
//the size not being aligned... we miss out on a check to see if the address is aligned this way. This needs to
//be improved, but potentially needs a fix in esp_cache_msync not to check the size.
ESP_RETURN_ON_ERROR(esp_cache_msync(buffer_in, length_bytes_in, ESP_CACHE_MSYNC_FLAG_DIR_C2M | ESP_CACHE_MSYNC_FLAG_UNALIGNED),
TAG, "failed in cache sync for input buffer");
}
need_cache_sync = esp_ptr_internal(buffer_out) ? (int_mem_cache_line_size > 0) : (ext_mem_cache_line_size > 0);
if (need_cache_sync) {
if (esp_cache_get_line_size_by_addr(buffer_out) > 0) {
ESP_RETURN_ON_ERROR(esp_cache_msync(buffer_out, length_bytes_out, ESP_CACHE_MSYNC_FLAG_DIR_M2C),
TAG, "failed in cache sync for output buffer");
}

View File

@@ -199,16 +199,30 @@ esp_err_t jpeg_decoder_get_info(const uint8_t *in_buf, uint32_t inbuf_len, jpeg_
return ESP_OK;
}
static bool _check_buffer_alignment(void *buffer, uint32_t buffer_size, uint32_t alignment)
{
if (alignment == 0) {
alignment = 4; // basic align requirement from DMA
}
if ((uintptr_t)buffer & (alignment - 1)) {
return false;
}
if (buffer_size & (alignment - 1)) {
return false;
}
return true;
}
esp_err_t jpeg_decoder_process(jpeg_decoder_handle_t decoder_engine, const jpeg_decode_cfg_t *decode_cfg, const uint8_t *bit_stream, uint32_t stream_size, uint8_t *decode_outbuf, uint32_t outbuf_size, uint32_t *out_size)
{
ESP_RETURN_ON_FALSE(decoder_engine, ESP_ERR_INVALID_ARG, TAG, "jpeg decode handle is null");
ESP_RETURN_ON_FALSE(decode_cfg, ESP_ERR_INVALID_ARG, TAG, "jpeg decode config is null");
ESP_RETURN_ON_FALSE(decode_outbuf, ESP_ERR_INVALID_ARG, TAG, "jpeg decode picture buffer is null");
esp_dma_mem_info_t dma_mem_info = {
.dma_alignment_bytes = 4,
};
//TODO: IDF-9637
ESP_RETURN_ON_FALSE(esp_dma_is_buffer_alignment_satisfied(decode_outbuf, outbuf_size, dma_mem_info), ESP_ERR_INVALID_ARG, TAG, "jpeg decode decode_outbuf or out_buffer size is not aligned, please use jpeg_alloc_decoder_mem to malloc your buffer");
ESP_RETURN_ON_FALSE(decode_outbuf && outbuf_size, ESP_ERR_INVALID_ARG, TAG, "jpeg decode picture buffer is null");
uint32_t outbuf_cache_line_size = esp_cache_get_line_size_by_addr(decode_outbuf);
// check alignment of the output buffer
ESP_RETURN_ON_FALSE(_check_buffer_alignment(decode_outbuf, outbuf_size, outbuf_cache_line_size), ESP_ERR_INVALID_ARG, TAG,
"jpeg decode decode_outbuf or out_buffer size is not aligned, please use jpeg_alloc_decoder_mem to malloc your buffer");
esp_err_t ret = ESP_OK;
@@ -232,8 +246,10 @@ esp_err_t jpeg_decoder_process(jpeg_decoder_handle_t decoder_engine, const jpeg_
ESP_GOTO_ON_ERROR(jpeg_parse_header_info_to_hw(decoder_engine), err2, TAG, "write header info to hw failed");
ESP_GOTO_ON_ERROR(jpeg_dec_config_dma_descriptor(decoder_engine), err2, TAG, "config dma descriptor failed");
*out_size = decoder_engine->header_info->process_h * decoder_engine->header_info->process_v * decoder_engine->bit_per_pixel / 8;
ESP_GOTO_ON_FALSE((*out_size <= outbuf_size), ESP_ERR_INVALID_ARG, err2, TAG, "Given buffer size % " PRId32 " is smaller than actual jpeg decode output size % " PRId32 "the height and width of output picture size will be adjusted to 16 bytes aligned automatically", outbuf_size, *out_size);
if (out_size) {
*out_size = decoder_engine->header_info->process_h * decoder_engine->header_info->process_v * decoder_engine->bit_per_pixel / 8;
ESP_GOTO_ON_FALSE((*out_size <= outbuf_size), ESP_ERR_INVALID_ARG, err2, TAG, "Given buffer size % " PRId32 " is smaller than actual jpeg decode output size % " PRId32 "the height and width of output picture size will be adjusted to 16 bytes aligned automatically", outbuf_size, *out_size);
}
dma2d_trans_config_t trans_desc = {
.tx_channel_num = 1,
@@ -268,8 +284,10 @@ esp_err_t jpeg_decoder_process(jpeg_decoder_handle_t decoder_engine, const jpeg_
}
if (jpeg_dma2d_event.dma_evt & JPEG_DMA2D_RX_EOF) {
ret = esp_cache_msync((void*)decoder_engine->decoded_buf, outbuf_size, ESP_CACHE_MSYNC_FLAG_DIR_M2C);
assert(ret == ESP_OK);
if (outbuf_cache_line_size > 0) {
ret = esp_cache_msync((void*)decoder_engine->decoded_buf, outbuf_size, ESP_CACHE_MSYNC_FLAG_DIR_M2C);
assert(ret == ESP_OK);
}
break;
}
}

View File

@@ -636,16 +636,12 @@ esp_err_t parlio_tx_unit_transmit(parlio_tx_unit_handle_t tx_unit, const void *p
}
#endif // !SOC_PARLIO_TX_SUPPORT_EOF_FROM_DMA
size_t cache_line_size = 0;
size_t alignment = 0;
uint8_t cache_type = 0;
esp_ptr_external_ram(payload) ? (alignment = tx_unit->ext_mem_align, cache_type = CACHE_LL_LEVEL_EXT_MEM) : (alignment = tx_unit->int_mem_align, cache_type = CACHE_LL_LEVEL_INT_MEM);
size_t alignment = esp_ptr_external_ram(payload) ? tx_unit->ext_mem_align : tx_unit->int_mem_align;
// check alignment
ESP_RETURN_ON_FALSE(((uint32_t)payload & (alignment - 1)) == 0, ESP_ERR_INVALID_ARG, TAG, "payload address not aligned");
ESP_RETURN_ON_FALSE((payload_bits & (alignment - 1)) == 0, ESP_ERR_INVALID_ARG, TAG, "payload size not aligned");
cache_line_size = cache_hal_get_cache_line_size(cache_type, CACHE_TYPE_DATA);
if (cache_line_size > 0) {
if (esp_cache_get_line_size_by_addr(payload) > 0) {
// Write back to cache to synchronize the cache before DMA start
ESP_RETURN_ON_ERROR(esp_cache_msync((void *)payload, (payload_bits + 7) / 8,
ESP_CACHE_MSYNC_FLAG_DIR_C2M | ESP_CACHE_MSYNC_FLAG_UNALIGNED), TAG, "cache sync failed");

View File

@@ -50,7 +50,6 @@ extern "C" {
.set_input_delayline = &sdmmc_host_set_input_delayline, \
.dma_aligned_buffer = NULL, \
.pwr_ctrl_handle = NULL, \
.get_dma_info = NULL, \
.check_buffer_alignment = &sdmmc_host_check_buffer_alignment, \
.is_slot_set_to_uhs1 = &sdmmc_host_is_slot_set_to_uhs1, \
}

View File

@@ -291,19 +291,6 @@ esp_err_t sdmmc_host_set_input_delay(int slot, sdmmc_delay_phase_t delay_phase);
*/
esp_err_t sdmmc_host_set_input_delayline(int slot, sdmmc_delay_line_t delay_line);
/**
* @brief Get the DMA memory information for the host driver
*
* @deprecated This API is deprecated
*
* @param[in] slot slot number (SDMMC_HOST_SLOT_0 or SDMMC_HOST_SLOT_1)
* @param[out] dma_mem_info DMA memory information structure
* @return
* - ESP_OK: ON success.
* - ESP_ERR_INVALID_ARG: Invalid argument.
*/
esp_err_t sdmmc_host_get_dma_info(int slot, esp_dma_mem_info_t *dma_mem_info) __attribute__((deprecated("This API is deprecated")));
/**
* @brief Check if the buffer meets the alignment requirements
*

View File

@@ -233,18 +233,6 @@ esp_err_t sdmmc_host_io_int_wait(int slot, TickType_t timeout_ticks)
return ESP_OK;
}
esp_err_t sdmmc_host_get_dma_info(int slot, esp_dma_mem_info_t *dma_mem_info)
{
SLOT_CHECK(slot);
if (dma_mem_info == NULL) {
return ESP_ERR_INVALID_ARG;
}
dma_mem_info->extra_heap_caps = MALLOC_CAP_DMA;
dma_mem_info->dma_alignment_bytes = 4;
return ESP_OK;
}
bool sdmmc_host_check_buffer_alignment(int slot, const void *buf, size_t size)
{
assert(slot == 0 || slot == 1);

View File

@@ -63,7 +63,6 @@ typedef int sdspi_dev_handle_t;
.set_input_delayline = NULL, \
.dma_aligned_buffer = NULL, \
.pwr_ctrl_handle = NULL, \
.get_dma_info = NULL, \
.check_buffer_alignment = sdspi_host_check_buffer_alignment, \
.is_slot_set_to_uhs1 = NULL, \
}
@@ -223,19 +222,6 @@ esp_err_t sdspi_host_io_int_enable(sdspi_dev_handle_t handle);
*/
esp_err_t sdspi_host_io_int_wait(sdspi_dev_handle_t handle, TickType_t timeout_ticks);
/**
* @brief Get the DMA memory information for the host driver
*
* @deprecated This API is deprecated
*
* @param[in] slot Not used
* @param[out] dma_mem_info DMA memory information structure
* @return
* - ESP_OK: ON success.
* - ESP_ERR_INVALID_ARG: Invalid argument.
*/
esp_err_t sdspi_host_get_dma_info(int slot, esp_dma_mem_info_t *dma_mem_info) __attribute__((deprecated("This API is deprecated")));
/**
* @brief Check if the buffer meets the alignment requirements
*

View File

@@ -1003,14 +1003,6 @@ esp_err_t sdspi_host_io_int_wait(sdspi_dev_handle_t handle, TickType_t timeout_t
return ESP_OK;
}
esp_err_t sdspi_host_get_dma_info(int slot, esp_dma_mem_info_t *dma_mem_info)
{
(void)slot;
dma_mem_info->extra_heap_caps = MALLOC_CAP_DMA;
dma_mem_info->dma_alignment_bytes = 4;
return ESP_OK;
}
bool sdspi_host_check_buffer_alignment(int slot, const void *buf, size_t size)
{
//for future-proof

View File

@@ -77,7 +77,7 @@ if(NOT non_os_build)
endif()
if(CONFIG_SOC_GDMA_SUPPORTED)
list(APPEND srcs "dma/gdma.c" "deprecated/gdma_legacy.c")
list(APPEND srcs "dma/gdma.c")
if(CONFIG_SOC_GDMA_SUPPORT_SLEEP_RETENTION AND CONFIG_SOC_PAU_SUPPORTED)
list(APPEND srcs "dma/gdma_sleep_retention.c")
endif()

View File

@@ -1,52 +0,0 @@
/*
* SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "../dma/gdma_priv.h"
#include "hal/cache_hal.h"
#include "hal/cache_ll.h"
esp_err_t gdma_set_transfer_ability(gdma_channel_handle_t dma_chan, const gdma_transfer_ability_t *ability)
{
ESP_RETURN_ON_FALSE(dma_chan && ability, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
gdma_pair_t *pair = dma_chan->pair;
gdma_group_t *group = pair->group;
gdma_hal_context_t *hal = &group->hal;
size_t int_mem_alignment = ability->sram_trans_align;
size_t ext_mem_alignment = ability->psram_trans_align;
// alignment should be 2^n
ESP_RETURN_ON_FALSE((int_mem_alignment & (int_mem_alignment - 1)) == 0, ESP_ERR_INVALID_ARG,
TAG, "invalid sram alignment: %zu", int_mem_alignment);
uint32_t ext_mem_cache_line_size = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_DATA);
if (ext_mem_alignment == 0) {
// fall back to use the same size of the psram data cache line size
ext_mem_alignment = ext_mem_cache_line_size;
}
if ((ext_mem_cache_line_size > 0) && (ext_mem_alignment > ext_mem_cache_line_size)) {
ESP_RETURN_ON_FALSE(((ext_mem_alignment % ext_mem_cache_line_size) == 0), ESP_ERR_INVALID_ARG,
TAG, "ext_mem_alignment(%d) should be multiple of the ext_mem_cache_line_size(%"PRIu32")",
ext_mem_alignment, ext_mem_cache_line_size);
}
// if the DMA can't access the PSRAM, this HAL function is no-op
gdma_hal_set_burst_size(hal, pair->pair_id, dma_chan->direction, ext_mem_alignment);
// TX channel can always enable burst mode, no matter data alignment
bool en_burst = true;
if (dma_chan->direction == GDMA_CHANNEL_DIRECTION_RX) {
// RX channel burst mode depends on specific data alignment
en_burst = int_mem_alignment >= 4;
}
gdma_hal_enable_burst(hal, pair->pair_id, dma_chan->direction, en_burst, en_burst);
dma_chan->int_mem_alignment = int_mem_alignment;
dma_chan->ext_mem_alignment = ext_mem_alignment;
ESP_LOGD(TAG, "%s channel (%d,%d), (%u:%u) bytes aligned, burst %s", dma_chan->direction == GDMA_CHANNEL_DIRECTION_TX ? "tx" : "rx",
group->group_id, pair->pair_id, int_mem_alignment, ext_mem_alignment, en_burst ? "enabled" : "disabled");
return ESP_OK;
}

View File

@@ -32,18 +32,6 @@ menu "GDMA Configurations"
3. set the runtime log level to VERBOSE
Please enable this option by caution, as it will increase the binary size.
config GDMA_ISR_IRAM_SAFE
bool "GDMA ISR IRAM-Safe (Deprecated. Read Help!)"
default n
select GDMA_ISR_HANDLER_IN_IRAM
help
This will ensure the GDMA interrupt handler is IRAM-Safe, allow to avoid flash
cache misses, and also be able to run whilst the cache is disabled.
(e.g. SPI Flash write).
If this option is enabled, ALL GDMA channel's ISR handlers should be placed in IRAM, which is a overkill.
It's recommend to set the "isr_cache_safe" in the "gdma_channel_alloc_config_t".
Then other GDMA channels won't be influenced.
config GDMA_ENABLE_WEIGHTED_ARBITRATION
depends on SOC_GDMA_SUPPORT_WEIGHTED_ARBITRATION && IDF_EXPERIMENTAL_FEATURES
bool "GDMA enable weighted arbitration (Experimental)"
@@ -52,8 +40,6 @@ menu "GDMA Configurations"
Whether to enable the weighted arbitration for GDMA driver.
The default weight of each channel is 1. You need to set weight for each channel before transmissions.
If this option is enabled, the buffer should be aligned to the burst size.
endmenu # GDMA Configurations
menu "DW_GDMA Configurations"

View File

@@ -379,15 +379,8 @@ static esp_err_t mcp_gdma_memcpy(async_memcpy_context_t *ctx, void *dst, void *s
// read the cache line size of internal and external memory, we use this information to check if a given memory is behind the cache
// write back the source data if it's behind the cache
size_t int_mem_cache_line_size = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_INT_MEM, CACHE_TYPE_DATA);
size_t ext_mem_cache_line_size = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_DATA);
bool need_write_back = false;
if (esp_ptr_external_ram(src)) {
need_write_back = ext_mem_cache_line_size > 0;
} else if (esp_ptr_internal(src)) {
need_write_back = int_mem_cache_line_size > 0;
}
if (need_write_back) {
size_t cache_line_size = esp_cache_get_line_size_by_addr(src);
if (cache_line_size > 0) {
esp_cache_msync(src, n, ESP_CACHE_MSYNC_FLAG_DIR_C2M | ESP_CACHE_MSYNC_FLAG_UNALIGNED);
}

View File

@@ -143,222 +143,3 @@ size_t esp_dma_calculate_node_count(size_t buffer_size, size_t buffer_alignment,
// calculate the number of nodes
return (buffer_size + max_buffer_size_per_node - 1) / max_buffer_size_per_node;
}
esp_err_t esp_dma_capable_malloc(size_t size, const esp_dma_mem_info_t *dma_mem_info, void **out_ptr, size_t *actual_size)
{
ESP_RETURN_ON_FALSE_ISR(dma_mem_info && out_ptr, ESP_ERR_INVALID_ARG, TAG, "null pointer");
size_t alignment_bytes = 0;
//dma align
size_t dma_alignment_bytes = dma_mem_info->dma_alignment_bytes;
//cache align
int cache_flags = 0;
size_t cache_alignment_bytes = 0;
int heap_caps = dma_mem_info->extra_heap_caps | MALLOC_CAP_DMA;
if (dma_mem_info->extra_heap_caps & MALLOC_CAP_SPIRAM) {
cache_flags |= MALLOC_CAP_SPIRAM;
heap_caps = dma_mem_info->extra_heap_caps | MALLOC_CAP_SPIRAM;
/**
* This is a workaround because we don't have `MALLOC_CAP_DMA | MALLOC_CAP_SPIRAM`
* match when using heap_cap related allocations.
*/
heap_caps &= ~MALLOC_CAP_DMA;
}
// Return value unused if asserts are disabled
esp_err_t __attribute((unused)) ret = esp_cache_get_alignment(cache_flags, &cache_alignment_bytes);
assert(ret == ESP_OK);
//Get the least common multiple of two alignment
alignment_bytes = hal_utils_calc_lcm(dma_alignment_bytes, cache_alignment_bytes);
//malloc
size = ALIGN_UP_BY(size, alignment_bytes);
void *ptr = heap_caps_aligned_alloc(alignment_bytes, size, heap_caps);
ESP_RETURN_ON_FALSE_ISR(ptr, ESP_ERR_NO_MEM, TAG, "Not enough heap memory");
*out_ptr = ptr;
if (actual_size) {
*actual_size = size;
}
return ESP_OK;
}
esp_err_t esp_dma_capable_calloc(size_t calloc_num, size_t size, const esp_dma_mem_info_t *dma_mem_info, void **out_ptr, size_t *actual_size)
{
esp_err_t ret = ESP_FAIL;
size_t size_bytes = 0;
bool ovf = false;
ovf = __builtin_mul_overflow(calloc_num, size, &size_bytes);
ESP_RETURN_ON_FALSE_ISR(!ovf, ESP_ERR_INVALID_ARG, TAG, "wrong size, total size overflow");
void *ptr = NULL;
ret = esp_dma_capable_malloc(size_bytes, dma_mem_info, &ptr, actual_size);
if (ret == ESP_OK) {
memset(ptr, 0, size_bytes);
*out_ptr = ptr;
}
return ret;
}
static bool s_buf_in_region(const void *ptr, size_t size, esp_dma_buf_location_t location)
{
bool found = false;
if (location == ESP_DMA_BUF_LOCATION_INTERNAL) {
if (esp_ptr_dma_capable(ptr) && esp_ptr_dma_capable(ptr + size - 1)) {
found = true;
}
} else if (location == ESP_DMA_BUF_LOCATION_PSRAM) {
#if SOC_PSRAM_DMA_CAPABLE
if (esp_ptr_external_ram(ptr) && esp_ptr_external_ram(ptr + size - 1)) {
found = true;
}
#endif
}
return found;
}
static inline bool s_is_buf_aligned(intptr_t ptr, size_t alignment)
{
return (ptr % alignment == 0);
}
bool esp_dma_is_buffer_alignment_satisfied(const void *ptr, size_t size, esp_dma_mem_info_t dma_mem_info)
{
assert(ptr);
bool found = false;
for (int i = ESP_DMA_BUF_LOCATION_INTERNAL; i < ESP_DMA_BUF_LOCATION_AUTO; i++) {
if (s_buf_in_region(ptr, size, i)) {
found = true;
break;
}
}
if (!found) {
return false;
}
size_t alignment_bytes = 0;
//dma align
size_t dma_alignment_bytes = dma_mem_info.dma_alignment_bytes;
//cache align
int cache_flags = 0;
size_t cache_alignment_bytes = 0;
if (esp_ptr_external_ram(ptr)) {
cache_flags |= MALLOC_CAP_SPIRAM;
}
// Return value unused if asserts are disabled
esp_err_t __attribute__((unused)) ret = esp_cache_get_alignment(cache_flags, &cache_alignment_bytes);
assert(ret == ESP_OK);
//Get the least common multiple of two alignment
alignment_bytes = hal_utils_calc_lcm(dma_alignment_bytes, cache_alignment_bytes);
bool is_aligned = s_is_buf_aligned((intptr_t)ptr, alignment_bytes) && s_is_buf_aligned((intptr_t)size, alignment_bytes);
return is_aligned;
}
//-----------------------Deprecated APIs-----------------------//
esp_err_t s_legacy_malloc(size_t size, uint32_t flags, void **out_ptr, size_t *actual_size)
{
ESP_RETURN_ON_FALSE_ISR(out_ptr, ESP_ERR_INVALID_ARG, TAG, "null pointer");
int heap_caps = 0;
if (flags & ESP_DMA_MALLOC_FLAG_PSRAM) {
heap_caps |= MALLOC_CAP_SPIRAM;
} else {
heap_caps |= MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL;
}
esp_dma_mem_info_t dma_mem_info = {
.extra_heap_caps = heap_caps,
.dma_alignment_bytes = 4, //legacy API behaviour is only check max dma buffer alignment
};
ESP_RETURN_ON_ERROR_ISR(esp_dma_capable_malloc(size, &dma_mem_info, out_ptr, actual_size), TAG, "failed to do malloc");
return ESP_OK;
}
esp_err_t esp_dma_malloc(size_t size, uint32_t flags, void **out_ptr, size_t *actual_size)
{
return s_legacy_malloc(size, flags, out_ptr, actual_size);
}
esp_err_t esp_dma_calloc(size_t n, size_t size, uint32_t flags, void **out_ptr, size_t *actual_size)
{
ESP_RETURN_ON_FALSE_ISR(out_ptr, ESP_ERR_INVALID_ARG, TAG, "null pointer");
esp_err_t ret = ESP_FAIL;
size_t size_bytes = 0;
bool ovf = false;
ovf = __builtin_mul_overflow(n, size, &size_bytes);
ESP_RETURN_ON_FALSE_ISR(!ovf, ESP_ERR_INVALID_ARG, TAG, "wrong size, total size overflow");
void *ptr = NULL;
ret = s_legacy_malloc(size_bytes, flags, &ptr, actual_size);
if (ret == ESP_OK) {
memset(ptr, 0, size_bytes);
*out_ptr = ptr;
}
return ret;
}
static bool s_buf_in_region_legacy(const void *ptr, size_t size, esp_dma_buf_location_t location, int *heap_caps)
{
bool found = false;
if (location == ESP_DMA_BUF_LOCATION_INTERNAL) {
if (esp_ptr_dma_capable(ptr) && esp_ptr_dma_capable(ptr + size - 1)) {
*heap_caps = MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL;
found = true;
}
} else if (location == ESP_DMA_BUF_LOCATION_PSRAM) {
#if SOC_PSRAM_DMA_CAPABLE
if (esp_ptr_external_ram(ptr) && esp_ptr_external_ram(ptr + size - 1)) {
*heap_caps = MALLOC_CAP_SPIRAM;
found = true;
}
#endif
}
return found;
}
bool esp_dma_is_buffer_aligned(const void *ptr, size_t size, esp_dma_buf_location_t location)
{
assert(ptr);
bool found = false;
int heap_caps = 0;
if (location == ESP_DMA_BUF_LOCATION_AUTO) {
for (int i = ESP_DMA_BUF_LOCATION_INTERNAL; i < ESP_DMA_BUF_LOCATION_AUTO; i++) {
if (s_buf_in_region_legacy(ptr, size, i, &heap_caps)) {
found = true;
break;
}
}
} else if (location == ESP_DMA_BUF_LOCATION_INTERNAL) {
found = s_buf_in_region_legacy(ptr, size, ESP_DMA_BUF_LOCATION_INTERNAL, &heap_caps);
} else {
found = s_buf_in_region_legacy(ptr, size, ESP_DMA_BUF_LOCATION_PSRAM, &heap_caps);
}
if (!found) {
return false;
}
esp_dma_mem_info_t dma_mem_info = {
.extra_heap_caps = heap_caps,
.dma_alignment_bytes = 4, //legacy API behaviour is only check max dma buffer alignment
};
return esp_dma_is_buffer_alignment_satisfied(ptr, size, dma_mem_info);
}

View File

@@ -148,12 +148,7 @@ search_done:
alloc_tx_channel->base.pair = pair;
alloc_tx_channel->base.direction = GDMA_CHANNEL_DIRECTION_TX;
alloc_tx_channel->base.periph_id = GDMA_INVALID_PERIPH_TRIG;
// for backward compatibility, `CONFIG_GDMA_ISR_IRAM_SAFE` can still force ALL GDMA ISRs to be cache safe
#if CONFIG_GDMA_ISR_IRAM_SAFE
alloc_tx_channel->base.flags.isr_cache_safe = true;
#else
alloc_tx_channel->base.flags.isr_cache_safe = config->flags.isr_cache_safe;
#endif
alloc_tx_channel->base.del = gdma_del_tx_channel; // set channel deletion function
*ret_chan = &alloc_tx_channel->base; // return the installed channel
}
@@ -164,12 +159,7 @@ search_done:
alloc_rx_channel->base.pair = pair;
alloc_rx_channel->base.direction = GDMA_CHANNEL_DIRECTION_RX;
alloc_rx_channel->base.periph_id = GDMA_INVALID_PERIPH_TRIG;
// for backward compatibility, `CONFIG_GDMA_ISR_IRAM_SAFE` can still force ALL GDMA ISRs to be cache safe
#if CONFIG_GDMA_ISR_IRAM_SAFE
alloc_rx_channel->base.flags.isr_cache_safe = true;
#else
alloc_rx_channel->base.flags.isr_cache_safe = config->flags.isr_cache_safe;
#endif
alloc_rx_channel->base.del = gdma_del_rx_channel; // set channel deletion function
*ret_chan = &alloc_rx_channel->base; // return the installed channel
}

View File

@@ -1,119 +1,15 @@
/*
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include "esp_err.h"
#include "esp_heap_caps.h"
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief DMA Mem info
*/
typedef struct {
int extra_heap_caps; ///< extra heap caps based on MALLOC_CAP_DMA
size_t dma_alignment_bytes; ///< DMA alignment
} esp_dma_mem_info_t;
/**
* @brief Helper function for malloc a DMA capable memory buffer
*
* @note This API will take care of the cache alignment internally,
* you will need to set `esp_dma_mem_info_t: dma_alignment_bytes`
* with either the custom alignment or DMA alignment of used peripheral driver.
*
* @param[in] size Size in bytes, the amount of memory to allocate
* @param[in] dma_mem_info DMA and memory info, see `esp_dma_mem_info_t`
* @param[out] out_ptr A pointer to the memory allocated successfully
* @param[out] actual_size Actual size for allocation in bytes, when the size you specified doesn't meet the DMA alignment requirements, this value might be bigger than the size you specified. Set null if you don't care this value.
*
* @return
* - ESP_OK:
* - ESP_ERR_INVALID_ARG: Invalid argument
* - ESP_ERR_NO_MEM: No enough memory for allocation
*/
esp_err_t esp_dma_capable_malloc(size_t size, const esp_dma_mem_info_t *dma_mem_info, void **out_ptr, size_t *actual_size);
/**
* @brief Helper function for calloc a DMA capable memory buffer
*
* @param[in] calloc_num Number of elements to allocate
* @param[in] size Size in bytes, the amount of memory to allocate
* @param[in] dma_mem_info DMA and memory info, see `esp_dma_mem_info_t`
* @param[out] out_ptr A pointer to the memory allocated successfully
* @param[out] actual_size Actual size for allocation in bytes, when the size you specified doesn't meet the DMA alignment requirements, this value might be bigger than the size you specified. Set null if you don't care this value.
*
* @return
* - ESP_OK:
* - ESP_ERR_INVALID_ARG: Invalid argument
* - ESP_ERR_NO_MEM: No enough memory for allocation
*/
esp_err_t esp_dma_capable_calloc(size_t calloc_num, size_t size, const esp_dma_mem_info_t *dma_mem_info, void **out_ptr, size_t *actual_size);
/**
* @brief Helper function to check if a DMA buffer pointer and size meet both hardware alignment requirements and custom alignment requirements
*
* @param[in] ptr Pointer to the buffer
* @param[in] size Size of the buffer
* @param[in] dma_mem_info DMA and memory info, see `esp_dma_mem_info_t`
*
* @return
* - True: Buffer is aligned
* - False: Buffer is not aligned, or buffer is not DMA capable
*/
bool esp_dma_is_buffer_alignment_satisfied(const void *ptr, size_t size, esp_dma_mem_info_t dma_mem_info);
/**
* @brief Needed info to get GDMA alignment
*/
typedef struct {
bool is_desc; ///< allocate DMA descriptor
bool on_psram; ///< allocate DMA from the PSRAM
} dma_alignment_info_t;
//-----------------------Deprecated APIs-----------------------//
/**
* DMA malloc flags
*/
/**
* @brief Memory is in PSRAM
*/
#define ESP_DMA_MALLOC_FLAG_PSRAM BIT(0)
/**
* @note This API will use MAX alignment requirement
*/
esp_err_t esp_dma_malloc(size_t size, uint32_t flags, void **out_ptr, size_t *actual_size)
__attribute__((deprecated("esp_dma_malloc is deprecated, please use esp_dma_capable_malloc")));
/**
* @note This API will use MAX alignment requirement
*/
esp_err_t esp_dma_calloc(size_t n, size_t size, uint32_t flags, void **out_ptr, size_t *actual_size)
__attribute__((deprecated("esp_dma_calloc is deprecated, please use esp_dma_capable_calloc")));
/**
* @brief DMA buffer location
*/
typedef enum {
ESP_DMA_BUF_LOCATION_INTERNAL, ///< DMA buffer is in internal memory
ESP_DMA_BUF_LOCATION_PSRAM, ///< DMA buffer is in PSRAM
ESP_DMA_BUF_LOCATION_AUTO, ///< Auto detect buffer location, under this condition API will loop to search the buffer location
} esp_dma_buf_location_t;
/**
* @note This API will use MAX alignment requirement
*/
bool esp_dma_is_buffer_aligned(const void *ptr, size_t size, esp_dma_buf_location_t location)
__attribute__((deprecated("esp_dma_is_buffer_aligned is deprecated, please use esp_dma_is_buffer_alignment_satisfied")));
#ifdef __cplusplus
}

View File

@@ -484,52 +484,6 @@ esp_err_t gdma_crc_get_result(gdma_channel_handle_t dma_chan, uint32_t *result);
esp_err_t gdma_set_weight(gdma_channel_handle_t dma_chan, uint32_t weight);
#endif // SOC_GDMA_SUPPORT_WEIGHTED_ARBITRATION
/****************************************************************************************
* Deprecated APIs (will be removed in esp-idf 6.0)
****************************************************************************************/
/** @cond */
/**
* @brief Create GDMA channel (Legacy API)
*
* @param[in] config Pointer to a collection of configurations for allocating GDMA channel
* @param[out] ret_chan Returned channel handle
* @return
* - ESP_OK: Create DMA channel successfully
* - ESP_ERR_INVALID_ARG: Create DMA channel failed because of invalid argument
* - ESP_ERR_NO_MEM: Create DMA channel failed because out of memory
* - ESP_FAIL: Create DMA channel failed because of other error
*/
esp_err_t gdma_new_channel(const gdma_channel_alloc_config_t *config, gdma_channel_handle_t *ret_chan)
__attribute__((deprecated("please use gdma_new_ahb_channel or gdma_new_axi_channel respectively")));
/**
* @brief GDMA transfer ability
*
* @note The alignment set in this structure is **not** a guarantee that gdma driver will take care of the nonalignment cases.
* Actually the GDMA driver has no knowledge about the DMA buffer (address and size) used by upper layer.
* So it's the responsibility of the **upper layer** to take care of the buffer address and size.
*
*/
typedef struct {
size_t sram_trans_align; /*!< DMA transfer alignment for memory in SRAM, in bytes. The driver enables/disables burst mode based on this value. 0 means no alignment is required */
size_t psram_trans_align; /*!< DMA transfer alignment for memory in PSRAM, in bytes. The driver sets proper burst block size based on the alignment value. 0 means no alignment is required */
} gdma_transfer_ability_t;
/**
* @brief Set DMA channel transfer ability
*
* @param[in] dma_chan GDMA channel handle, allocated by `gdma_new_channel`
* @param[in] ability Transfer ability, e.g. alignment
* @return
* - ESP_OK: Set DMA channel transfer ability successfully
* - ESP_ERR_INVALID_ARG: Set DMA channel transfer ability failed because of invalid argument
* - ESP_FAIL: Set DMA channel transfer ability failed because of other error
*/
esp_err_t gdma_set_transfer_ability(gdma_channel_handle_t dma_chan, const gdma_transfer_ability_t *ability)
__attribute__((deprecated("please use gdma_config_transfer instead")));
/** @endcond */
#ifdef __cplusplus
}
#endif

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -52,11 +52,7 @@ typedef bool (*async_memcpy_isr_cb_t)(async_memcpy_handle_t mcp_hdl, async_memcp
typedef struct {
uint32_t backlog; /*!< Maximum number of transactions that can be prepared in the background */
uint32_t weight; /*!< Weight of async memcpy dma channel, higher weight means higher average bandwidth */
size_t sram_trans_align __attribute__((deprecated)); /*!< DMA transfer alignment (both in size and address) for SRAM memory */
union {
size_t psram_trans_align __attribute__((deprecated)); /*!< DMA transfer alignment (both in size and address) for PSRAM memory */
size_t dma_burst_size; /*!< DMA transfer burst size, in bytes */
};
size_t dma_burst_size; /*!< DMA transfer burst size, in bytes */
uint32_t flags; /*!< Extra flags to control async memcpy feature */
} async_memcpy_config_t;

View File

@@ -1,4 +1,4 @@
set(srcs "test_app_main.c" "test_dma_utils.c")
set(srcs "test_app_main.c")
if(CONFIG_SOC_ASYNC_MEMCPY_SUPPORTED)
list(APPEND srcs "test_async_memcpy.c")

View File

@@ -1,81 +0,0 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <string.h>
#include <inttypes.h>
#include "sdkconfig.h"
#include "unity.h"
#include "esp_log.h"
#include "esp_dma_utils.h"
#include "esp_private/esp_cache_private.h"
#include "esp_private/gdma.h"
#include "soc/soc_caps.h"
#define ALIGN_UP_BY(num, align) (((num) + ((align) - 1)) & ~((align) - 1))
static const char *TAG = "test_dma_utils";
#if CONFIG_SPIRAM
/**
* To test the API logic is correct, here we simply use max value under default sdkconfig
*/
#if CONFIG_IDF_TARGET_ESP32P4
#define TEST_BUFFER_PSRAM_ALIGNMENT 64
#else
#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
#define TEST_BUFFER_PSRAM_ALIGNMENT 4
#else
#define TEST_BUFFER_PSRAM_ALIGNMENT 32
#endif
#endif
TEST_CASE("test esp_dma_capable_malloc for PSRAM", "[dma_utils]")
{
size_t test_size = 0;
void *test_ptr = NULL;
size_t actual_size = 0;
esp_dma_mem_info_t dma_mem_info = {
.extra_heap_caps = MALLOC_CAP_SPIRAM,
.dma_alignment_bytes = 4,
};
//------ psram ------//
//aligned
test_size = TEST_BUFFER_PSRAM_ALIGNMENT;
ESP_LOGI(TAG, "to alloc 0x%zx", test_size);
TEST_ESP_OK(esp_dma_capable_malloc(test_size, &dma_mem_info, &test_ptr, &actual_size));
ESP_LOGI(TAG, "get test_ptr: %p, actual_size: 0x%zx", test_ptr, actual_size);
TEST_ASSERT((uint32_t)test_ptr % TEST_BUFFER_PSRAM_ALIGNMENT == 0);
TEST_ASSERT(test_size == actual_size);
free(test_ptr);
//unaligned
test_size = TEST_BUFFER_PSRAM_ALIGNMENT + TEST_BUFFER_PSRAM_ALIGNMENT / 2;
ESP_LOGI(TAG, "to alloc 0x%zx", test_size);
TEST_ESP_OK(esp_dma_capable_malloc(test_size, &dma_mem_info, &test_ptr, &actual_size));
ESP_LOGI(TAG, "get test_ptr: %p, actual_size: 0x%zx", test_ptr, actual_size);
TEST_ASSERT((uint32_t)test_ptr % TEST_BUFFER_PSRAM_ALIGNMENT == 0);
TEST_ASSERT(ALIGN_UP_BY(test_size, TEST_BUFFER_PSRAM_ALIGNMENT) == actual_size);
free(test_ptr);
}
#endif
TEST_CASE("test esp_dma_is_buffer_alignment_satisfied", "[dma_utils]")
{
size_t test_size = 64;
void *test_ptr = NULL;
esp_dma_mem_info_t dma_mem_info = {
.dma_alignment_bytes = 4,
};
TEST_ESP_OK(esp_dma_capable_malloc(test_size, &dma_mem_info, &test_ptr, NULL));
ESP_LOGI(TAG, "test_ptr %p", test_ptr);
bool is_aligned = esp_dma_is_buffer_alignment_satisfied(test_ptr, test_size, dma_mem_info);
TEST_ASSERT(is_aligned);
is_aligned = esp_dma_is_buffer_alignment_satisfied(test_ptr + 3, test_size, dma_mem_info);
TEST_ASSERT(!is_aligned);
}

View File

@@ -527,19 +527,16 @@ static esp_err_t panel_io_i80_tx_color(esp_lcd_panel_io_t *io, int lcd_cmd, cons
esp_lcd_i80_bus_t *bus = i80_device->bus;
lcd_i80_trans_descriptor_t *trans_desc = NULL;
assert(color_size <= bus->max_transfer_bytes && "color bytes too long, enlarge max_transfer_bytes");
uint32_t cache_line_size = 0;
if (esp_ptr_external_ram(color)) {
// check alignment
ESP_RETURN_ON_FALSE(((uint32_t)color & (bus->ext_mem_align - 1)) == 0, ESP_ERR_INVALID_ARG, TAG, "color address not aligned");
ESP_RETURN_ON_FALSE((color_size & (bus->ext_mem_align - 1)) == 0, ESP_ERR_INVALID_ARG, TAG, "color size not aligned");
cache_line_size = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_DATA);
} else {
// check alignment
ESP_RETURN_ON_FALSE(((uint32_t)color & (bus->int_mem_align - 1)) == 0, ESP_ERR_INVALID_ARG, TAG, "color address not aligned");
ESP_RETURN_ON_FALSE((color_size & (bus->int_mem_align - 1)) == 0, ESP_ERR_INVALID_ARG, TAG, "color size not aligned");
cache_line_size = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_INT_MEM, CACHE_TYPE_DATA);
}
if (cache_line_size > 0) {
if (esp_cache_get_line_size_by_addr(color) > 0) {
// flush data from cache to the physical memory
esp_cache_msync((void *)color, color_size, ESP_CACHE_MSYNC_FLAG_DIR_C2M | ESP_CACHE_MSYNC_FLAG_UNALIGNED);
}

View File

@@ -20,6 +20,7 @@
#include "hal/cache_ll.h"
#include "esp_cache.h"
#include "esp_compiler.h"
#include "esp_memory_utils.h"
#include "esp_private/esp_cache_private.h"
#include "esp_private/critical_section.h"
@@ -147,125 +148,6 @@ esp_err_t esp_cache_msync(void *addr, size_t size, int flags)
return ESP_OK;
}
//The esp_cache_aligned_malloc function is marked deprecated but also called by other
//(also deprecated) functions in this file. In order to work around that generating warnings, it's
//split into a non-deprecated internal function and the stubbed external deprecated function.
static esp_err_t esp_cache_aligned_malloc_internal(size_t size, uint32_t heap_caps, void **out_ptr, size_t *actual_size)
{
ESP_RETURN_ON_FALSE_ISR(out_ptr, ESP_ERR_INVALID_ARG, TAG, "null pointer");
uint32_t valid_caps = MALLOC_CAP_SPIRAM | MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA;
ESP_RETURN_ON_FALSE_ISR((heap_caps & valid_caps) > 0, ESP_ERR_INVALID_ARG, TAG, "not supported cap matches");
uint32_t cache_level = CACHE_LL_LEVEL_INT_MEM;
uint32_t data_cache_line_size = 0;
void *ptr = NULL;
if (heap_caps & MALLOC_CAP_SPIRAM) {
cache_level = CACHE_LL_LEVEL_EXT_MEM;
}
data_cache_line_size = cache_hal_get_cache_line_size(cache_level, CACHE_TYPE_DATA);
if (data_cache_line_size == 0) {
//default alignment
data_cache_line_size = 4;
}
size = ALIGN_UP_BY(size, data_cache_line_size);
ptr = heap_caps_aligned_alloc(data_cache_line_size, size, (uint32_t)heap_caps);
if (!ptr) {
return ESP_ERR_NO_MEM;
}
*out_ptr = ptr;
if (actual_size) {
*actual_size = size;
}
return ESP_OK;
}
//this is the deprecated stub for the above function
esp_err_t esp_cache_aligned_malloc(size_t size, uint32_t heap_caps, void **out_ptr, size_t *actual_size)
{
return esp_cache_aligned_malloc_internal(size, heap_caps, out_ptr, actual_size);
}
esp_err_t esp_cache_aligned_malloc_prefer(size_t size, void **out_ptr, size_t *actual_size, size_t flag_nums, ...)
{
ESP_RETURN_ON_FALSE_ISR(out_ptr, ESP_ERR_INVALID_ARG, TAG, "null pointer");
esp_err_t ret = ESP_FAIL;
va_list argp;
uint32_t flags = 0;
va_start(argp, flag_nums);
*out_ptr = NULL;
while (flag_nums--) {
flags = va_arg(argp, int);
ret = esp_cache_aligned_malloc_internal(size, flags, out_ptr, actual_size);
if (ret == ESP_OK) {
break;
}
}
va_end(argp);
return ret;
}
esp_err_t esp_cache_aligned_calloc(size_t n, size_t size, uint32_t heap_caps, void **out_ptr, size_t *actual_size)
{
ESP_RETURN_ON_FALSE_ISR(out_ptr, ESP_ERR_INVALID_ARG, TAG, "null pointer");
esp_err_t ret = ESP_FAIL;
size_t size_bytes = 0;
bool ovf = false;
ovf = __builtin_mul_overflow(n, size, &size_bytes);
ESP_RETURN_ON_FALSE_ISR(!ovf, ESP_ERR_INVALID_ARG, TAG, "wrong size, total size overflow");
void *ptr = NULL;
ret = esp_cache_aligned_malloc_internal(size_bytes, heap_caps, &ptr, actual_size);
if (ret == ESP_OK) {
memset(ptr, 0, size_bytes);
*out_ptr = ptr;
}
return ret;
}
esp_err_t esp_cache_aligned_calloc_prefer(size_t n, size_t size, void **out_ptr, size_t *actual_size, size_t flag_nums, ...)
{
ESP_RETURN_ON_FALSE_ISR(out_ptr, ESP_ERR_INVALID_ARG, TAG, "null pointer");
esp_err_t ret = ESP_FAIL;
size_t size_bytes = 0;
bool ovf = false;
*out_ptr = NULL;
ovf = __builtin_mul_overflow(n, size, &size_bytes);
ESP_RETURN_ON_FALSE_ISR(!ovf, ESP_ERR_INVALID_ARG, TAG, "wrong size, total size overflow");
void *ptr = NULL;
va_list argp;
va_start(argp, flag_nums);
int arg;
for (int i = 0; i < flag_nums; i++) {
arg = va_arg(argp, int);
ret = esp_cache_aligned_malloc_internal(size_bytes, arg, &ptr, actual_size);
if (ret == ESP_OK) {
ESP_COMPILER_DIAGNOSTIC_PUSH_IGNORE("-Wanalyzer-null-argument")
memset(ptr, 0, size_bytes);
*out_ptr = ptr;
ESP_COMPILER_DIAGNOSTIC_POP("-Wanalyzer-null-argument")
break;
}
}
va_end(argp);
return ret;
}
esp_err_t esp_cache_get_alignment(uint32_t heap_caps, size_t *out_alignment)
{
ESP_RETURN_ON_FALSE(out_alignment, ESP_ERR_INVALID_ARG, TAG, "null pointer");
@@ -283,3 +165,19 @@ esp_err_t esp_cache_get_alignment(uint32_t heap_caps, size_t *out_alignment)
return ESP_OK;
}
size_t esp_cache_get_line_size_by_addr(const void *addr)
{
if (!addr) {
return 0;
}
size_t data_cache_line_size = 0;
if (esp_ptr_external_ram(addr)) {
data_cache_line_size = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_DATA);
} else if (esp_ptr_internal(addr)) {
data_cache_line_size = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_INT_MEM, CACHE_TYPE_DATA);
}
return data_cache_line_size;
}

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -79,6 +79,16 @@ extern "C" {
*/
esp_err_t esp_cache_msync(void *addr, size_t size, int flags);
/**
* @brief Get the cache line size by address
*
* @param[in] addr The buffer address to examine
*
* @return The cache line size in bytes.
* Return 0 if the memory (that the address points to) is not cacheable.
*/
size_t esp_cache_get_line_size_by_addr(const void *addr);
#ifdef __cplusplus
}
#endif

View File

@@ -67,98 +67,6 @@ void esp_cache_freeze_caches_disable_interrupts(void);
void esp_cache_unfreeze_caches_enable_interrupts(void);
#endif
/**
* @brief Helper function for malloc a cache aligned data memory buffer
*
* @note Now only support 'MALLOC_CAP_INTERNAL', 'MALLOC_CAP_DMA' and 'MALLOC_CAP_SPIRAM'
*
* @param[in] size Size in bytes, the amount of memory to allocate
* @param[in] heap_caps Flags, see `MALLOC_CAP_x`
* @param[out] out_ptr A pointer to the memory allocated successfully
* @param[out] actual_size Actual size for allocation in bytes, when the size you specified doesn't meet the cache alignment requirements, this value might be bigger than the size you specified. Set null if you don't care this value.
*
* @deprecated This function is deprecated and will be removed in the future.
* Use 'heap_caps_malloc' with MALLOC_CAP_CACHE_ALIGNED caps instead
*
* @return
* - ESP_OK:
* - ESP_ERR_INVALID_ARG: Invalid argument
* - ESP_ERR_NO_MEM: No enough memory for allocation
*/
__attribute__((deprecated("Use 'heap_caps_malloc' with MALLOC_CAP_CACHE_ALIGNED caps instead")))
esp_err_t esp_cache_aligned_malloc(size_t size, uint32_t heap_caps, void **out_ptr, size_t *actual_size);
/**
* @brief Helper function for malloc a cache aligned data memory buffer as preference in decreasing order.
*
* @note Now only support 'MALLOC_CAP_INTERNAL', 'MALLOC_CAP_DMA' and 'MALLOC_CAP_SPIRAM'
*
* @param[in] size Size in bytes, the amount of memory to allocate
* @param[out] out_ptr A pointer to the memory allocated successfully
* @param[out] actual_size Actual size for allocation in bytes, when the size you specified doesn't meet the cache alignment requirements, this value might be bigger than the size you specified. Set null if you don't care this value.
* @param[in] flag_nums Number of variable parameters
* @param[in] spread param The spread params are bitwise OR of Flags, see `MALLOC_CAP_x`. This API prefers to allocate memory with the first parameter. If failed, allocate memory with
* the next parameter. It will try in this order until allocating a chunk of memory successfully
* or fail to allocate memories with any of the parameters.
*
* @deprecated This function is deprecated and will be removed in the future.
* Use 'heap_caps_malloc_prefer' with MALLOC_CAP_CACHE_ALIGNED caps instead
*
* @return
* - ESP_OK:
* - ESP_ERR_INVALID_ARG: Invalid argument
* - ESP_ERR_NO_MEM: No enough memory for allocation
*/
__attribute__((deprecated("Use 'heap_caps_malloc_prefer' with MALLOC_CAP_CACHE_ALIGNED caps instead")))
esp_err_t esp_cache_aligned_malloc_prefer(size_t size, void **out_ptr, size_t *actual_size, size_t flag_nums, ...);
/**
* @brief Helper function for calloc a cache aligned data memory buffer
*
* @note Now only support 'MALLOC_CAP_INTERNAL', 'MALLOC_CAP_DMA' and 'MALLOC_CAP_SPIRAM'
*
* @param[in] n Number of continuing chunks of memory to allocate
* @param[in] size Size of one chunk, in bytes
* @param[in] heap_caps Flags, see `MALLOC_CAP_x`
* @param[out] out_ptr A pointer to the memory allocated successfully
* @param[out] actual_size Actual size for allocation in bytes, when the size you specified doesn't meet the cache alignment requirements, this value might be bigger than the size you specified. Set null if you don't care this value.
*
* @deprecated This function is deprecated and will be removed in the future.
* Use 'heap_caps_calloc' with MALLOC_CAP_CACHE_ALIGNED caps instead
*
* @return
* - ESP_OK:
* - ESP_ERR_INVALID_ARG: Invalid argument
* - ESP_ERR_NO_MEM: No enough memory for allocation
*/
__attribute__((deprecated("Use 'heap_caps_calloc' with MALLOC_CAP_CACHE_ALIGNED caps instead")))
esp_err_t esp_cache_aligned_calloc(size_t n, size_t size, uint32_t heap_caps, void **out_ptr, size_t *actual_size);
/**
* @brief Helper function for calloc a cache aligned data memory buffer as preference in decreasing order.
*
* @note Now only support 'MALLOC_CAP_INTERNAL', 'MALLOC_CAP_DMA' and 'MALLOC_CAP_SPIRAM'
*
* @param[in] n Number of continuing chunks of memory to allocate
* @param[in] size Size in bytes, the amount of memory to allocate
* @param[out] out_ptr A pointer to the memory allocated successfully
* @param[out] actual_size Actual size for allocation in bytes, when the size you specified doesn't meet the cache alignment requirements, this value might be bigger than the size you specified. Set null if you don't care this value.
* @param[in] flag_nums Number of variable parameters
* @param[in] spread param The spread params are bitwise OR of Flags, see `MALLOC_CAP_x`. This API prefers to allocate memory with the first parameter. If failed, allocate memory with
* the next parameter. It will try in this order until allocating a chunk of memory successfully
* or fail to allocate memories with any of the parameters.
*
* @deprecated This function is deprecated and will be removed in the future.
* Use 'heap_caps_calloc_prefer' with MALLOC_CAP_CACHE_ALIGNED caps instead
*
* @return
* - ESP_OK:
* - ESP_ERR_INVALID_ARG: Invalid argument
* - ESP_ERR_NO_MEM: No enough memory for allocation
*/
__attribute__((deprecated("Use 'heap_caps_calloc' with MALLOC_CAP_CACHE_ALIGNED caps instead")))
esp_err_t esp_cache_aligned_calloc_prefer(size_t n, size_t size, void **out_ptr, size_t *actual_size, size_t flag_nums, ...);
/**
* @brief Get Cache alignment requirement for data
*

View File

@@ -1,6 +1,6 @@
set(srcs "test_app_main.c")
list(APPEND srcs "test_mmap.c" "test_cache_msync_malloc.c")
list(APPEND srcs "test_mmap.c")
if(CONFIG_SOC_CACHE_WRITEBACK_SUPPORTED)
list(APPEND srcs "test_cache_msync.c")

View File

@@ -1,47 +0,0 @@
/*
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "sdkconfig.h"
#include <sys/param.h>
#include <string.h>
#include "inttypes.h"
#include "esp_log.h"
#include "esp_attr.h"
#include "unity.h"
#include "esp_private/esp_cache_private.h"
#include "esp_memory_utils.h"
const static char *TAG = "CACHE_MALLOC_TEST";
TEST_CASE("test esp_cache_aligned_malloc_prefer", "[cache]")
{
void *ptr = NULL;
size_t actual_size = 0;
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
TEST_ESP_OK(esp_cache_aligned_malloc_prefer(40, &ptr, &actual_size, 1, MALLOC_CAP_DMA, 0));
#pragma GCC diagnostic pop
TEST_ASSERT(esp_ptr_dma_capable(ptr));
ESP_LOGI(TAG, "actual size: 0x%x", actual_size);
free(ptr);
}
TEST_CASE("test esp_cache_aligned_calloc_prefer", "[cache]")
{
void *ptr = NULL;
size_t actual_size = 0;
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
TEST_ESP_OK(esp_cache_aligned_calloc_prefer(1, 40, &ptr, &actual_size, 1, MALLOC_CAP_DMA, 0));
#pragma GCC diagnostic pop
TEST_ASSERT(esp_ptr_dma_capable(ptr));
ESP_LOGI(TAG, "actual size: 0d%d", actual_size);
free(ptr);
}

View File

@@ -226,7 +226,6 @@ typedef struct {
esp_err_t (*set_input_delayline)(int slot, sdmmc_delay_line_t delay_line); /*!< set input delay line */
void* dma_aligned_buffer; /*!< Leave it NULL. Reserved for cache aligned buffers for SDIO mode */
sd_pwr_ctrl_handle_t pwr_ctrl_handle; /*!< Power control handle */
esp_err_t (*get_dma_info)(int slot, esp_dma_mem_info_t *dma_mem_info); /*!< host function to dma memory information*/
bool (*check_buffer_alignment)(int slot, const void *buf, size_t size); /*!< Check if buffer meets alignment requirements */
esp_err_t (*is_slot_set_to_uhs1)(int slot, bool *is_uhs1); /*!< host slot is set to uhs1 or not*/
} sdmmc_host_t;

View File

@@ -68,3 +68,16 @@ The legacy timer group driver ``driver/timer.h`` is deprecated since version 5.0
------------------------------------
The legacy PCNT driver ``driver/pcnt.h`` is deprecated since version 5.0 (see :ref:`deprecate_pcnt_legacy_driver`). Starting from version 6.0, the legacy driver is completely removed. The new driver is placed in the :component:`esp_driver_pcnt`, and the header file path is ``driver/pulse_cnt.h``.
GDMA
----
- The ``GDMA_ISR_IRAM_SAFE`` Kconfig option has been removed due to potential risks. Now, the interrupt behavior of different DMA channels during Cache disabled periods are independent of each other.
- ``gdma_new_channel`` is removed. When requesting a GDMA channel, use either ``gdma_new_ahb_channel`` or ``gdma_new_axi_channel`` according to the bus type.
- The ``sram_trans_align`` and ``psram_trans_align`` members have been removed from :cpp:type:`async_memcpy_config_t`. Use :cpp:member:`async_memcpy_config_t::dma_burst_size` to set the DMA burst transfer size.
- The ``esp_dma_capable_malloc`` and ``esp_dma_capable_calloc`` functions have been removed. Use :cpp:func:`heap_caps_malloc` and :cpp:func:`heap_caps_calloc` from :component_file:`heap/include/esp_heap_caps.h` with ``MALLOC_CAP_DMA|MALLOC_CAP_CACHE_ALIGNED`` to allocate memory suitable for DMA and cache alignment.
SDMMC
-----
- The ``get_dma_info`` member in the :cpp:type:`sdmmc_host_t` structure, as well as the ``sdspi_host_get_dma_info`` and ``sdmmc_host_get_dma_info`` functions, have been removed. DMA configuration is now handled internally by the driver.

View File

@@ -68,3 +68,16 @@ I2C 从机在 v5.4 上已经被重新设计。在当前版本上,老的 I2C
----------------------
旧版的 PCNT 驱动 ``driver/pcnt.h`` 在 5.0 的版本中就已经被弃用 (参考 :ref:`deprecate_pcnt_legacy_driver`)。从 6.0 版本开始,旧版驱动被完全移除。新驱动位于 :component:`esp_driver_pcnt` 组件中,头文件引用路径为 ``driver/pulse_cnt.h``
GDMA
----
- ``GDMA_ISR_IRAM_SAFE`` Kconfig 选项会带来不必要的风险,因此被移除。现在,不同的 GDMA 通道它们的中断在 Cache 关闭期间的行为可以互不影响。
- ``gdma_new_channel`` 已经被移除。现在当申请一个 GDMA 通道时,必须要根据实际使用的总线调用 ``gdma_new_ahb_channel````gdma_new_axi_channel`` 函数。
- :cpp:type:`async_memcpy_config_t` 中的 ``sram_trans_align````psram_trans_align`` 成员均已经被移除。请使用 :cpp:member:`async_memcpy_config_t::dma_burst_size` 来设置 DMA 的突发传输大小。
- ``esp_dma_capable_malloc````esp_dma_capable_calloc`` 函数已经被移除。请使用 :component_file:`heap/include/esp_heap_caps.h` 中的 :cpp:func:`heap_caps_malloc`:cpp:func:`heap_caps_calloc` 函数搭配 ``MALLOC_CAP_DMA|MALLOC_CAP_CACHE_ALIGNED`` 分配满足 DMA 和 Cache 对齐要求的内存。
SDMMC
-----
- :cpp:type:`sdmmc_host_t` 结构体中的 ``get_dma_info`` 成员接口已经被移除。对应的 ``sdspi_host_get_dma_info````sdmmc_host_get_dma_info`` 函数也已经被移除。DMA 相关的设置会由驱动内部处理好。

View File

@@ -16,6 +16,6 @@ dependencies:
rules:
- if: "target in [esp32p4, esp32h2]"
espressif/esp-extconn:
version: "~0.2.0"
version: "~0.3.0"
rules:
- if: "target in [esp32p4]"

View File

@@ -489,6 +489,10 @@
re: "has no member named 'io_od_mode'"
hint: "Please include 'driver/gpio.h' and call 'gpio_od_enable' to enable the open-drain mode."
-
re: "error: implicit declaration of function '(esp_dma_capable_malloc|esp_dma_capable_calloc|esp_cache_aligned_malloc|esp_cache_aligned_calloc)'"
hint: "Use the memory allocation functions from the esp_heap_caps.h with proper capability flags.\nFor example, use heap_caps_malloc() with the MALLOC_CAP_CACHE_ALIGNED flag to allocate memory that is aligned to cache line."
-
re: "fatal error: {}: No such file or directory"
hint: "The {} driver is removed. It should be replaced by '{}' in the '{}' component. Please read the migration guide for more details."