Merge branch 'fix/mmap_cache_flash_wr_v6.1' into 'release/v6.1'

fix(mmap): fixed mmap read data wrong when flash being erased/written and cache not disabled (v6.1)

See merge request espressif/esp-idf!50117
This commit is contained in:
Jiang Jiang Jian
2026-07-17 10:30:14 +08:00
73 changed files with 1680 additions and 488 deletions
+7 -2
View File
@@ -142,11 +142,16 @@ tools/test_apps/system/no_embedded_paths:
reason: the other targets are not tested yet
tools/test_apps/system/panic/coredump:
enable:
- if: IDF_TARGET in ["esp32", "esp32c2", "esp32c3", "esp32c5", "esp32c6", "esp32c61", "esp32h2", "esp32p4", "esp32s2", "esp32s3", "esp32s31"]
disable:
- if: CONFIG_NAME in ["coredump_flash_extram_stack_bss", "coredump_flash_extram_stack_heap"] and SOC_SPIRAM_SUPPORTED != 1
- if: CONFIG_NAME == "coredump_flash_extram_stack_bss_xip" and SOC_SPIRAM_XIP_SUPPORTED != 1
- if: IDF_TARGET in ["esp32h4", "esp32h21"]
temporary: true
reason: IDF-12308, IDF-11543
depends_components:
- espcoredump
- esp_system
- spi_flash
tools/test_apps/system/panic/panic_base:
enable:
@@ -7,6 +7,7 @@ from pathlib import Path
import pytest
from pytest_embedded_idf.utils import idf_parametrize
from pytest_embedded_idf.utils import soc_filtered_targets
PANIC_BASE_APP = Path(__file__).resolve().parent.parent / 'panic_base'
sys.path.insert(0, str(PANIC_BASE_APP))
@@ -78,30 +79,17 @@ def test_task_wdt_cpu1(dut: PanicTestDut, config: str, test_func_name: str) -> N
panic_tests.test_task_wdt_cpu1(dut, config, test_func_name)
@pytest.mark.parametrize(
'app_path, config, target',
[
pytest.param(COREDUMP_APP, 'coredump_flash_extram_stack_heap_esp32', 'esp32', marks=(pytest.mark.psram,)),
pytest.param(COREDUMP_APP, 'coredump_flash_extram_stack_heap_esp32s2', 'esp32s2', marks=(pytest.mark.generic,)),
pytest.param(
COREDUMP_APP, 'coredump_flash_extram_stack_heap_esp32s3', 'esp32s3', marks=(pytest.mark.quad_psram,)
),
pytest.param(COREDUMP_APP, 'coredump_flash_extram_stack_bss_esp32', 'esp32', marks=(pytest.mark.psram,)),
pytest.param(COREDUMP_APP, 'coredump_flash_extram_stack_bss_esp32s2', 'esp32s2', marks=(pytest.mark.generic,)),
pytest.param(
COREDUMP_APP, 'coredump_flash_extram_stack_bss_esp32s3', 'esp32s3', marks=(pytest.mark.quad_psram,)
),
],
indirect=True,
)
def test_panic_extram_stack(dut: PanicTestDut, config: str) -> None:
def _test_panic_extram_stack_impl(dut: PanicTestDut, config: str) -> None:
if 'heap' in config:
dut.run_test_func('test_panic_extram_stack_heap')
else:
dut.run_test_func('test_panic_extram_stack_bss')
dut.expect_none('Allocated stack is not in external RAM')
dut.expect_none('Guru Meditation')
dut.expect_backtrace()
if dut.is_xtensa:
dut.expect_backtrace()
else:
dut.expect_stack_dump()
dut.expect_elf_sha256()
if dut.target == 'esp32':
@@ -112,13 +100,70 @@ def test_panic_extram_stack(dut: PanicTestDut, config: str) -> None:
coredump_pattern = re.compile(
'.coredump.tasks.data (0x3[fF][5-9a-fA-F][0-7][0-9a-fA-F]{4}) (0x[a-fA-F0-9]+) RW'
)
else:
elif dut.target == 'esp32s3':
# ESP32-S3 External data memory range [0x3c000000-0x3e000000)
coredump_pattern = re.compile('.coredump.tasks.data (0x3[c-dC-D][0-9a-fA-F]{6}) (0x[a-fA-F0-9]+) RW')
else:
# RISC-V targets (esp32c5, esp32c61, etc.) External data memory range [0x42000000-0x44000000)
coredump_pattern = re.compile('.coredump.tasks.data (0x4[2-3][0-9a-fA-F]{6}) (0x[a-fA-F0-9]+) RW')
common_test(dut, config, expected_backtrace=None, expected_coredump=[coredump_pattern])
def get_psram_marker(target: str) -> pytest.mark:
if target == 'esp32':
return pytest.mark.psram
elif target == 'esp32s3':
return pytest.mark.quad_psram
return pytest.mark.generic
@pytest.mark.parametrize(
'app_path, config, target',
[
pytest.param(COREDUMP_APP, 'coredump_flash_extram_stack_heap', target, marks=(get_psram_marker(target),))
for target in soc_filtered_targets('SOC_SPIRAM_SUPPORTED == 1')
],
indirect=True,
)
@pytest.mark.temp_skip_ci(targets=['esp32p4'], reason='p4 rev3 migration')
@pytest.mark.temp_skip_ci(targets=['esp32c5', 'esp32c61', 'esp32p4', 'esp32s31'], reason='TODO: IDF-15623')
@pytest.mark.temp_skip_ci(targets=['esp32h4'], reason='IDF-12308')
def test_panic_extram_stack_heap_psram(dut: PanicTestDut, config: str) -> None:
_test_panic_extram_stack_impl(dut, config)
@pytest.mark.parametrize(
'app_path, config, target',
[
pytest.param(COREDUMP_APP, 'coredump_flash_extram_stack_bss', target, marks=(get_psram_marker(target),))
for target in soc_filtered_targets('SOC_SPIRAM_SUPPORTED == 1')
],
indirect=True,
)
@pytest.mark.temp_skip_ci(targets=['esp32p4'], reason='p4 rev3 migration')
@pytest.mark.temp_skip_ci(targets=['esp32c5', 'esp32c61', 'esp32p4', 'esp32s31'], reason='TODO: IDF-15623')
@pytest.mark.temp_skip_ci(targets=['esp32h4'], reason='IDF-12308')
def test_panic_extram_stack_heap_bss(dut: PanicTestDut, config: str) -> None:
_test_panic_extram_stack_impl(dut, config)
@pytest.mark.parametrize(
'app_path, config, target',
[
pytest.param(COREDUMP_APP, 'coredump_flash_extram_stack_bss_xip', target, marks=(get_psram_marker(target),))
for target in soc_filtered_targets('SOC_SPIRAM_XIP_SUPPORTED == 1')
],
indirect=True,
)
@pytest.mark.temp_skip_ci(targets=['esp32p4'], reason='p4 rev3 migration')
@pytest.mark.temp_skip_ci(targets=['esp32c5', 'esp32c61', 'esp32p4', 'esp32s31'], reason='TODO: IDF-15623')
@pytest.mark.temp_skip_ci(targets=['esp32h4'], reason='IDF-12308')
def test_panic_extram_stack_heap_bss_xip(dut: PanicTestDut, config: str) -> None:
_test_panic_extram_stack_impl(dut, config)
@pytest.mark.generic
@pytest.mark.parametrize('app_path, config', CONFIGS, indirect=True)
@idf_parametrize('target', COREDUMP_TARGETS_ALL, indirect=['target'])
@@ -1,4 +1,3 @@
CONFIG_IDF_TARGET="esp32"
CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH=y
# We need to have the coredump info log
CONFIG_LOG_DEFAULT_LEVEL_INFO=y
@@ -1,11 +0,0 @@
CONFIG_IDF_TARGET="esp32s3"
CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH=y
# We need to have the coredump info log
CONFIG_LOG_DEFAULT_LEVEL_INFO=y
CONFIG_SPIRAM=y
CONFIG_FREERTOS_TASK_CREATE_ALLOW_EXT_MEM=y
CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY=y
CONFIG_ESP_COREDUMP_USE_STACK_SIZE=y
CONFIG_ESP_COREDUMP_CAPTURE_DRAM=y
CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_capture_dram.csv"
@@ -1,8 +1,8 @@
CONFIG_IDF_TARGET="esp32s2"
CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH=y
# We need to have the coredump info log
CONFIG_LOG_DEFAULT_LEVEL_INFO=y
CONFIG_SPIRAM=y
CONFIG_SPIRAM_XIP_FROM_PSRAM=y
CONFIG_FREERTOS_TASK_CREATE_ALLOW_EXT_MEM=y
CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY=y
CONFIG_ESP_COREDUMP_USE_STACK_SIZE=y
@@ -1,4 +1,3 @@
CONFIG_IDF_TARGET="esp32"
CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH=y
# We need to have the coredump info log
CONFIG_LOG_DEFAULT_LEVEL_INFO=y
@@ -1,7 +0,0 @@
CONFIG_IDF_TARGET="esp32s2"
CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH=y
# We need to have the coredump info log
CONFIG_LOG_DEFAULT_LEVEL_INFO=y
CONFIG_SPIRAM=y
CONFIG_FREERTOS_TASK_CREATE_ALLOW_EXT_MEM=y
CONFIG_ESP_COREDUMP_USE_STACK_SIZE=y
@@ -1,7 +0,0 @@
CONFIG_IDF_TARGET="esp32s3"
CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH=y
# We need to have the coredump info log
CONFIG_LOG_DEFAULT_LEVEL_INFO=y
CONFIG_SPIRAM=y
CONFIG_FREERTOS_TASK_CREATE_ALLOW_EXT_MEM=y
CONFIG_ESP_COREDUMP_USE_STACK_SIZE=y
@@ -41,7 +41,7 @@ static void s_test_ext_vaddr(void)
}
}
static void s_test_flash_mmap_data_integrity(void)
static void s_test_flash_mmap_data_integrity_nonblock(void)
{
char src_p_1[32] = "Test data pattern 123456789";
char src_p_2[32] = "Test data pattern 987654321";
@@ -50,16 +50,41 @@ static void s_test_flash_mmap_data_integrity(void)
spi_flash_mmap_handle_t handle1;
const void *ptr1;
TEST_ESP_OK(spi_flash_mmap(addr, SPI_FLASH_SEC_SIZE, SPI_FLASH_MMAP_DATA, &ptr1, &handle1));
TEST_ESP_OK(spi_flash_mmap(addr, SPI_FLASH_SEC_SIZE, SPI_FLASH_MMAP_FLAG_DATA, &ptr1, &handle1));
TEST_ESP_OK(esp_flash_erase_region(NULL, addr, SPI_FLASH_SEC_SIZE));
TEST_ESP_OK(esp_flash_write(NULL, src_p_1, addr, sizeof(src_p_1)));
memcpy(buf, ptr1, sizeof(buf));
TEST_ASSERT_EQUAL(0, memcmp(buf, src_p_1, sizeof(buf)));
TEST_ESP_OK(esp_flash_erase_region(NULL, addr, SPI_FLASH_SEC_SIZE));
TEST_ESP_OK(esp_flash_write(NULL, src_p_2, addr, sizeof(src_p_2)));
memcpy(buf, ptr1, sizeof(buf));
TEST_ASSERT_EQUAL(0, memcmp(buf, src_p_2, sizeof(buf)));
spi_flash_munmap(handle1);
}
static void s_test_flash_mmap_data_integrity_block(void)
{
char src_p_1[32] = "Test data pattern 123456789";
char src_p_2[32] = "Test data pattern 987654321";
char buf[32];
const int addr = 0x10000;
spi_flash_mmap_handle_t handle1;
const void *ptr1;
TEST_ESP_OK(esp_flash_erase_region(NULL, addr, SPI_FLASH_SEC_SIZE));
TEST_ESP_OK(esp_flash_write(NULL, src_p_1, addr, sizeof(src_p_1)));
TEST_ESP_OK(spi_flash_mmap(addr, SPI_FLASH_SEC_SIZE, SPI_FLASH_MMAP_FLAG_DATA | SPI_FLASH_MMAP_FLAG_BLOCKS_WRITE, &ptr1, &handle1));
memcpy(buf, ptr1, sizeof(buf));
TEST_ASSERT_EQUAL(0, memcmp(buf, src_p_1, sizeof(buf)));
spi_flash_munmap(handle1);
TEST_ESP_OK(esp_flash_erase_region(NULL, addr, SPI_FLASH_SEC_SIZE));
TEST_ESP_OK(esp_flash_write(NULL, src_p_2, addr, sizeof(src_p_2)));
TEST_ESP_OK(spi_flash_mmap(addr, SPI_FLASH_SEC_SIZE, SPI_FLASH_MMAP_FLAG_DATA | SPI_FLASH_MMAP_FLAG_BLOCKS_WRITE, &ptr1, &handle1));
memcpy(buf, ptr1, sizeof(buf));
TEST_ASSERT_EQUAL(0, memcmp(buf, src_p_2, sizeof(buf)));
spi_flash_munmap(handle1);
}
@@ -85,7 +110,8 @@ void app_main(void)
#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP
s_test_ext_vaddr();
s_test_flash_mmap_data_integrity();
s_test_flash_mmap_data_integrity_block();
s_test_flash_mmap_data_integrity_nonblock();
#endif
uint32_t uptime = 0;