test(gdma): can read data from flash rodata

This commit is contained in:
morris 2024-04-24 18:04:36 +08:00
parent a6d8251366
commit a04f786380
5 changed files with 34 additions and 15 deletions

View File

@ -11,6 +11,7 @@
#include "freertos/semphr.h"
#include "unity.h"
#include "esp_heap_caps.h"
#include "esp_memory_utils.h"
#include "esp_private/gdma.h"
#include "hal/dma_types.h"
#include "soc/soc_caps.h"
@ -62,6 +63,8 @@ static void test_gdma_crc_calculation(gdma_channel_handle_t tx_chan, int test_nu
uint32_t crc_result = 0;
const char *test_input_string = "Share::Connect::Innovate";
size_t input_data_size = strlen(test_input_string);
// this test case also test the GDMA can fetch data from MSPI Flash
TEST_ASSERT_TRUE(esp_ptr_in_drom(test_input_string));
printf("Calculate CRC value for string: \"%s\"\r\n", test_input_string);
gdma_trigger_t m2m_trigger = GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_M2M, 0);
@ -71,27 +74,22 @@ static void test_gdma_crc_calculation(gdma_channel_handle_t tx_chan, int test_nu
m2m_trigger.instance_id = __builtin_ctz(free_m2m_id_mask);
TEST_ESP_OK(gdma_connect(tx_chan, m2m_trigger));
// allocate the source and destination buffer from SRAM
// |--------------------------------------------------|
// | 128 bytes DMA descriptor | 128 bytes data buffer |
// |--------------------------------------------------|
size_t sram_alignment = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_INT_MEM, CACHE_TYPE_DATA);
uint8_t *src_buf = heap_caps_aligned_calloc(sram_alignment, 1, 256, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
TEST_ASSERT_NOT_NULL(src_buf);
dma_descriptor_align8_t *tx_descs = (dma_descriptor_align8_t *) src_buf;
uint8_t *src_data = src_buf + 64;
memcpy(src_data, test_input_string, input_data_size);
size_t sram_cache_line_size = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_INT_MEM, CACHE_TYPE_DATA);
size_t alignment = MAX(sram_cache_line_size, 8);
dma_descriptor_align8_t *tx_descs = heap_caps_aligned_calloc(alignment, 1, sizeof(dma_descriptor_align8_t),
MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
TEST_ASSERT_NOT_NULL(tx_descs);
tx_descs->buffer = src_data;
tx_descs->dw0.size = 256 - 64;
tx_descs->buffer = (void *)test_input_string;
tx_descs->dw0.size = input_data_size + 1; // +1 for '\0'
tx_descs->dw0.length = input_data_size;
tx_descs->dw0.owner = DMA_DESCRIPTOR_BUFFER_OWNER_DMA;
tx_descs->dw0.suc_eof = 1;
tx_descs->next = NULL;
if (sram_alignment) {
if (sram_cache_line_size) {
// do write-back for the buffer because it's in the cache
TEST_ESP_OK(esp_cache_msync((void *)src_buf, 256, ESP_CACHE_MSYNC_FLAG_DIR_C2M));
TEST_ESP_OK(esp_cache_msync((void *)tx_descs, sizeof(dma_descriptor_align8_t), ESP_CACHE_MSYNC_FLAG_DIR_C2M | ESP_CACHE_MSYNC_FLAG_UNALIGNED));
}
for (int i = 0; i < test_num_crc_algorithm; i++) {
@ -111,7 +109,7 @@ static void test_gdma_crc_calculation(gdma_channel_handle_t tx_chan, int test_nu
TEST_ASSERT_EQUAL(crc_test_cases[i].expected_result, crc_result);
}
free(src_buf);
free(tx_descs);
}
TEST_CASE("GDMA CRC Calculation", "[GDMA][CRC]")

View File

@ -451,6 +451,10 @@ config SOC_DS_KEY_CHECK_MAX_WAIT_US
int
default 1100
config SOC_DMA_CAN_ACCESS_MSPI_MEM
bool
default y
config SOC_AHB_GDMA_VERSION
int
default 2

View File

@ -182,6 +182,9 @@
See TRM DS chapter for more details */
#define SOC_DS_KEY_CHECK_MAX_WAIT_US (1100)
/*-------------------------- DMA Common CAPS ----------------------------------------*/
#define SOC_DMA_CAN_ACCESS_MSPI_MEM 1 /*!< DMA can access MSPI memory (e.g. Flash, PSRAM) */
/*-------------------------- GDMA CAPS -------------------------------------*/
#define SOC_AHB_GDMA_VERSION 2
#define SOC_GDMA_SUPPORT_CRC 1

View File

@ -77,6 +77,13 @@ Non-IRAM-Safe Interrupt Handlers
If the ``ESP_INTR_FLAG_IRAM`` flag is not set when registering, the interrupt handler will not get executed when the caches are disabled. Once the caches are restored, the non-IRAM-safe interrupts will be re-enabled. After this moment, the interrupt handler will run normally again. This means that as long as caches are disabled, users will not see the corresponding hardware event happening.
.. only:: SOC_DMA_CAN_ACCESS_MSPI_MEM
When DMA Read Data from Flash
-----------------------------
When DMA is reading data from Flash, erase/write operations from SPI1 take higher priority in hardware, resulting in unpredictable data read by DMA. It is recommended to stop DMA access to Flash before erasing or writing to it. If DMA cannot be stopped (for example, the LCD needs to continuously refresh image data stored in Flash), it is advisable to copy such data to PSRAM or internal SRAM.
.. only:: SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND

View File

@ -77,6 +77,13 @@ IRAM 安全中断处理程序
如果在注册时没有设置 ``ESP_INTR_FLAG_IRAM`` 标志,当禁用 cache 时,将不会执行中断处理程序。一旦 cache 恢复,非 IRAM 安全的中断将重新启用,中断处理程序随即再次正常运行。这意味着,只要禁用了 cache就不会发生相应的硬件事件。
.. only:: SOC_DMA_CAN_ACCESS_MSPI_MEM
当 DMA 也可以访问 Flash 中的数据时
----------------------------------
当 DMA 正在从 Flash 中读取数据时,来自 SPI1 的擦/写操作优先级会更高,导致 DMA 读到错误的数据。建议在擦写 Flash 之前先停止 DMA 对 Flash 的访问。如果 DMA 不可以停止,比如 LCD 需要持续刷新保存在 Flash 中的图像数据,建议将此类数据拷贝到 PSRAM 或者内部的 SRAM 中。
.. only:: SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND