Page 1 of 1

Why does xQueueCreate doesn't use PSRAM?

Posted: Sat Jul 22, 2023 3:55 pm
by Superkurt
Hello,

hope you can help me. I've migrated my app from ESP-IDF 4.4.5 to 5.1 and have a problem with xQueueCreate.

My ESP32 has 8MB PSRAM, and ESP-IDF is configured to use the PSRAM also for malloc (Make RAM allocatable using malloc() as well is checked).

In IDF 4.4.5 xQueueCreate used the PSRAM for large queue. But now in 5.1 it doesn't use the PSRAM. Here is my code:
  1. void app_main()
  2. {
  3.     ESP_LOGI("app", "MALLOC_CAP_SPIRAM = %d", (int)heap_caps_get_free_size(MALLOC_CAP_SPIRAM));
  4.     QueueHandle_t x = xQueueCreate(5262, 21);
  5.     ESP_LOGI("app", "x = %d", (int)x);
  6.     ESP_LOGI("app", "MALLOC_CAP_SPIRAM = %d", (int)heap_caps_get_free_size(MALLOC_CAP_SPIRAM));
  7.     void* y = malloc(5262 * 21);
  8.     ESP_LOGI("app", "y = %d", (int)y);
  9.     ESP_LOGI("app", "MALLOC_CAP_SPIRAM = %d", (int)heap_caps_get_free_size(MALLOC_CAP_SPIRAM));
  10. }  
The log:
  1. I (381) esp_psram: Adding pool of 4096K of PSRAM memory to heap allocator
  2. I (390) spi_flash: detected chip: gd
  3. I (392) spi_flash: flash io: dio
  4. I (397) coexist: coex firmware version: ebddf30
  5. I (402) app_start: Starting scheduler on CPU0
  6. II (407) app_start: Starting scheduler on CPU1
  7.  (407) main_task: Started on CPU0
  8. I (417) esp_psram: Reserving pool of 32K of internal memory for DMA/internal allocations
  9. I (417) main_task: Calling app_main()
  10. I (427) app: MALLOC_CAP_SPIRAM = 4192136
  11. I (427) app: x = 1073628860
  12. I (437) app: MALLOC_CAP_SPIRAM = 4192136
  13. I (437) app: y = 1065355388
  14. I (437) app: MALLOC_CAP_SPIRAM = 4081628
  15. I (447) main_task: Returned from app_main()
So xQueueCreate for 5262 elements of 21 bytes doesn't use the PSRAM. But allocating the same amount 5262 * 21 via malloc it uses PSRAM.

How can I achieve that xQueueCreate also use the PSRAM? It does this in ESP-IDF 4.4.5.

Re: Why does xQueueCreate doesn't use PSRAM?

Posted: Sat Jul 22, 2023 5:29 pm
by ESP_igrr
It seems this change had been mentioned in the release notes of v5.1. To allocate a Freertos object in PSRAM, you have to first allocate memory for it with heap_caps_malloc(..., MALLOC_CAP_SPIRAM) and then use xQueueCreateStatic to initialize the object inside the allocated buffer.
Here's an example: https://github.com/espressif/esp-idf/bl ... ter.c#L115

Re: Why does xQueueCreate doesn't use PSRAM?

Posted: Sat Jul 22, 2023 9:38 pm
by Superkurt
Thanks @ESP_iggr,

that put me in the right direction. I've now found the functions xQueueCreateWithCaps where I can give MALLOC_CAP_SPIRAM as the last parameter to say that I've need the allocation in PSRAM. I use now the function xQueueCreateWithCaps.

I've found the hint in the 5.1 release notes: https://github.com/espressif/esp-idf/releases/tag/v5.1
IDF: All dynamic memory allocated by FreeRTOS now defaults to internal memory. To allocate FreeRTOS objects in special memory (e.g., external memory), please use one of the CreateWithCaps() functions in #include "freertos/idf_additions.h"

And now I found it also in the migration guide from 5.0 to 5.1: https://docs.espressif.com/projects/esp ... ystem.html
Users that want to place a FreeRTOS task/object into external memory will now need to do so explicitly.

Thanks for your help!