diff --git a/components/esp_system/test_apps/.build-test-rules.yml b/components/esp_system/test_apps/.build-test-rules.yml index 9985a538bd..27f3165dc1 100644 --- a/components/esp_system/test_apps/.build-test-rules.yml +++ b/components/esp_system/test_apps/.build-test-rules.yml @@ -1,5 +1,9 @@ # Documentation: .gitlab/ci/README.md#manifest-file-to-control-the-buildtest-apps +components/esp_system/test_apps/cache_panic: + depends_components: + - spi_flash # esp_system is included by default + components/esp_system/test_apps/console: disable: - if: CONFIG_NAME == "serial_jtag_only" and SOC_USB_SERIAL_JTAG_SUPPORTED != 1 diff --git a/components/esp_system/test_apps/cache_panic/CMakeLists.txt b/components/esp_system/test_apps/cache_panic/CMakeLists.txt new file mode 100644 index 0000000000..fd5f8fb78a --- /dev/null +++ b/components/esp_system/test_apps/cache_panic/CMakeLists.txt @@ -0,0 +1,8 @@ +# This is the project CMakeLists.txt file for the test subproject +cmake_minimum_required(VERSION 3.16) + +# "Trim" the build. Include the minimal set of components, main, and anything it depends on. +set(COMPONENTS main) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(cache_panic) diff --git a/components/esp_system/test_apps/cache_panic/README.md b/components/esp_system/test_apps/cache_panic/README.md new file mode 100644 index 0000000000..7b96141437 --- /dev/null +++ b/components/esp_system/test_apps/cache_panic/README.md @@ -0,0 +1,2 @@ +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- | diff --git a/components/esp_system/test_apps/cache_panic/main/CMakeLists.txt b/components/esp_system/test_apps/cache_panic/main/CMakeLists.txt new file mode 100644 index 0000000000..e0f128b847 --- /dev/null +++ b/components/esp_system/test_apps/cache_panic/main/CMakeLists.txt @@ -0,0 +1,6 @@ +set(srcs "test_cache_disabled.c" + "test_app_main.c") + +idf_component_register(SRCS ${srcs} + PRIV_REQUIRES unity spi_flash + WHOLE_ARCHIVE) diff --git a/components/esp_system/test_apps/cache_panic/main/test_app_main.c b/components/esp_system/test_apps/cache_panic/main/test_app_main.c new file mode 100644 index 0000000000..05944419cc --- /dev/null +++ b/components/esp_system/test_apps/cache_panic/main/test_app_main.c @@ -0,0 +1,55 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "unity.h" +#include "unity_test_runner.h" +#include "esp_heap_caps.h" + +#define TEST_MEMORY_LEAK_THRESHOLD (-200) + +static size_t before_free_8bit; +static size_t before_free_32bit; + +static void check_leak(size_t before_free, size_t after_free, const char *type) +{ + ssize_t delta = after_free - before_free; + printf("MALLOC_CAP_%s: Before %u bytes free, After %u bytes free (delta %d)\n", type, before_free, after_free, delta); + TEST_ASSERT_MESSAGE(delta >= TEST_MEMORY_LEAK_THRESHOLD, "memory leak"); +} + +void setUp(void) +{ + before_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT); + before_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT); +} + +void tearDown(void) +{ + size_t after_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT); + size_t after_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT); + check_leak(before_free_8bit, after_free_8bit, "8BIT"); + check_leak(before_free_32bit, after_free_32bit, "32BIT"); +} + +void app_main(void) +{ + + // _____ _ _____ _ _______ _ + // / ____| | | | __ \ (_) |__ __| | | + // | | __ _ ___| |__ ___ | |__) |_ _ _ __ _ ___ | | ___ ___| |_ + // | | / _` |/ __| '_ \ / _ \ | ___/ _` | '_ \| |/ __| | |/ _ \/ __| __| + // | |___| (_| | (__| | | | __/ | | | (_| | | | | | (__ | | __/\__ \ |_ + // \_____\__,_|\___|_| |_|\___| |_| \__,_|_| |_|_|\___| |_|\___||___/\__| + + printf(" _____ _ _____ _ _______ _\n"); + printf(" / ____| | | | __ \\ (_) |__ __| | |\n"); + printf(" | | __ _ ___| |__ ___ | |__) |_ _ _ __ _ ___ | | ___ ___| |_\n"); + printf(" | | / _` |/ __| '_ \\ / _ \\ | ___/ _` | '_ \\| |/ __| | |/ _ \\/ __| __|\n"); + printf(" | |___| (_| | (__| | | | __/ | | | (_| | | | | | (__ | | __/\\__ \\ |_\n"); + printf(" \\_____\\__,_|\\___|_| |_|\\___| |_| \\__,_|_| |_|_|\\___| |_|\\___||___/\\__|\n"); + + unity_run_menu(); +} diff --git a/components/spi_flash/test_apps/mspi_test/main/test_cache_disabled.c b/components/esp_system/test_apps/cache_panic/main/test_cache_disabled.c similarity index 84% rename from components/spi_flash/test_apps/mspi_test/main/test_cache_disabled.c rename to components/esp_system/test_apps/cache_panic/main/test_cache_disabled.c index d92b876234..19fd6b9ef7 100644 --- a/components/spi_flash/test_apps/mspi_test/main/test_cache_disabled.c +++ b/components/esp_system/test_apps/cache_panic/main/test_cache_disabled.c @@ -8,27 +8,21 @@ #include #include #include -#include -#include -#include - -#include -#include -#include -#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/semphr.h" +#include "unity.h" +#include "esp_attr.h" #include "esp_memory_utils.h" - #include "esp_private/cache_utils.h" -//TODO: IDF-6730, migrate this test to test_app - static QueueHandle_t result_queue; static IRAM_ATTR void cache_test_task(void *arg) { bool do_disable = (bool)arg; bool result; - if(do_disable) { + if (do_disable) { spi_flash_disable_interrupts_caches_and_other_cpu(); } result = spi_flash_cache_enabled(); @@ -36,7 +30,7 @@ static IRAM_ATTR void cache_test_task(void *arg) spi_flash_enable_interrupts_caches_and_other_cpu(); } - TEST_ASSERT( xQueueSendToBack(result_queue, &result, 0) ); + TEST_ASSERT(xQueueSendToBack(result_queue, &result, 0)); vTaskDelete(NULL); } @@ -44,16 +38,16 @@ TEST_CASE("spi_flash_cache_enabled() works on both CPUs", "[spi_flash][esp_flash { result_queue = xQueueCreate(1, sizeof(bool)); - for(int cpu = 0; cpu < CONFIG_FREERTOS_NUMBER_OF_CORES; cpu++) { - for(int disable = 0; disable <= 1; disable++) { + for (int cpu = 0; cpu < CONFIG_FREERTOS_NUMBER_OF_CORES; cpu++) { + for (int disable = 0; disable <= 1; disable++) { bool do_disable = disable; bool result; printf("Testing cpu %d disabled %d\n", cpu, do_disable); xTaskCreatePinnedToCore(cache_test_task, "cache_check_task", - 2048, (void *)do_disable, configMAX_PRIORITIES-1, NULL, cpu); + 2048, (void *)do_disable, configMAX_PRIORITIES - 1, NULL, cpu); - TEST_ASSERT( xQueueReceive(result_queue, &result, 2) ); + TEST_ASSERT(xQueueReceive(result_queue, &result, 2)); TEST_ASSERT_EQUAL(!do_disable, result); } } @@ -64,7 +58,6 @@ TEST_CASE("spi_flash_cache_enabled() works on both CPUs", "[spi_flash][esp_flash #if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2) - // This needs to sufficiently large array, otherwise it may end up in // DRAM (e.g. size <= 8 bytes && ARCH == RISCV) static const uint32_t s_in_rodata[8] = { 0x12345678, 0xfedcba98 }; @@ -100,13 +93,12 @@ static void IRAM_ATTR cache_access_test_func(void* arg) #define CACHE_ERROR_REASON "Cache error,SW_CPU" #endif - // These tests works properly if they resets the chip with the // "Cache disabled but cached memory region accessed" reason and the correct CPU is logged. static void invalid_access_to_cache_pro_cpu(void) { xTaskCreatePinnedToCore(&cache_access_test_func, "ia", 2048, NULL, 5, NULL, 0); - vTaskDelay(1000/portTICK_PERIOD_MS); + vTaskDelay(1000 / portTICK_PERIOD_MS); } TEST_CASE_MULTIPLE_STAGES("invalid access to cache raises panic (PRO CPU)", "[spi_flash][reset="CACHE_ERROR_REASON"]", invalid_access_to_cache_pro_cpu, reset_after_invalid_cache); @@ -116,7 +108,7 @@ TEST_CASE_MULTIPLE_STAGES("invalid access to cache raises panic (PRO CPU)", "[sp static void invalid_access_to_cache_app_cpu(void) { xTaskCreatePinnedToCore(&cache_access_test_func, "ia", 2048, NULL, 5, NULL, 1); - vTaskDelay(1000/portTICK_PERIOD_MS); + vTaskDelay(1000 / portTICK_PERIOD_MS); } TEST_CASE_MULTIPLE_STAGES("invalid access to cache raises panic (APP CPU)", "[spi_flash][reset="CACHE_ERROR_REASON"]", invalid_access_to_cache_app_cpu, reset_after_invalid_cache); diff --git a/components/esp_system/test_apps/cache_panic/pytest_cache_panic_test.py b/components/esp_system/test_apps/cache_panic/pytest_cache_panic_test.py new file mode 100644 index 0000000000..f107e348a0 --- /dev/null +++ b/components/esp_system/test_apps/cache_panic/pytest_cache_panic_test.py @@ -0,0 +1,10 @@ +# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: Apache-2.0 +import pytest +from pytest_embedded import Dut + + +@pytest.mark.supported_targets +@pytest.mark.generic +def test_cache_panic(dut: Dut) -> None: + dut.run_all_single_board_cases() diff --git a/components/esp_system/test_apps/cache_panic/sdkconfig.defaults b/components/esp_system/test_apps/cache_panic/sdkconfig.defaults new file mode 100644 index 0000000000..e4bfc208a5 --- /dev/null +++ b/components/esp_system/test_apps/cache_panic/sdkconfig.defaults @@ -0,0 +1 @@ +CONFIG_ESP_TASK_WDT_EN=n diff --git a/components/spi_flash/test_apps/mspi_test/main/CMakeLists.txt b/components/spi_flash/test_apps/mspi_test/main/CMakeLists.txt index 4e1e8bed59..10af23bbe6 100644 --- a/components/spi_flash/test_apps/mspi_test/main/CMakeLists.txt +++ b/components/spi_flash/test_apps/mspi_test/main/CMakeLists.txt @@ -1,5 +1,4 @@ -set(srcs "test_cache_disabled.c" - "test_out_of_bounds_write.c" +set(srcs "test_out_of_bounds_write.c" "test_read_write.c" "test_large_flash_writes.c" "test_app_main.c")