diff --git a/esphome/components/esp32/core.cpp b/esphome/components/esp32/core.cpp index 5249f4a59e..1819fdbaad 100644 --- a/esphome/components/esp32/core.cpp +++ b/esphome/components/esp32/core.cpp @@ -3,6 +3,7 @@ #include "esphome/core/application.h" #include "esphome/core/defines.h" #include "preferences.h" +#include #include #include @@ -14,10 +15,14 @@ extern "C" __attribute__((weak)) void initArduino() {} namespace esphome { // HAL functions live in hal.cpp. This file keeps only the loop task setup. -TaskHandle_t loop_task_handle = nullptr; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) -static StaticTask_t loop_task_tcb; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) -static StackType_t - loop_task_stack[ESPHOME_LOOP_TASK_STACK_SIZE]; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) +// Force the static TCB and stack into internal DRAM. Otherwise the linker may +// place them in PSRAM under configs like CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY, +// which is unsafe when CONFIG_SPIRAM_XIP_FROM_PSRAM is enabled because the running +// task's stack must be reachable while the flash cache is disabled. +TaskHandle_t loop_task_handle = nullptr; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) +static StaticTask_t DRAM_ATTR loop_task_tcb{}; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) +static StackType_t DRAM_ATTR + loop_task_stack[ESPHOME_LOOP_TASK_STACK_SIZE]{}; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) void loop_task(void *pv_params) { setup();