- SPIWP:0xee
- mode:DIO, clock div:1
- load:0x3fce3810,len:0x178c
- load:0x403c9700,len:0x4
- load:0x403c9704,len:0xcb8
- load:0x403cc700,len:0x2d84
- entry 0x403c9914
- I (26) boot: ESP-IDF v5.3-dev-277-gc8243465e4 2nd stage bootloader
- I (27) boot: compile time Nov 15 2023 20:47:33
- I (27) boot: Multicore bootloader
- I (31) boot: chip revision: v0.1
- I (35) boot.esp32s3: Boot SPI Speed : 80MHz
- I (40) boot.esp32s3: SPI Mode : DIO
- I (45) boot.esp32s3: SPI Flash Size : 8MB
- I (49) boot: Enabling RNG early entropy source...
- I (55) boot: Partition Table:
- I (58) boot: ## Label Usage Type ST Offset Length
- I (66) boot: 0 nvs WiFi data 01 02 00009000 00006000
- I (73) boot: 1 phy_init RF data 01 01 0000f000 00001000
- I (81) boot: 2 factory factory app 00 00 00010000 00100000
- I (88) boot: End of partition table
- I (92) esp_image: segment 0: paddr=00010020 vaddr=3c020020 size=0dc44h ( 56388) map
- I (111) esp_image: segment 1: paddr=0001dc6c vaddr=3fc92500 size=023ach ( 9132) load
- I (113) esp_image: segment 2: paddr=00020020 vaddr=42000020 size=1a66ch (108140) map
- I (137) esp_image: segment 3: paddr=0003a694 vaddr=3fc948ac size=00608h ( 1544) load
- I (138) esp_image: segment 4: paddr=0003aca4 vaddr=40374000 size=0e4b4h ( 58548) load
- I (161) boot: Loaded app from partition at offset 0x10000
- I (162) boot: Disabling RNG early entropy source...
- I (173) cpu_start: Multicore app
- I (182) cpu_start: Pro cpu start user code
- I (182) cpu_start: cpu freq: 160000000 Hz
- I (183) cpu_start: Application information:
- I (185) cpu_start: Project name: async_memcpy
- I (191) cpu_start: App version: d6b7f7a-dirty
- I (196) cpu_start: Compile time: Nov 15 2023 20:47:26
- I (202) cpu_start: ELF file SHA256: 97614a826...
- I (208) cpu_start: ESP-IDF: v5.3-dev-277-gc8243465e4
- I (214) cpu_start: Min chip rev: v0.0
- I (219) cpu_start: Max chip rev: v0.99
- I (224) cpu_start: Chip rev: v0.1
- I (228) heap_init: Initializing. RAM available for dynamic allocation:
- I (236) heap_init: At 3FC95790 len 00053F80 (335 KiB): RAM
- I (242) heap_init: At 3FCE9710 len 00005724 (21 KiB): RAM
- I (248) heap_init: At 3FCF0000 len 00008000 (32 KiB): DRAM
- I (254) heap_init: At 600FE010 len 00001FD8 (7 KiB): RTCRAM
- I (261) spi_flash: detected chip: generic
- I (265) spi_flash: flash io: dio
- I (269) sleep: Configure to isolate all GPIO pins in sleep state
- I (276) sleep: Enable automatic switching of GPIO sleep configuration
- I (283) main_task: Started on CPU0
- I (293) main_task: Calling app_main()
- I (293) async_memcpy:
- async_memcpy!
- I (293) async_memcpy: Allocating memory for buffers...
- I (303) async_memcpy: Initializing source buffer...
- I (303) async_memcpy: Installing async_memcpy driver...
- D (313) gdma: new group (0) at 0x3fccbd8c
- D (313) gdma: new pair (0,0) at 0x3fccbe14
- D (323) gdma: new tx channel (0,0) at 0x3fccbd54
- D (323) gdma: new rx channel (0,0) at 0x3fccbe34
- D (333) gdma: tx channel (0,0), (0:32) bytes aligned, burst enabled
- D (333) gdma: rx channel (0,0), (0:32) bytes aligned, burst disabled
- D (343) gdma: install interrupt service for rx channel (0,0)
- I (353) async_memcpy: Creating semaphore...
- I (353) async_memcpy: Starting the async_memcpy to transfer 100000 bytes...
- I (363) async_memcpy: Waiting for the DMA operation to complete...
- I (373) async_memcpy: async_memcpy complete! Transferred 100000 bytes
- I (373) main_task: Returned from app_main()
I can successfully transfer data within IRAM using the MALLOC_CAP_DMA. If I try to word align (32bit align) the memory it doesn't work saying the memory is not aligned. Even though the memory addresses and lengths look aligned to me.
Finally, I noticed GDMA functionality for esp_async_memcpy is only available on the Master branch of the ESP-IDF and that it doesn't even exist in IDF 5.1.1.
Can anyone tell me what I'm doing wrong? Or is there a bug in the implementation of the esp_async_memcpy API?
- /*
- * Attempts to use the async_memcpy driver to copy data from one buffer to another
- *
- * Works for MALLOC_CAP_DMA but not if we try to align the buffers to 32 bits
- * Does not work for MALLOC_CAP_SPIRAM no matter what I try.
- * Reporting "invalid argument" on the call to esp_async_memcpy
- *
- * Using an ESP32-S3-WROOM-1U-N8R8 module
- * Using the master branch of ESP-IDF cloned on 15/11/2023
- *
- */
- #include <inttypes.h>
- #include <string.h>
- #include "malloc.h"
- #include "esp_log.h"
- #include "esp_heap_caps.h"
- #include "esp_async_memcpy.h"
- #include "freertos/FreeRTOS.h"
- #include "freertos/task.h"
- #include "freertos/semphr.h"
- static const char *TAG = "async_memcpy";
- /// @brief The source buffer
- void* _source;
- /// @brief The destination buffer
- void* _dest;
- /// @brief Async Memory copy callback implementation, running in ISR context
- /// @param mcp_hdl Handle of async memcpy
- /// @param event Event object, which contains related data, reserved for future
- /// @param cb_args User defined arguments, passed from esp_async_memcpy function
- /// @return Whether a high priority task is woken up by the callback function
- static IRAM_ATTR bool my_async_memcpy_cb(async_memcpy_t mcp_hdl, async_memcpy_event_t *event, void *cb_args)
- {
- // Get the semaphore handle from the callback arguments
- SemaphoreHandle_t sem = (SemaphoreHandle_t)cb_args;
- // Give the semaphore so the CPU can continue execution when its ready
- // high_task_wakeup set to pdTRUE if we want to yield to a high priority task
- BaseType_t high_task_wakeup = pdTRUE;
- xSemaphoreGiveFromISR(sem, &high_task_wakeup);
- // Return whether a high priority task was woken up so the ISR knows if it needs to yield
- return high_task_wakeup == pdTRUE;
- }
- /// @brief Main application entry point
- void app_main(void)
- {
- // Hello world
- ESP_LOGI(TAG, "\n\nasync_memcpy!\n");
- // Allocate some RAM for the source and destination buffers
- ESP_LOGI(TAG, "Allocating memory for buffers...");
- uint32_t size = 100000;
- // ** This works **
- _source = heap_caps_malloc(size, MALLOC_CAP_DMA);
- _dest = heap_caps_malloc(size, MALLOC_CAP_DMA);
- // ** This DOES NOT work **
- // _source = heap_caps_malloc(size, MALLOC_CAP_DMA | MALLOC_CAP_32BIT);
- // _dest = heap_caps_malloc(size, MALLOC_CAP_DMA | MALLOC_CAP_32BIT);
- // ** This DOES NOT work **
- // _source = heap_caps_malloc(size, MALLOC_CAP_SPIRAM | MALLOC_CAP_DMA | MALLOC_CAP_32BIT);
- // _dest = heap_caps_malloc(size, MALLOC_CAP_SPIRAM | MALLOC_CAP_DMA | MALLOC_CAP_32BIT);
- // ** This DOES NOT work **
- //_source = heap_caps_malloc(size, MALLOC_CAP_SPIRAM);
- //_dest = heap_caps_malloc(size, MALLOC_CAP_SPIRAM);
- // Initialize the source buffer
- ESP_LOGI(TAG, "Initializing source buffer...");
- //memset(_source, 0x77, size);
- // Install the Async memcpy driver. Using the defaults + a larger backlog.
- ESP_LOGI(TAG, "Installing async_memcpy driver...");
- async_memcpy_config_t config = ASYNC_MEMCPY_DEFAULT_CONFIG();
- //uint32_t backlog = 8;
- uint32_t backlog = (size > 2500) ? size/2500 : 4; // I think 2500 is approx the size of DMA transfer?
- config.backlog = backlog;
- // config.sram_trans_align = 32; // These don't work
- // config.psram_trans_align = 32;
- async_memcpy_handle_t driver = NULL;
- //ESP_ERROR_CHECK(esp_async_memcpy_install(&config, &driver));
- ESP_ERROR_CHECK(esp_async_memcpy_install_gdma_ahb(&config, &driver));
- // Create a semaphore so we can wait for the async memcpy to complete
- ESP_LOGI(TAG, "Creating semaphore...");
- SemaphoreHandle_t semaphore = xSemaphoreCreateBinary();
- // Start the async memcpy
- ESP_LOGI(TAG, "Starting the async_memcpy to transfer %" PRIu32 " bytes...", size);
- ESP_ERROR_CHECK(esp_async_memcpy(driver, _dest, _source, size, my_async_memcpy_cb, semaphore));
- // Wait for the async memcpy to complete
- ESP_LOGI(TAG, "Waiting for the DMA operation to complete...");
- xSemaphoreTake(semaphore, portMAX_DELAY);
- // Success. All done
- ESP_LOGI(TAG, "async_memcpy complete! Transferred %" PRIu32 " bytes", size);
- }
- SPIWP:0xee
- mode:DIO, clock div:1
- load:0x3fce3810,len:0x178c
- load:0x403c9700,len:0x4
- load:0x403c9704,len:0xcb8
- load:0x403cc700,len:0x2d84
- entry 0x403c9914
- I (26) boot: ESP-IDF v5.3-dev-277-gc8243465e4 2nd stage bootloader
- I (26) boot: compile time Nov 15 2023 20:47:33
- I (27) boot: Multicore bootloader
- I (31) boot: chip revision: v0.1
- I (35) boot.esp32s3: Boot SPI Speed : 80MHz
- I (39) boot.esp32s3: SPI Mode : DIO
- I (44) boot.esp32s3: SPI Flash Size : 8MB
- I (49) boot: Enabling RNG early entropy source...
- I (54) boot: Partition Table:
- I (58) boot: ## Label Usage Type ST Offset Length
- I (65) boot: 0 nvs WiFi data 01 02 00009000 00006000
- I (73) boot: 1 phy_init RF data 01 01 0000f000 00001000
- I (80) boot: 2 factory factory app 00 00 00010000 00100000
- I (88) boot: End of partition table
- I (92) esp_image: segment 0: paddr=00010020 vaddr=3c020020 size=0dc44h ( 56388) map
- I (110) esp_image: segment 1: paddr=0001dc6c vaddr=3fc92500 size=023ach ( 9132) load
- I (113) esp_image: segment 2: paddr=00020020 vaddr=42000020 size=1a66ch (108140) map
- I (136) esp_image: segment 3: paddr=0003a694 vaddr=3fc948ac size=00608h ( 1544) load
- I (137) esp_image: segment 4: paddr=0003aca4 vaddr=40374000 size=0e4b4h ( 58548) load
- I (161) boot: Loaded app from partition at offset 0x10000
- I (161) boot: Disabling RNG early entropy source...
- I (172) cpu_start: Multicore app
- I (182) cpu_start: Pro cpu start user code
- I (182) cpu_start: cpu freq: 160000000 Hz
- I (182) cpu_start: Application information:
- I (185) cpu_start: Project name: async_memcpy
- I (190) cpu_start: App version: d6b7f7a-dirty
- I (196) cpu_start: Compile time: Nov 15 2023 20:47:26
- I (202) cpu_start: ELF file SHA256: 7c7112055...
- I (207) cpu_start: ESP-IDF: v5.3-dev-277-gc8243465e4
- I (214) cpu_start: Min chip rev: v0.0
- I (218) cpu_start: Max chip rev: v0.99
- I (223) cpu_start: Chip rev: v0.1
- I (228) heap_init: Initializing. RAM available for dynamic allocation:
- I (235) heap_init: At 3FC95790 len 00053F80 (335 KiB): RAM
- I (241) heap_init: At 3FCE9710 len 00005724 (21 KiB): RAM
- I (247) heap_init: At 3FCF0000 len 00008000 (32 KiB): DRAM
- I (253) heap_init: At 600FE010 len 00001FD8 (7 KiB): RTCRAM
- I (261) spi_flash: detected chip: generic
- I (264) spi_flash: flash io: dio
- I (269) sleep: Configure to isolate all GPIO pins in sleep state
- I (275) sleep: Enable automatic switching of GPIO sleep configuration
- I (283) main_task: Started on CPU0
- I (293) main_task: Calling app_main()
- I (293) async_memcpy:
- async_memcpy!
- I (293) async_memcpy: Allocating memory for buffers...
- I (303) async_memcpy: Initializing source buffer...
- I (303) async_memcpy: Installing async_memcpy driver...
- D (313) gdma: new group (0) at 0x3fc9b05c
- D (313) gdma: new pair (0,0) at 0x3fc9b0e4
- D (323) gdma: new tx channel (0,0) at 0x3fc9b024
- D (323) gdma: new rx channel (0,0) at 0x3fc9b104
- D (333) gdma: tx channel (0,0), (0:32) bytes aligned, burst enabled
- D (333) gdma: rx channel (0,0), (0:32) bytes aligned, burst disabled
- D (343) gdma: install interrupt service for rx channel (0,0)
- I (353) async_memcpy: Creating semaphore...
- I (353) async_memcpy: Starting the async_memcpy to transfer 100000 bytes...
- E (363) async_mcp: esp_async_memcpy(21): invalid argument
- ESP_ERROR_CHECK failed: esp_err_t 0x102 (ESP_ERR_INVALID_ARG) at 0x420084c1
- 0x420084c1: app_main at D:/Ferret/Dev/esp32/Tests/Async_memcpy/main/main.c:102 (discriminator 1)
- file: "./main/main.c" line 102
- func: app_main
- expression: esp_async_memcpy(driver, _dest, _source, size, my_async_memcpy_cb, semaphore)
- abort() was called at PC 0x40379ca7 on core 0
- ex40379ca7: _esp_error_check_failed at C:/esp32/esp-idf_master/esp-idf/components/esp_system/esp_err.cN:o50n
- Backtrace: 0x403758a6:0x3fc99340 0x40379cb1:0x3fc99360 0x40380441:0x3fc99380 0x40379ca7:0x3fc993f0 0x420084c1:0x3fc99420 0x42019813:0x3fc99460 0x4037a515:0x3fc99490
- Waiting for the device to reconnect0x403758a6: panic_abort at C:/esp32/esp-idf_master/esp-idf/components/esp_system/panic.c:472
- 0x40379cb1: esp_system_abort at C:/esp32/esp-idf_master/esp-idf/components/esp_system/port/esp_system_chip.c:93
- 0x40380441: abort at C:/esp32/esp-idf_master/esp-idf/components/newlib/abort.c:38
- 0x40379ca7: _esp_error_check_failed at C:/esp32/esp-idf_master/esp-idf/components/esp_system/esp_err.c:50
- 0x420084c1: app_main at D:/Ferret/Dev/esp32/Tests/Async_memcpy/main/main.c:102 (discriminator 1)
- 0x42019813: main_task at C:/esp32/esp-idf_master/esp-idf/components/freertos/app_startup.c:208
- 0x4037a515: vPortTaskWrapper at C:/esp32/esp-idf_master/esp-idf/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c:137
- ELF file SHA256: 7c7112055
- Rebooting...
- ESP-ROM:esp32s3-20210327
- Build:Mar 27 2021
- rst:0xc (RTC_SW_CPU_RST),boot:0xf (SPI_FAST_FLASH_BOOT)
- Saved PC:0x4037581c
- 0x4037581c: esp_restart_noos at C:/esp32/esp-idf_master/esp-idf/components/esp_system/port/soc/esp32s3/system_internal.c:158