From a3a20a7a27c5f9181624c9743e6bc083822d13c4 Mon Sep 17 00:00:00 2001 From: luaijun Date: Wed, 5 Aug 2026 19:46:05 +0800 Subject: [PATCH 1/2] fix: the incorrect SOC_PSRAM_SUPPORTED build condition with SOC_SPIRAM_SUPPORTED. change: the light-sleep test so an internal-RAM helper task enters light sleep while the PSRAM-stacked Unity task is blocked.Verifies that light sleep succeeds and that the PSRAM-stacked task resumes correctly afterward.Removes the unreliable sleep-callback counter check. --- tools/test_apps/system/.build-test-rules.yml | 6 +- .../psram_stack/main/test_psram_stack.c | 63 +++++++++---------- 2 files changed, 32 insertions(+), 37 deletions(-) diff --git a/tools/test_apps/system/.build-test-rules.yml b/tools/test_apps/system/.build-test-rules.yml index c841e477355..8bd6db3b4ae 100644 --- a/tools/test_apps/system/.build-test-rules.yml +++ b/tools/test_apps/system/.build-test-rules.yml @@ -174,7 +174,7 @@ tools/test_apps/system/panic/panic_base: tools/test_apps/system/psram_stack: disable: - - if: SOC_PSRAM_SUPPORTED != 1 + - if: SOC_SPIRAM_SUPPORTED != 1 reason: PSRAM stack feature requires a target with PSRAM support tools/test_apps/system/ram_loadable_app: @@ -254,5 +254,5 @@ tools/test_apps/system/unicore_bootloader: disable: - if: SOC_CPU_CORES_NUM == 1 reason: the test is only relevant for multicore chips - - if: CONFIG_NAME == "unicore_psram" and SOC_PSRAM_SUPPORTED != 1 - - if: CONFIG_NAME == "multicore_psram" and SOC_PSRAM_SUPPORTED != 1 + - if: CONFIG_NAME == "unicore_psram" and SOC_SPIRAM_SUPPORTED != 1 + - if: CONFIG_NAME == "multicore_psram" and SOC_SPIRAM_SUPPORTED != 1 diff --git a/tools/test_apps/system/psram_stack/main/test_psram_stack.c b/tools/test_apps/system/psram_stack/main/test_psram_stack.c index 7038a60693b..4948ec7c41c 100644 --- a/tools/test_apps/system/psram_stack/main/test_psram_stack.c +++ b/tools/test_apps/system/psram_stack/main/test_psram_stack.c @@ -16,18 +16,16 @@ #include #include "freertos/FreeRTOS.h" #include "freertos/task.h" +#include "freertos/idf_additions.h" #include "unity.h" -#include "esp_attr.h" #include "esp_heap_caps.h" #include "esp_memory_utils.h" #include "esp_partition.h" -#include "esp_pm.h" #include "esp_sleep.h" #include "esp_log.h" #include "nvs_flash.h" #include "nvs.h" #include "esp_flash_dispatcher.h" -#include "esp_private/esp_clk.h" #include "sdkconfig.h" #define WORKER_STACK_SIZE 4096 @@ -35,13 +33,8 @@ #define UNITY_STACK_SIZE 8192 #define NUM_CONCURRENT 5 #define CONCURRENT_READS 10 -#define MHZ 1000000 static const char *TAG = "psram_stack_test"; -#if CONFIG_PM_ENABLE && CONFIG_FREERTOS_USE_TICKLESS_IDLE && CONFIG_PM_LIGHT_SLEEP_CALLBACKS -static volatile uint32_t s_light_sleep_exit_count; -static volatile int64_t s_last_light_sleep_us; -#endif /* Confirm the calling task's stack is in PSRAM before each test body runs. */ #define ASSERT_STACK_IN_PSRAM() \ @@ -83,43 +76,45 @@ TEST_CASE("PSRAM stack: deep sleep rejected from PSRAM-stacked task", "[psram_st #if CONFIG_PM_ENABLE && CONFIG_FREERTOS_USE_TICKLESS_IDLE && CONFIG_PM_LIGHT_SLEEP_CALLBACKS -static esp_err_t IRAM_ATTR light_sleep_exit_cb(int64_t slept_us, void *arg) +typedef struct { + TaskHandle_t parent; + esp_err_t sleep_result; + bool stack_in_internal_ram; +} light_sleep_result_t; + +static void light_sleep_from_internal_stack(void *arg) { - (void)arg; + light_sleep_result_t *result = arg; + volatile uint8_t stack_probe = 0; - if (slept_us > 0) { - s_last_light_sleep_us = slept_us; - s_light_sleep_exit_count++; - } + result->stack_in_internal_ram = esp_ptr_in_dram((const void *)&stack_probe); + esp_sleep_enable_timer_wakeup(100000ULL); + result->sleep_result = esp_light_sleep_start(); - return ESP_OK; + xTaskNotifyGive(result->parent); + vTaskSuspend(NULL); } -TEST_CASE("PSRAM stack: task resumes correctly after tickless-idle light sleep", "[psram_stack][light_sleep]") +TEST_CASE("PSRAM stack: blocked task resumes correctly after light sleep", "[psram_stack][light_sleep]") { ASSERT_STACK_IN_PSRAM(); - s_light_sleep_exit_count = 0; - s_last_light_sleep_us = 0; - - esp_pm_sleep_cbs_register_config_t sleep_cbs = { - .exit_cb = light_sleep_exit_cb, + light_sleep_result_t result = { + .parent = xTaskGetCurrentTaskHandle(), + .sleep_result = ESP_FAIL, }; - TEST_ESP_OK(esp_pm_light_sleep_unregister_cbs(&sleep_cbs)); - TEST_ESP_OK(esp_pm_light_sleep_register_cbs(&sleep_cbs)); + TaskHandle_t sleep_task = NULL; + TEST_ASSERT_EQUAL( + pdPASS, + xTaskCreateWithCaps(light_sleep_from_internal_stack, "light_sleep", WORKER_STACK_SIZE, + &result, WORKER_PRIORITY, &sleep_task, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT)); + TEST_ASSERT_NOT_NULL(sleep_task); - printf("Waiting for tickless-idle light sleep...\n"); - vTaskDelay(pdMS_TO_TICKS(100)); - - const uint32_t exit_count = s_light_sleep_exit_count; - const int64_t last_slept_us = s_last_light_sleep_us; - TEST_ESP_OK(esp_pm_light_sleep_unregister_cbs(&sleep_cbs)); - - ESP_LOGI(TAG, "Auto light sleep exit callbacks: %" PRIu32 ", last slept: %" PRId64 " us", - exit_count, last_slept_us); - TEST_ASSERT_GREATER_THAN_UINT32(0, exit_count); - TEST_ASSERT_GREATER_THAN_UINT32(0, last_slept_us); + TEST_ASSERT_EQUAL_UINT32(1, ulTaskNotifyTake(pdTRUE, pdMS_TO_TICKS(1000))); + vTaskDeleteWithCaps(sleep_task); + TEST_ASSERT_TRUE_MESSAGE(result.stack_in_internal_ram, "light sleep task stack is not in internal RAM"); + TEST_ASSERT_EQUAL(ESP_OK, result.sleep_result); ASSERT_STACK_IN_PSRAM(); } From c41541b83b3914458803e4bdc9ca91d6c85f9cab Mon Sep 17 00:00:00 2001 From: Marius Vikhammer Date: Mon, 10 Aug 2026 10:02:48 +0200 Subject: [PATCH 2/2] fix(ipc): fixed IPC task ending up in PSRAM With CONFIG_FREERTOS_PLACE_TASK_STACKS_IN_EXT_RAM enabled IPC task would end up in PSRAM, causing issues with disabling cache --- components/esp_system/esp_ipc.c | 8 +++++--- tools/test_apps/system/psram_stack/README.md | 4 ++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/components/esp_system/esp_ipc.c b/components/esp_system/esp_ipc.c index 9141efd361a..8cda46c9632 100644 --- a/components/esp_system/esp_ipc.c +++ b/components/esp_system/esp_ipc.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -18,6 +18,7 @@ #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/semphr.h" +#include "freertos/idf_additions.h" #define IPC_MAX_PRIORITY (configMAX_PRIORITIES - 1) @@ -111,8 +112,9 @@ static void esp_ipc_init(void) task_name[3] = i + (char)'0'; s_ipc_mutex[i] = xSemaphoreCreateMutexStatic(&s_ipc_mutex_buffer[i]); s_ipc_ack[i] = xSemaphoreCreateBinaryStatic(&s_ipc_ack_buffer[i]); - BaseType_t res = xTaskCreatePinnedToCore(ipc_task, task_name, IPC_STACK_SIZE, (void*) i, - IPC_MAX_PRIORITY, &s_ipc_task_handle[i], i); + BaseType_t res = xTaskCreatePinnedToCoreWithCaps(ipc_task, task_name, IPC_STACK_SIZE, (void*) i, + IPC_MAX_PRIORITY, &s_ipc_task_handle[i], i, + MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); assert(res == pdTRUE); (void)res; } diff --git a/tools/test_apps/system/psram_stack/README.md b/tools/test_apps/system/psram_stack/README.md index 691f9018dee..0a0cf5d5c68 100644 --- a/tools/test_apps/system/psram_stack/README.md +++ b/tools/test_apps/system/psram_stack/README.md @@ -1,2 +1,2 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-H4 | ESP32-P4 | ESP32-S2 | ESP32-S3 | ESP32-S31 | Linux | -| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | -------- | --------- | ----- | +| Supported Targets | ESP32 | ESP32-C5 | ESP32-C61 | ESP32-H4 | ESP32-P4 | ESP32-S2 | ESP32-S3 | ESP32-S31 | +| ----------------- | ----- | -------- | --------- | -------- | -------- | -------- | -------- | --------- |