Merge branch 'refactor/spi_ram_stack_with_heap_caps_config' into 'master'

refactor(esp_psram): allow PSRAM as stack when PSRAM is only available via esp_heap_caps

Closes IDFGH-11604

See merge request espressif/esp-idf!32832
This commit is contained in:
Jakob Hasse
2024-08-20 16:48:44 +08:00
9 changed files with 120 additions and 3 deletions

View File

@@ -262,7 +262,7 @@ menu "SPI RAM config"
config SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY config SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY
bool "Allow external memory as an argument to xTaskCreateStatic" bool "Allow external memory as an argument to xTaskCreateStatic"
default n default n
depends on SPIRAM_USE_MALLOC depends on SPIRAM_USE_CAPS_ALLOC || SPIRAM_USE_MALLOC
help help
Because some bits of the ESP32 code environment cannot be recompiled with the cache workaround, Because some bits of the ESP32 code environment cannot be recompiled with the cache workaround,
normally tasks cannot be safely run with their stack residing in external memory; for this reason normally tasks cannot be safely run with their stack residing in external memory; for this reason

View File

@@ -1,6 +1,6 @@
# Documentation: .gitlab/ci/README.md#manifest-file-to-control-the-buildtest-apps # Documentation: .gitlab/ci/README.md#manifest-file-to-control-the-buildtest-apps
components/esp_psram/test_apps: components/esp_psram/test_apps/psram:
disable: disable:
- if: SOC_SPIRAM_SUPPORTED != 1 - if: SOC_SPIRAM_SUPPORTED != 1
depends_components: depends_components:
@@ -9,3 +9,11 @@ components/esp_psram/test_apps:
- esp_driver_gpio - esp_driver_gpio
- esp_driver_spi - esp_driver_spi
- spi_flash - spi_flash
components/esp_psram/test_apps/psram_no_malloc_task_stack:
enable:
- if: IDF_TARGET in ["esp32", "esp32p4"]
depends_components:
- esp_psram
- freertos

View File

@@ -0,0 +1,7 @@
# The following five lines of boilerplate have to be in your project's
# CMakeLists in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.16)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
set(COMPONENTS main)
project(psram_no_malloc_task_stack)

View File

@@ -0,0 +1,2 @@
| Supported Targets | ESP32 | ESP32-P4 |
| ----------------- | ----- | -------- |

View File

@@ -0,0 +1,3 @@
idf_component_register(SRCS "test_psram_no_malloc_task_stack.c"
INCLUDE_DIRS "."
PRIV_REQUIRES unity esp_psram freertos heap)

View File

@@ -0,0 +1,82 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#include <stdio.h>
#include "esp_log.h"
#include "unity.h"
#include "unity_test_runner.h"
#include "unity_test_utils_memory.h"
#include "unity_test_utils.h"
#include "esp_heap_caps.h"
#include "esp_memory_utils.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
static const char* TAG = "psram_no_malloc_task_stack_test";
#define STACK_SIZE 4096
#define WAIT_TICKS 2
#define TEST_TASK_PRIORITY 6 // relatively high priority to let task finish quickly
void setUp(void)
{
unity_utils_set_leak_level(0);
unity_utils_record_free_mem();
}
void tearDown(void)
{
unity_utils_evaluate_leaks();
}
static uint8_t *stack_memory;
static StaticTask_t *tcb_memory;
static bool is_external;
static SemaphoreHandle_t task_waiter;
static void test_task(void *arg)
{
int dummy = 47;
is_external = esp_ptr_external_ram(&dummy);
xSemaphoreGive(task_waiter);
vTaskDelay(portMAX_DELAY);
}
TEST_CASE("FreeRTOS task with stack on SPIRAM works", "[psram]")
{
stack_memory = heap_caps_malloc(STACK_SIZE, MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM);
TEST_ASSERT_NOT_NULL(stack_memory);
tcb_memory = heap_caps_malloc(sizeof(StaticTask_t), MALLOC_CAP_8BIT);
TEST_ASSERT_NOT_NULL(tcb_memory);
task_waiter = xSemaphoreCreateBinary();
TEST_ASSERT_NOT_NULL(task_waiter);
TaskHandle_t task = xTaskCreateStatic(test_task,
"heap caps static",
STACK_SIZE,
NULL,
TEST_TASK_PRIORITY,
stack_memory,
tcb_memory);
TEST_ASSERT_NOT_NULL(task);
TEST_ASSERT_EQUAL(pdTRUE, xSemaphoreTake(task_waiter, WAIT_TICKS));
TEST_ASSERT_EQUAL(true, is_external);
// use unity_utils_task_delete() to avoid deleting stack of a still running task
unity_utils_task_delete(task);
vSemaphoreDelete(task_waiter);
heap_caps_free(tcb_memory);
heap_caps_free(stack_memory);
}
void app_main(void)
{
ESP_LOGI(TAG, "Running PSRAM task stack test app with SPIRAM_USE_CAPS_ALLOC");
unity_run_menu();
}

View File

@@ -0,0 +1,11 @@
# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: CC0-1.0
import pytest
from pytest_embedded import Dut
@pytest.mark.esp32
@pytest.mark.esp32p4
@pytest.mark.generic
def test_psram_no_malloc_task_stack(dut: Dut) -> None:
dut.run_all_single_board_cases()

View File

@@ -0,0 +1,4 @@
CONFIG_ESP_TASK_WDT_EN=n
CONFIG_SPIRAM=y
CONFIG_SPIRAM_USE_CAPS_ALLOC=y
CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY=y

View File

@@ -133,7 +133,7 @@ def common_test(dut: PanicTestDut, config: str, expected_backtrace: Optional[Lis
elif 'panic' in config: elif 'panic' in config:
pass pass
dut.expect('Rebooting...') dut.expect('Rebooting...', timeout=60)
if check_cpu_reset: if check_cpu_reset:
dut.expect_cpu_reset() dut.expect_cpu_reset()