diff --git a/components/espcoredump/Kconfig b/components/espcoredump/Kconfig index 199d4e0bc8..623fc059ac 100644 --- a/components/espcoredump/Kconfig +++ b/components/espcoredump/Kconfig @@ -91,7 +91,8 @@ menu "Core dump" depends on ESP_COREDUMP_ENABLE range 0 4096 if !ESP_COREDUMP_USE_STACK_SIZE range 1280 4096 if ESP_COREDUMP_USE_STACK_SIZE - default 0 + default 0 if !ESP_COREDUMP_USE_STACK_SIZE + default 1280 if ESP_COREDUMP_USE_STACK_SIZE help Size of the memory to be reserved for core dump stack. If 0 core dump process will run on the stack of crashed task/ISR, otherwise special stack will be allocated. diff --git a/tools/test_apps/system/panic/main/CMakeLists.txt b/tools/test_apps/system/panic/main/CMakeLists.txt index 83427066bf..92dc346341 100644 --- a/tools/test_apps/system/panic/main/CMakeLists.txt +++ b/tools/test_apps/system/panic/main/CMakeLists.txt @@ -1,3 +1,3 @@ idf_component_register(SRCS "test_panic_main.c" INCLUDE_DIRS "." - REQUIRES spi_flash esp_system esp_partition) + REQUIRES spi_flash esp_psram esp_system esp_partition) diff --git a/tools/test_apps/system/panic/main/test_panic_main.c b/tools/test_apps/system/panic/main/test_panic_main.c index 2b4c4512ef..5d9211e52f 100644 --- a/tools/test_apps/system/panic/main/test_panic_main.c +++ b/tools/test_apps/system/panic/main/test_panic_main.c @@ -17,6 +17,9 @@ static void test_abort(void); static void test_abort_cache_disabled(void); static void test_int_wdt(void); static void test_task_wdt_cpu0(void); +#if CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH && CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY +static void test_panic_extram_stack(void); +#endif #if !CONFIG_FREERTOS_UNICORE static void test_task_wdt_cpu1(void); static void test_task_wdt_both_cpus(void); @@ -55,6 +58,9 @@ void app_main(void) HANDLE_TEST(test_abort_cache_disabled); HANDLE_TEST(test_int_wdt); HANDLE_TEST(test_task_wdt_cpu0); +#if CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH && CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY + HANDLE_TEST(test_panic_extram_stack); +#endif #if !CONFIG_FREERTOS_UNICORE HANDLE_TEST(test_task_wdt_cpu1); HANDLE_TEST(test_task_wdt_both_cpus); @@ -102,6 +108,34 @@ static void test_task_wdt_cpu0(void) } } +#if CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH && CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY + +static void stack_in_extram(void* arg) { + (void) arg; + /* Abort instead of using a load/store prohibited to prevent a sanitize error */ + abort(); +} + +static void test_panic_extram_stack(void) { + /* Start by initializing a Task which has a stack in external RAM */ + StaticTask_t handle; + const uint32_t stack_size = 8192; + void* stack = heap_caps_malloc(stack_size, MALLOC_CAP_SPIRAM); + + /* Make sure the stack is in external RAM */ + if (!esp_ptr_external_ram(stack)) { + die("Allocated stack is not in external RAM!\n"); + } + + xTaskCreateStatic(stack_in_extram, "Task_stack_extram", stack_size, NULL, 4, (StackType_t*) stack, &handle); + + vTaskDelay(1000); +} + + +#endif // ESP_COREDUMP_ENABLE_TO_FLASH && SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY + + #if !CONFIG_FREERTOS_UNICORE static void infinite_loop(void* arg) { (void) arg; diff --git a/tools/test_apps/system/panic/pytest_panic.py b/tools/test_apps/system/panic/pytest_panic.py index a923f8cf4e..ff7a64e76c 100644 --- a/tools/test_apps/system/panic/pytest_panic.py +++ b/tools/test_apps/system/panic/pytest_panic.py @@ -28,6 +28,14 @@ CONFIGS_ESP32 = [ pytest.param('panic', marks=[pytest.mark.esp32]), ] +# IDF-5692: Uncomment the marks related to ESP32-S3 and quad_psram once ESP32-S3 runners are available +CONFIG_EXTRAM_STACK = [ + pytest.param('coredump_extram_stack', + marks=[pytest.mark.esp32, pytest.mark.esp32s2, pytest.mark.psram, + # pytest.mark.esp32s3, pytest.mark.quad_psram + ]) +] + def get_default_backtrace(config: str) -> List[str]: return [config, 'app_main', 'main_task', 'vPortTaskWrapper'] @@ -142,6 +150,23 @@ def test_task_wdt_both_cpus(dut: PanicTestDut, config: str, test_func_name: str) common_test(dut, config) +@pytest.mark.parametrize('config', CONFIG_EXTRAM_STACK, indirect=True) +def test_panic_extram_stack(dut: PanicTestDut, config: str, test_func_name: str) -> None: + dut.expect_test_func_name(test_func_name) + dut.expect_none('Allocated stack is not in external RAM') + dut.expect_none('Guru Meditation') + dut.expect_backtrace() + dut.expect_elf_sha256() + # Check that coredump is getting written to flash + dut.expect_exact('Save core dump to flash...') + # And that the stack is replaced and restored + dut.expect_exact('Backing up stack @') + dut.expect_exact('Restoring stack') + # The caller must be accessible after restoring the stack + dut.expect_exact('Core dump has been saved to flash.') + common_test(dut, config) + + @pytest.mark.parametrize('config', CONFIGS, indirect=True) @pytest.mark.generic def test_int_wdt( diff --git a/tools/test_apps/system/panic/sdkconfig.ci.coredump_extram_stack b/tools/test_apps/system/panic/sdkconfig.ci.coredump_extram_stack new file mode 100644 index 0000000000..06ac9fcc8e --- /dev/null +++ b/tools/test_apps/system/panic/sdkconfig.ci.coredump_extram_stack @@ -0,0 +1,11 @@ +CONFIG_IDF_TARGET="esp32" +CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH=y +CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF=y +CONFIG_ESP_COREDUMP_CHECKSUM_SHA256=y +# CONFIG_ESP_SYSTEM_PANIC_GDBSTUB is not set +CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT=y +# We need to have the coredump info log +CONFIG_LOG_DEFAULT_LEVEL_INFO=y +CONFIG_SPIRAM=y +CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY=y +CONFIG_ESP_COREDUMP_USE_STACK_SIZE=y