diff --git a/components/esp_common/include/esp_attr.h b/components/esp_common/include/esp_attr.h index 9dcd66b093..7e543d7d11 100644 --- a/components/esp_common/include/esp_attr.h +++ b/components/esp_common/include/esp_attr.h @@ -137,8 +137,11 @@ extern "C" { #if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY // Forces bss variable into external memory. " #define EXT_RAM_BSS_ATTR _SECTION_ATTR_IMPL(".ext_ram.bss", __COUNTER__) +// Forces data into external memory BSS and maps it to coredump +#define COREDUMP_EXTRAM_ATTR _SECTION_ATTR_IMPL(".ext_ram.coredump", __COUNTER__) #else #define EXT_RAM_BSS_ATTR +#define COREDUMP_EXTRAM_ATTR #endif // Forces data into noinit section to avoid initialization after restart. @@ -147,9 +150,12 @@ extern "C" { #if CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY // Forces data into external memory noinit section to avoid initialization after restart. #define EXT_RAM_NOINIT_ATTR _SECTION_ATTR_IMPL(".ext_ram_noinit", __COUNTER__) +// Forces data into external memory noinit section and maps it to coredump +#define COREDUMP_EXTRAM_NOINIT_ATTR _SECTION_ATTR_IMPL(".ext_ram_noinit.coredump", __COUNTER__) #else // Place in internal noinit section #define EXT_RAM_NOINIT_ATTR __NOINIT_ATTR +#define COREDUMP_EXTRAM_NOINIT_ATTR #endif // Forces code into DRAM instead of flash and map it to coredump diff --git a/components/espcoredump/include_core_dump/esp_core_dump_common.h b/components/espcoredump/include_core_dump/esp_core_dump_common.h index 5c23c73dcf..1db4397165 100644 --- a/components/espcoredump/include_core_dump/esp_core_dump_common.h +++ b/components/espcoredump/include_core_dump/esp_core_dump_common.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -38,6 +38,12 @@ typedef enum { COREDUMP_MEMORY_RTC_FAST, #endif COREDUMP_MEMORY_NOINIT, +#if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY + COREDUMP_MEMORY_EXTRAM, +#endif +#if CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY + COREDUMP_MEMORY_EXTRAM_NOINIT, +#endif COREDUMP_MEMORY_MAX, COREDUMP_MEMORY_START = COREDUMP_MEMORY_IRAM } coredump_region_t; diff --git a/components/espcoredump/linker.lf b/components/espcoredump/linker.lf index 9e4f893df7..5e1cae98ce 100644 --- a/components/espcoredump/linker.lf +++ b/components/espcoredump/linker.lf @@ -25,6 +25,14 @@ entries: entries: .noinit.coredump+ +[sections:extram_coredump] +entries: + .ext_ram.coredump+ + +[sections:extram_noinit_coredump] +entries: + .ext_ram_noinit.coredump+ + [scheme:coredump_default] entries: dram_coredump -> dram0_data @@ -33,6 +41,8 @@ entries: rtc_noinit_coredump -> rtc_noinit noinit_coredump -> noinit iram_coredump -> iram0_data + extram_coredump -> extern_ram + extram_noinit_coredump -> extram_noinit [mapping:coredump_default] archive: * @@ -43,7 +53,9 @@ entries: rtc_noinit_coredump -> rtc_noinit SURROUND(coredump_rtc_noinit), noinit_coredump -> noinit SURROUND(coredump_noinit), dram_coredump -> dram0_data SURROUND(coredump_dram), - iram_coredump -> iram0_data SURROUND(coredump_iram) + iram_coredump -> iram0_data SURROUND(coredump_iram), + extram_coredump -> extern_ram SURROUND(coredump_extram), + extram_noinit_coredump -> extram_noinit SURROUND(coredump_extram_noinit) [mapping:espcoredump] archive: libespcoredump.a diff --git a/components/espcoredump/src/core_dump_common.c b/components/espcoredump/src/core_dump_common.c index 2a12cef523..3267a277ea 100644 --- a/components/espcoredump/src/core_dump_common.c +++ b/components/espcoredump/src/core_dump_common.c @@ -57,6 +57,14 @@ extern int _coredump_rtc_noinit_end; extern int _coredump_noinit_start; extern int _coredump_noinit_end; #endif +#if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY +extern int _coredump_extram_start; +extern int _coredump_extram_end; +#endif +#if CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY +extern int _coredump_extram_noinit_start; +extern int _coredump_extram_noinit_end; +#endif static void* s_exc_frame = NULL; static uint32_t s_coredump_sp = 0; @@ -271,6 +279,12 @@ static const struct { #else [COREDUMP_MEMORY_NOINIT] = { &_coredump_noinit_start, &_coredump_noinit_end }, #endif +#if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY + [COREDUMP_MEMORY_EXTRAM] = { &_coredump_extram_start, &_coredump_extram_end }, +#endif +#if CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY + [COREDUMP_MEMORY_EXTRAM_NOINIT] = { &_coredump_extram_noinit_start, &_coredump_extram_noinit_end }, +#endif }; int esp_core_dump_get_user_ram_info(coredump_region_t region, uint32_t *start) diff --git a/tools/test_apps/system/panic/main/include/test_panic.h b/tools/test_apps/system/panic/main/include/test_panic.h index b61c70aa75..cc46d3dc78 100644 --- a/tools/test_apps/system/panic/main/include/test_panic.h +++ b/tools/test_apps/system/panic/main/include/test_panic.h @@ -87,6 +87,10 @@ void test_panic_print_backtrace(void); void test_panic_halt(void); #endif /* CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT */ +#if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY && CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY +void test_panic_extram_attr(void); +#endif + #ifdef __cplusplus } #endif diff --git a/tools/test_apps/system/panic/main/test_app_main.c b/tools/test_apps/system/panic/main/test_app_main.c index 8413507b16..a50cb8e0ba 100644 --- a/tools/test_apps/system/panic/main/test_app_main.c +++ b/tools/test_apps/system/panic/main/test_app_main.c @@ -218,5 +218,9 @@ void app_main(void) #endif #endif +#if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY && CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY + HANDLE_TEST(test_name, test_panic_extram_attr); +#endif + die("Unknown test name"); } diff --git a/tools/test_apps/system/panic/main/test_panic.c b/tools/test_apps/system/panic/main/test_panic.c index 6947146e22..62edf6ef48 100644 --- a/tools/test_apps/system/panic/main/test_panic.c +++ b/tools/test_apps/system/panic/main/test_panic.c @@ -430,6 +430,16 @@ void test_capture_dram(void) } #endif +#if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY && CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY +COREDUMP_EXTRAM_ATTR uint32_t g_extram_bss_var; +COREDUMP_EXTRAM_NOINIT_ATTR uint32_t g_extram_noinit_var; +void test_panic_extram_attr(void) +{ + g_extram_bss_var = 123456; + g_extram_noinit_var = 789012; + assert(0); +} +#endif #if CONFIG_ESP_SYSTEM_USE_FRAME_POINTER diff --git a/tools/test_apps/system/panic/pytest_panic.py b/tools/test_apps/system/panic/pytest_panic.py index ffcd8b1e81..c97e796545 100644 --- a/tools/test_apps/system/panic/pytest_panic.py +++ b/tools/test_apps/system/panic/pytest_panic.py @@ -284,6 +284,25 @@ def test_panic_extram_stack(dut: PanicTestDut, config: str) -> None: common_test(dut, config, expected_backtrace=None, expected_coredump=[coredump_pattern]) +@pytest.mark.psram +@idf_parametrize('config, target', [('coredump_flash_extram_attr_esp32', 'esp32')], indirect=['config', 'target']) +def test_panic_extram_attr(dut: PanicTestDut, config: str) -> None: + dut.run_test_func('test_panic_extram_attr') + regex_pattern = rb'assert failed:[\s\w()]*?\s[.\w/]*\.(?:c|cpp|h|hpp):\d.*$' + dut.expect(re.compile(regex_pattern, re.MULTILINE)) + dut.expect_backtrace() + dut.expect_elf_sha256() + dut.expect_none(['Guru Meditation', 'Re-entered core dump']) + + expect_coredump_flash_write_logs(dut, config) + core_elf_file = dut.process_coredump_flash() + + dut.start_gdb_for_coredump(core_elf_file) + + assert dut.gdb_data_eval_expr('g_extram_bss_var') == '123456' + assert dut.gdb_data_eval_expr('g_extram_noinit_var') == '789012' + + @pytest.mark.generic @idf_parametrize('config, target', CONFIGS, indirect=['config', 'target']) @pytest.mark.temp_skip_ci(targets=['esp32p4'], reason='p4 rev3 migration')