From fbe93aa25e815900f121a70c2f484934f16280d7 Mon Sep 17 00:00:00 2001 From: Mahavir Jain Date: Thu, 17 Oct 2024 21:44:35 +0530 Subject: [PATCH] test: add configurable mmu page size test app Test app to ensure that bootloader and application built with different flash MMU page size are compatible. This is for the SoCs that support configurable flash MMU page size. --- tools/test_apps/system/.build-test-rules.yml | 9 ++++ .../system/mmu_page_size/CMakeLists.txt | 7 +++ .../test_apps/system/mmu_page_size/README.md | 5 ++ .../system/mmu_page_size/conftest.py | 51 ++++++++++++++++++ .../system/mmu_page_size/main/CMakeLists.txt | 2 + .../system/mmu_page_size/main/main.c | 40 ++++++++++++++ .../system/mmu_page_size/partitions.csv | 6 +++ .../mmu_page_size/pytest_mmu_page_size.py | 52 +++++++++++++++++++ .../system/mmu_page_size/sdkconfig.ci.32K | 2 + .../system/mmu_page_size/sdkconfig.ci.64K | 2 + .../system/mmu_page_size/sdkconfig.defaults | 1 + 11 files changed, 177 insertions(+) create mode 100644 tools/test_apps/system/mmu_page_size/CMakeLists.txt create mode 100644 tools/test_apps/system/mmu_page_size/README.md create mode 100644 tools/test_apps/system/mmu_page_size/conftest.py create mode 100644 tools/test_apps/system/mmu_page_size/main/CMakeLists.txt create mode 100644 tools/test_apps/system/mmu_page_size/main/main.c create mode 100644 tools/test_apps/system/mmu_page_size/partitions.csv create mode 100644 tools/test_apps/system/mmu_page_size/pytest_mmu_page_size.py create mode 100644 tools/test_apps/system/mmu_page_size/sdkconfig.ci.32K create mode 100644 tools/test_apps/system/mmu_page_size/sdkconfig.ci.64K create mode 100644 tools/test_apps/system/mmu_page_size/sdkconfig.defaults diff --git a/tools/test_apps/system/.build-test-rules.yml b/tools/test_apps/system/.build-test-rules.yml index 209d0e9866..c98392018b 100644 --- a/tools/test_apps/system/.build-test-rules.yml +++ b/tools/test_apps/system/.build-test-rules.yml @@ -62,6 +62,15 @@ tools/test_apps/system/memprot: temporary: true reason: the other targets are not tested yet +tools/test_apps/system/mmu_page_size: + enable: + - if: IDF_TARGET in ["esp32c6", "esp32h2"] + reason: Coverage for two targets with configurable MMU page size is sufficient + depends_components: + - esp_app_format + - bootloader_support + - esp_mm + tools/test_apps/system/no_embedded_paths: enable: - if: IDF_TARGET in ["esp32", "esp32c3", "esp32s2"] diff --git a/tools/test_apps/system/mmu_page_size/CMakeLists.txt b/tools/test_apps/system/mmu_page_size/CMakeLists.txt new file mode 100644 index 0000000000..9a2312cf5b --- /dev/null +++ b/tools/test_apps/system/mmu_page_size/CMakeLists.txt @@ -0,0 +1,7 @@ +# The following 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(test_mmu_page_size) diff --git a/tools/test_apps/system/mmu_page_size/README.md b/tools/test_apps/system/mmu_page_size/README.md new file mode 100644 index 0000000000..0163e2dec5 --- /dev/null +++ b/tools/test_apps/system/mmu_page_size/README.md @@ -0,0 +1,5 @@ +| Supported Targets | ESP32-C6 | ESP32-H2 | +| ----------------- | -------- | -------- | + +This test app ensures that bootloader can support configurable MMU page size as per the application binary header. +This test tries to boot the application with different MMU page sizes and checks if the application is able to boot successfully. diff --git a/tools/test_apps/system/mmu_page_size/conftest.py b/tools/test_apps/system/mmu_page_size/conftest.py new file mode 100644 index 0000000000..21d1a1145e --- /dev/null +++ b/tools/test_apps/system/mmu_page_size/conftest.py @@ -0,0 +1,51 @@ +# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: Apache-2.0 +import logging +import os + +import pytest +from _pytest.fixtures import FixtureRequest +from _pytest.monkeypatch import MonkeyPatch +from pytest_embedded_idf.app import FlashFile +from pytest_embedded_idf.serial import IdfSerial + + +# This is a custom IdfSerial class to support custom functionality +# which is required only for this test +class FlashBootloader(IdfSerial): + def bootloader_flash(self, binary_path: str) -> None: + """ + Flash bootloader. + + :return: None + """ + logging.info('Flashing bootloader') + bootloader_path = os.path.join(binary_path, 'bootloader', 'bootloader.bin') + logging.info(bootloader_path) + offs = int(self.app.sdkconfig.get('BOOTLOADER_OFFSET_IN_FLASH', 0)) + logging.info('bootloader offset is {0}'.format(hex(offs))) + prev_flash_files = self.app.flash_files + flash_files = [] + flash_files.append( + FlashFile( + offs, + bootloader_path, + False, + ) + ) + self.app.flash_files = flash_files + self.flash() + # Restore self.app.flash files to original value + self.app.flash_files = prev_flash_files + + +@pytest.fixture(scope='module') +def monkeypatch_module(request: FixtureRequest) -> MonkeyPatch: + mp = MonkeyPatch() + request.addfinalizer(mp.undo) + return mp + + +@pytest.fixture(scope='module', autouse=True) +def replace_dut_class(monkeypatch_module: MonkeyPatch) -> None: + monkeypatch_module.setattr('pytest_embedded_idf.IdfSerial', FlashBootloader) diff --git a/tools/test_apps/system/mmu_page_size/main/CMakeLists.txt b/tools/test_apps/system/mmu_page_size/main/CMakeLists.txt new file mode 100644 index 0000000000..06087b89d5 --- /dev/null +++ b/tools/test_apps/system/mmu_page_size/main/CMakeLists.txt @@ -0,0 +1,2 @@ +idf_component_register(SRCS "main.c" + PRIV_REQUIRES unity esp_partition) diff --git a/tools/test_apps/system/mmu_page_size/main/main.c b/tools/test_apps/system/mmu_page_size/main/main.c new file mode 100644 index 0000000000..a820c55c54 --- /dev/null +++ b/tools/test_apps/system/mmu_page_size/main/main.c @@ -0,0 +1,40 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#include "unity.h" +#include "esp_partition.h" + +#define SZ 4096 + +void app_main(void) +{ + printf("App is running\n"); + + // Perform some partition and memory map related operations + char src_p_1[32] = "Test data pattern 123456789"; + char buf[32]; + + // Find storage partition + const esp_partition_t* partition = esp_partition_find_first( + ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_FAT, NULL); + TEST_ASSERT_NOT_NULL(partition); + + esp_partition_mmap_handle_t handle1; + const void *ptr1; + TEST_ESP_OK(esp_partition_mmap(partition, 0, SZ, ESP_PARTITION_MMAP_DATA, &ptr1, &handle1)); + TEST_ESP_OK(esp_partition_erase_range(partition, 0, SZ)); + TEST_ESP_OK(esp_partition_write(partition, 0, src_p_1, sizeof(src_p_1))); + memcpy(buf, ptr1, sizeof(buf)); + + TEST_ASSERT_EQUAL(0, memcmp(buf, src_p_1, sizeof(buf))); + esp_partition_munmap(handle1); + + printf("Partition test done\n"); +} diff --git a/tools/test_apps/system/mmu_page_size/partitions.csv b/tools/test_apps/system/mmu_page_size/partitions.csv new file mode 100644 index 0000000000..5f1296d92d --- /dev/null +++ b/tools/test_apps/system/mmu_page_size/partitions.csv @@ -0,0 +1,6 @@ +# Name, Type, SubType, Offset, Size, Flags +# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap +nvs, data, nvs, , 0x6000, +phy_init, data, phy, , 0x1000, +factory, app, factory, , 1M, +storage, data, fat, , 64K, diff --git a/tools/test_apps/system/mmu_page_size/pytest_mmu_page_size.py b/tools/test_apps/system/mmu_page_size/pytest_mmu_page_size.py new file mode 100644 index 0000000000..cd9eb47db2 --- /dev/null +++ b/tools/test_apps/system/mmu_page_size/pytest_mmu_page_size.py @@ -0,0 +1,52 @@ +# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: CC0-1.0 +import os + +import pytest +from artifacts_handler import ArtifactType +from idf_ci_utils import IDF_PATH +from pytest_embedded import Dut + + +@pytest.mark.esp32c6 +@pytest.mark.esp32h2 +@pytest.mark.generic +@pytest.mark.parametrize('config', ['32K'], indirect=True) +def test_app_mmu_page_size_32k_and_bootloader_mmu_page_size_64k(dut: Dut, app_downloader, config) -> None: # type: ignore + dut.expect('App is running') + + assert '32K' in config + app_config = config.replace('32K', '64K') + + path_to_mmu_page_size_64k_build = os.path.join(dut.app.app_path, f'build_{dut.target}_{app_config}') + if app_downloader: + app_downloader.download_app( + os.path.relpath(path_to_mmu_page_size_64k_build, IDF_PATH), ArtifactType.BUILD_DIR_WITHOUT_MAP_AND_ELF_FILES + ) + + dut.serial.bootloader_flash(path_to_mmu_page_size_64k_build) + dut.expect('MMU page size mismatch') + dut.expect('App is running') + dut.expect('Partition test done\n') + + +@pytest.mark.esp32c6 +@pytest.mark.esp32h2 +@pytest.mark.generic +@pytest.mark.parametrize('config', ['64K'], indirect=True) +def test_app_mmu_page_size_64k_and_bootloader_mmu_page_size_32k(dut: Dut, app_downloader, config) -> None: # type: ignore + dut.expect('App is running') + + assert '64K' in config + app_config = config.replace('64K', '32K') + + path_to_mmu_page_size_32k_build = os.path.join(dut.app.app_path, f'build_{dut.target}_{app_config}') + if app_downloader: + app_downloader.download_app( + os.path.relpath(path_to_mmu_page_size_32k_build, IDF_PATH), ArtifactType.BUILD_DIR_WITHOUT_MAP_AND_ELF_FILES + ) + + dut.serial.bootloader_flash(path_to_mmu_page_size_32k_build) + dut.expect('MMU page size mismatch') + dut.expect('App is running') + dut.expect('Partition test done\n') diff --git a/tools/test_apps/system/mmu_page_size/sdkconfig.ci.32K b/tools/test_apps/system/mmu_page_size/sdkconfig.ci.32K new file mode 100644 index 0000000000..d2d45ce8e2 --- /dev/null +++ b/tools/test_apps/system/mmu_page_size/sdkconfig.ci.32K @@ -0,0 +1,2 @@ +# This config option internally select 32KB MMU page size +CONFIG_ESPTOOLPY_FLASHSIZE_2MB=y diff --git a/tools/test_apps/system/mmu_page_size/sdkconfig.ci.64K b/tools/test_apps/system/mmu_page_size/sdkconfig.ci.64K new file mode 100644 index 0000000000..f57de8fda2 --- /dev/null +++ b/tools/test_apps/system/mmu_page_size/sdkconfig.ci.64K @@ -0,0 +1,2 @@ +# This config option internally select 64KB MMU page size +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y diff --git a/tools/test_apps/system/mmu_page_size/sdkconfig.defaults b/tools/test_apps/system/mmu_page_size/sdkconfig.defaults new file mode 100644 index 0000000000..4b0421e1ab --- /dev/null +++ b/tools/test_apps/system/mmu_page_size/sdkconfig.defaults @@ -0,0 +1 @@ +CONFIG_PARTITION_TABLE_CUSTOM=y