feat(freertos): added option for automatically placing task stacks in PSRAM

When CONFIG_FREERTOS_PLACE_TASK_STACKS_IN_EXT_RAM is enabled freertos will
now automatically allocate task stacks to PSRAM.
This commit is contained in:
Marius Vikhammer
2026-06-04 16:06:52 +08:00
parent 4a0c14dc7d
commit d21dc8ca2e
26 changed files with 560 additions and 7 deletions
+24
View File
@@ -593,6 +593,30 @@ menu "FreeRTOS"
(no direct calls, but also no Bluetooth/WiFi), you can try enable this to
cause xTaskCreateStatic to allow tasks stack in external memory.
config FREERTOS_PLACE_TASK_STACKS_IN_EXT_RAM
bool "Place dynamic task stacks in PSRAM by default"
depends on FREERTOS_TASK_CREATE_ALLOW_EXT_MEM
default n
help
When enabled, task stacks allocated by xTaskCreate() / xTaskCreatePinnedToCore() are
placed in PSRAM (with internal RAM as fallback). TCBs are still allocated from internal RAM.
Restrictions that still require user attention:
- Flash operations cannot be called from tasks a PSRAM stack as they will
run while cache is disabled. This includes all filesystem access and NVS.
The recommended approach here is to use esp-flash-dispatcher,
idf.py add-dependency "espressif/esp_flash_dispatcher"
which automatically routes all flash API calls to a dedicated task
placed in internal RAM.
- Deep-sleep requests issued from a task with a PSRAM stack are rejected at runtime. Auto-light-sleep
is unaffected because it runs from the idle task, whose stack is always in internal RAM.
- Components that spawn tasks via xTaskCreate and require cache-disabled-safe stacks
should use xTaskCreateWithCaps(..., MALLOC_CAP_INTERNAL) instead.
- xTaskCreateStatic is unaffected; the caller always decides where the stack lives.
endmenu # Extra
# Hidden or compatibility options
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -136,7 +136,11 @@
#define configSUPPORT_STATIC_ALLOCATION 1
#define configSUPPORT_DYNAMIC_ALLOCATION 1
#define configAPPLICATION_ALLOCATED_HEAP 1
#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0
#if CONFIG_FREERTOS_PLACE_TASK_STACKS_IN_EXT_RAM
#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 1
#else
#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0
#endif
/* ------------------------ Hooks -------------------------- */
+13 -1
View File
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -94,6 +94,18 @@ bool xPortCheckValidTCBMem(const void * ptr)
#endif /* CONFIG_IDF_TARGET_LINUX */
}
#if CONFIG_FREERTOS_PLACE_TASK_STACKS_IN_EXT_RAM
void * pvPortMallocStack(size_t xWantedSize)
{
return heap_caps_malloc_prefer(xWantedSize, 2, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
}
void vPortFreeStack(void * pv)
{
heap_caps_free(pv);
}
#endif /* CONFIG_FREERTOS_PLACE_TASK_STACKS_IN_EXT_RAM */
bool xPortcheckValidStackMem(const void * ptr)
{
#if CONFIG_IDF_TARGET_LINUX
+3
View File
@@ -0,0 +1,3 @@
-
re: "assert failed: .*?\\(s_task_stack_is_sane_when_cache_frozen\\(\\)\\)"
hint: "Flash operations cannot be performed when task stack is in PSRAM. Check out esp_flash_dispatcher component at https://components.espressif.com/components/espressif/esp_flash_dispatcher/versions/1.0.1/readme?language= for a potential solution to this issue."