From 94a915fd5c8d7d753eafe31d418f0bf6e2ad9f21 Mon Sep 17 00:00:00 2001 From: Nachiket Kukade Date: Mon, 12 Aug 2024 14:24:52 +0530 Subject: [PATCH] fix(wifi): Add PSRAM failure fallback in WiFi Queue API's --- components/esp_wifi/esp32/esp_adapter.c | 46 +++++++++++----------- components/esp_wifi/esp32c5/esp_adapter.c | 29 +++++++++----- components/esp_wifi/esp32c61/esp_adapter.c | 29 +++++++++----- components/esp_wifi/esp32p4/esp_adapter.c | 29 +++++++++++++- components/esp_wifi/esp32s2/esp_adapter.c | 46 +++++++++++----------- components/esp_wifi/esp32s3/esp_adapter.c | 46 +++++++++++----------- 6 files changed, 131 insertions(+), 94 deletions(-) diff --git a/components/esp_wifi/esp32/esp_adapter.c b/components/esp_wifi/esp32/esp_adapter.c index ce79917000..f58f93769d 100644 --- a/components/esp_wifi/esp32/esp_adapter.c +++ b/components/esp_wifi/esp32/esp_adapter.c @@ -49,6 +49,9 @@ #include "esp_rom_sys.h" #include "esp32/rom/ets_sys.h" #include "private/esp_modem_wrapper.h" +#if __has_include("esp_psram.h") +#include "esp_psram.h" +#endif #define TAG "esp_adapter" @@ -260,36 +263,31 @@ static int32_t IRAM_ATTR mutex_unlock_wrapper(void *mutex) static void * queue_create_wrapper(uint32_t queue_len, uint32_t item_size) { -#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0) - /* - * Since release/v5.1, FreeRTOS has been updated to always use internal memory (i.e., DRAM) - * for dynamic memory allocation. Calling FreeRTOS creation functions (e.g., xTaskCreate(), xQueueCreate()) - * will guarantee that the memory allocated for those tasks/objects is from internal memory. - * For more details, please refer to the Migration Guide in release/v5.1. - */ -#if CONFIG_SPIRAM_USE_MALLOC - /* Use xQueueCreateWithCaps() to allocate from SPIRAM */ - return (void *)xQueueCreateWithCaps(queue_len, item_size, MALLOC_CAP_SPIRAM); -#else - return (void *)xQueueCreate(queue_len, item_size); -#endif -#else - return (void *)xQueueCreate(queue_len, item_size); -#endif + StaticQueue_t *queue_buffer = heap_caps_malloc_prefer(sizeof(StaticQueue_t) + (queue_len * item_size), 2, + MALLOC_CAP_DEFAULT | MALLOC_CAP_SPIRAM, + MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL); + if (!queue_buffer) { + return NULL; + } + QueueHandle_t queue_handle = xQueueCreateStatic(queue_len, item_size, (uint8_t *)queue_buffer + sizeof(StaticQueue_t), + queue_buffer); + if (!queue_handle) { + free(queue_buffer); + return NULL; + } + + return (void *)queue_handle; } static void queue_delete_wrapper(void *queue) { if (queue) { -#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0) -#if CONFIG_SPIRAM_USE_MALLOC - vQueueDeleteWithCaps(queue); -#else + StaticQueue_t *queue_buffer = NULL; + xQueueGetStaticBuffers(queue, NULL, &queue_buffer); vQueueDelete(queue); -#endif -#else - vQueueDelete(queue); -#endif + if (queue_buffer) { + free(queue_buffer); + } } } diff --git a/components/esp_wifi/esp32c5/esp_adapter.c b/components/esp_wifi/esp32c5/esp_adapter.c index 0bc270b856..f341af368a 100644 --- a/components/esp_wifi/esp32c5/esp_adapter.c +++ b/components/esp_wifi/esp32c5/esp_adapter.c @@ -252,22 +252,31 @@ static int32_t IRAM_ATTR mutex_unlock_wrapper(void *mutex) static void *queue_create_wrapper(uint32_t queue_len, uint32_t item_size) { -#if CONFIG_SPIRAM_USE_MALLOC - /* Use xQueueCreateWithCaps() to allocate from SPIRAM */ - return (void *)xQueueCreateWithCaps(queue_len, item_size, MALLOC_CAP_SPIRAM); -#else - return (void *)xQueueCreate(queue_len, item_size); -#endif + StaticQueue_t *queue_buffer = heap_caps_malloc_prefer(sizeof(StaticQueue_t) + (queue_len * item_size), 2, + MALLOC_CAP_DEFAULT | MALLOC_CAP_SPIRAM, + MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL); + if (!queue_buffer) { + return NULL; + } + QueueHandle_t queue_handle = xQueueCreateStatic(queue_len, item_size, (uint8_t *)queue_buffer + sizeof(StaticQueue_t), + queue_buffer); + if (!queue_handle) { + free(queue_buffer); + return NULL; + } + + return (void *)queue_handle; } static void queue_delete_wrapper(void *queue) { if (queue) { -#if CONFIG_SPIRAM_USE_MALLOC - vQueueDeleteWithCaps(queue); -#else + StaticQueue_t *queue_buffer = NULL; + xQueueGetStaticBuffers(queue, NULL, &queue_buffer); vQueueDelete(queue); -#endif + if (queue_buffer) { + free(queue_buffer); + } } } diff --git a/components/esp_wifi/esp32c61/esp_adapter.c b/components/esp_wifi/esp32c61/esp_adapter.c index 8f6aac9216..58b7e56688 100644 --- a/components/esp_wifi/esp32c61/esp_adapter.c +++ b/components/esp_wifi/esp32c61/esp_adapter.c @@ -252,22 +252,31 @@ static int32_t IRAM_ATTR mutex_unlock_wrapper(void *mutex) static void *queue_create_wrapper(uint32_t queue_len, uint32_t item_size) { -#if CONFIG_SPIRAM_USE_MALLOC - /* Use xQueueCreateWithCaps() to allocate from SPIRAM */ - return (void *)xQueueCreateWithCaps(queue_len, item_size, MALLOC_CAP_SPIRAM); -#else - return (void *)xQueueCreate(queue_len, item_size); -#endif + StaticQueue_t *queue_buffer = heap_caps_malloc_prefer(sizeof(StaticQueue_t) + (queue_len * item_size), 2, + MALLOC_CAP_DEFAULT | MALLOC_CAP_SPIRAM, + MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL); + if (!queue_buffer) { + return NULL; + } + QueueHandle_t queue_handle = xQueueCreateStatic(queue_len, item_size, (uint8_t *)queue_buffer + sizeof(StaticQueue_t), + queue_buffer); + if (!queue_handle) { + free(queue_buffer); + return NULL; + } + + return (void *)queue_handle; } static void queue_delete_wrapper(void *queue) { if (queue) { -#if CONFIG_SPIRAM_USE_MALLOC - vQueueDeleteWithCaps(queue); -#else + StaticQueue_t *queue_buffer = NULL; + xQueueGetStaticBuffers(queue, NULL, &queue_buffer); vQueueDelete(queue); -#endif + if (queue_buffer) { + free(queue_buffer); + } } } diff --git a/components/esp_wifi/esp32p4/esp_adapter.c b/components/esp_wifi/esp32p4/esp_adapter.c index 74bc498cc4..4def952a2c 100644 --- a/components/esp_wifi/esp32p4/esp_adapter.c +++ b/components/esp_wifi/esp32p4/esp_adapter.c @@ -257,7 +257,32 @@ static int32_t IRAM_ATTR mutex_unlock_wrapper(void *mutex) static void *queue_create_wrapper(uint32_t queue_len, uint32_t item_size) { - return (void *)xQueueCreate(queue_len, item_size); + StaticQueue_t *queue_buffer = heap_caps_malloc_prefer(sizeof(StaticQueue_t) + (queue_len * item_size), 2, + MALLOC_CAP_DEFAULT | MALLOC_CAP_SPIRAM, + MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL); + if (!queue_buffer) { + return NULL; + } + QueueHandle_t queue_handle = xQueueCreateStatic(queue_len, item_size, (uint8_t *)queue_buffer + sizeof(StaticQueue_t), + queue_buffer); + if (!queue_handle) { + free(queue_buffer); + return NULL; + } + + return (void *)queue_handle; +} + +static void queue_delete_wrapper(void *queue) +{ + if (queue) { + StaticQueue_t *queue_buffer = NULL; + xQueueGetStaticBuffers(queue, NULL, &queue_buffer); + vQueueDelete(queue); + if (queue_buffer) { + free(queue_buffer); + } + } } static int32_t queue_send_wrapper(void *queue, void *item, uint32_t block_time_tick) @@ -691,7 +716,7 @@ wifi_osi_funcs_t g_wifi_osi_funcs = { ._mutex_lock = mutex_lock_wrapper, ._mutex_unlock = mutex_unlock_wrapper, ._queue_create = queue_create_wrapper, - ._queue_delete = (void(*)(void *))vQueueDelete, + ._queue_delete = queue_delete_wrapper, ._queue_send = queue_send_wrapper, ._queue_send_from_isr = queue_send_from_isr_wrapper, ._queue_send_to_back = queue_send_to_back_wrapper, diff --git a/components/esp_wifi/esp32s2/esp_adapter.c b/components/esp_wifi/esp32s2/esp_adapter.c index 95f9f2dbb1..3e131130f8 100644 --- a/components/esp_wifi/esp32s2/esp_adapter.c +++ b/components/esp_wifi/esp32s2/esp_adapter.c @@ -50,6 +50,9 @@ #include "esp_rom_sys.h" #include "esp32s2/rom/ets_sys.h" #include "private/esp_modem_wrapper.h" +#if __has_include("esp_psram.h") +#include "esp_psram.h" +#endif #define TAG "esp_adapter" @@ -251,36 +254,31 @@ static int32_t IRAM_ATTR mutex_unlock_wrapper(void *mutex) static void * queue_create_wrapper(uint32_t queue_len, uint32_t item_size) { -#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0) - /* - * Since release/v5.1, FreeRTOS has been updated to always use internal memory (i.e., DRAM) - * for dynamic memory allocation. Calling FreeRTOS creation functions (e.g., xTaskCreate(), xQueueCreate()) - * will guarantee that the memory allocated for those tasks/objects is from internal memory. - * For more details, please refer to the Migration Guide in release/v5.1. - */ -#if CONFIG_SPIRAM_USE_MALLOC - /* Use xQueueCreateWithCaps() to allocate from SPIRAM */ - return (void *)xQueueCreateWithCaps(queue_len, item_size, MALLOC_CAP_SPIRAM); -#else - return (void *)xQueueCreate(queue_len, item_size); -#endif -#else - return (void *)xQueueCreate(queue_len, item_size); -#endif + StaticQueue_t *queue_buffer = heap_caps_malloc_prefer(sizeof(StaticQueue_t) + (queue_len * item_size), 2, + MALLOC_CAP_DEFAULT | MALLOC_CAP_SPIRAM, + MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL); + if (!queue_buffer) { + return NULL; + } + QueueHandle_t queue_handle = xQueueCreateStatic(queue_len, item_size, (uint8_t *)queue_buffer + sizeof(StaticQueue_t), + queue_buffer); + if (!queue_handle) { + free(queue_buffer); + return NULL; + } + + return (void *)queue_handle; } static void queue_delete_wrapper(void *queue) { if (queue) { -#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0) -#if CONFIG_SPIRAM_USE_MALLOC - vQueueDeleteWithCaps(queue); -#else + StaticQueue_t *queue_buffer = NULL; + xQueueGetStaticBuffers(queue, NULL, &queue_buffer); vQueueDelete(queue); -#endif -#else - vQueueDelete(queue); -#endif + if (queue_buffer) { + free(queue_buffer); + } } } diff --git a/components/esp_wifi/esp32s3/esp_adapter.c b/components/esp_wifi/esp32s3/esp_adapter.c index ba3311a240..3fef6ab866 100644 --- a/components/esp_wifi/esp32s3/esp_adapter.c +++ b/components/esp_wifi/esp32s3/esp_adapter.c @@ -51,6 +51,9 @@ #include "esp_rom_sys.h" #include "esp32s3/rom/ets_sys.h" #include "private/esp_modem_wrapper.h" +#if __has_include("esp_psram.h") +#include "esp_psram.h" +#endif #define TAG "esp_adapter" @@ -254,36 +257,31 @@ static int32_t IRAM_ATTR mutex_unlock_wrapper(void *mutex) static void * queue_create_wrapper(uint32_t queue_len, uint32_t item_size) { -#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0) - /* - * Since release/v5.1, FreeRTOS has been updated to always use internal memory (i.e., DRAM) - * for dynamic memory allocation. Calling FreeRTOS creation functions (e.g., xTaskCreate(), xQueueCreate()) - * will guarantee that the memory allocated for those tasks/objects is from internal memory. - * For more details, please refer to the Migration Guide in release/v5.1. - */ -#if CONFIG_SPIRAM_USE_MALLOC - /* Use xQueueCreateWithCaps() to allocate from SPIRAM */ - return (void *)xQueueCreateWithCaps(queue_len, item_size, MALLOC_CAP_SPIRAM); -#else - return (void *)xQueueCreate(queue_len, item_size); -#endif -#else - return (void *)xQueueCreate(queue_len, item_size); -#endif + StaticQueue_t *queue_buffer = heap_caps_malloc_prefer(sizeof(StaticQueue_t) + (queue_len * item_size), 2, + MALLOC_CAP_DEFAULT | MALLOC_CAP_SPIRAM, + MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL); + if (!queue_buffer) { + return NULL; + } + QueueHandle_t queue_handle = xQueueCreateStatic(queue_len, item_size, (uint8_t *)queue_buffer + sizeof(StaticQueue_t), + queue_buffer); + if (!queue_handle) { + free(queue_buffer); + return NULL; + } + + return (void *)queue_handle; } static void queue_delete_wrapper(void *queue) { if (queue) { -#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0) -#if CONFIG_SPIRAM_USE_MALLOC - vQueueDeleteWithCaps(queue); -#else + StaticQueue_t *queue_buffer = NULL; + xQueueGetStaticBuffers(queue, NULL, &queue_buffer); vQueueDelete(queue); -#endif -#else - vQueueDelete(queue); -#endif + if (queue_buffer) { + free(queue_buffer); + } } }