[esp32] Pin static loop task stack to internal DRAM

The static loop task TCB and stack added in #15659 had no explicit
section attribute, so under some sdkconfig combinations (notably
CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY) the linker can place them
in PSRAM. That is unsafe when CONFIG_SPIRAM_XIP_FROM_PSRAM is also
enabled, because the running task's stack must stay reachable while the
flash cache is disabled (asserted by esp_task_stack_is_sane_cache_disabled).
DRAM_ATTR keeps both objects in internal DRAM regardless of those configs.
This commit is contained in:
J. Nick Koston
2026-05-22 21:31:10 -05:00
parent b0dc688c14
commit 8f198ffb2e

View File

@@ -3,6 +3,7 @@
#include "esphome/core/application.h"
#include "esphome/core/defines.h"
#include "preferences.h"
#include <esp_attr.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
@@ -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();