diff --git a/.gitlab/ci/rules.yml b/.gitlab/ci/rules.yml index 9659fc8f1c..61b91ac9cc 100644 --- a/.gitlab/ci/rules.yml +++ b/.gitlab/ci/rules.yml @@ -2803,19 +2803,6 @@ - <<: *if-dev-push changes: *patterns-unit_test -.rules:test:unit_test-esp32c3-flash_multi: - rules: - - <<: *if-revert-branch - when: never - - <<: *if-protected - - <<: *if-label-build-only - when: never - - <<: *if-label-target_test - - <<: *if-label-unit_test - - <<: *if-label-unit_test_esp32c3 - - <<: *if-dev-push - changes: *patterns-unit_test-flash_multi - .rules:test:unit_test-esp32c3-sdio: rules: - <<: *if-revert-branch diff --git a/.gitlab/ci/target-test.yml b/.gitlab/ci/target-test.yml index 18a5ec83bb..ca1cdb0c36 100644 --- a/.gitlab/ci/target-test.yml +++ b/.gitlab/ci/target-test.yml @@ -1253,12 +1253,6 @@ UT_033: - UT_T2_Ethernet - psram -UT_034: - extends: .unit_test_esp32_template - tags: - - ESP32_IDF - - UT_T1_ESP_FLASH - UT_035: extends: .unit_test_esp32s2_template parallel: 16 @@ -1266,12 +1260,6 @@ UT_035: - ESP32S2_IDF - UT_T1_1 -UT_038: - extends: .unit_test_esp32s2_template - tags: - - ESP32S2_IDF - - UT_T1_ESP_FLASH - UT_S2_SDSPI: extends: - .unit_test_esp32s2_template @@ -1288,14 +1276,6 @@ UT_C2: - UT_T1_1 - xtal_40mhz -UT_C2_FLASH: - extends: - - .unit_test_esp32c2_template - tags: - - ESP32C2_IDF - - UT_T1_ESP_FLASH - - xtal_40mhz - UT_C3: extends: .unit_test_esp32c3_template parallel: 11 @@ -1303,14 +1283,6 @@ UT_C3: - ESP32C3_IDF - UT_T1_1 -UT_C3_FLASH: - extends: - - .unit_test_esp32c3_template - - .rules:test:unit_test-esp32c3-flash_multi - tags: - - ESP32C3_IDF - - UT_T1_ESP_FLASH - UT_C3_SDSPI: extends: - .unit_test_esp32c3_template @@ -1340,12 +1312,6 @@ UT_S3: - ESP32S3_IDF - UT_T1_1 -UT_S3_FLASH: - extends: .unit_test_esp32s3_template - tags: - - ESP32S3_IDF - - UT_T1_ESP_FLASH - UT_S3_QUAD_PSRAM: extends: .unit_test_esp32s3_template diff --git a/components/spi_flash/.build-test-rules.yml b/components/spi_flash/.build-test-rules.yml index aaa7c74123..573f9e1ceb 100644 --- a/components/spi_flash/.build-test-rules.yml +++ b/components/spi_flash/.build-test-rules.yml @@ -1,11 +1,5 @@ # Documentation: .gitlab/ci/README.md#manifest-file-to-control-the-buildtest-apps -components/spi_flash/test_apps/esp_flash: - disable: - - if: IDF_TARGET == "esp32c6" or IDF_TARGET == "esp32h2" - temporary: true - reason: target esp32c6 cannot pass atomic build, target esp32h2 currently doesn't support GPSPI. - components/spi_flash/test_apps/flash_encryption: disable_test: - if: IDF_TARGET in ["esp32c2", "esp32s2", "esp32c6", "esp32h2"] @@ -19,3 +13,8 @@ components/spi_flash/test_apps/flash_suspend: - if: IDF_TARGET != "esp32c3" temporary: true reason: lack of runners + +components/spi_flash/test_apps/mspi_test: + disable: + - if: CONFIG_NAME == "psram" and SOC_SPIRAM_SUPPORTED != 1 + - if: CONFIG_NAME == "xip_psram" and SOC_SPIRAM_SUPPORTED != 1 diff --git a/components/spi_flash/test/test_esp_flash.c b/components/spi_flash/test/test_esp_flash.c deleted file mode 100644 index 764b4f42e0..0000000000 --- a/components/spi_flash/test/test_esp_flash.c +++ /dev/null @@ -1,652 +0,0 @@ -#include -#include -#include -#include -#include - -#include -#include "esp_flash.h" -#include "esp_private/spi_common_internal.h" -#include "spi_flash_mmap.h" -#include "esp_flash_spi_init.h" -#include "memspi_host_driver.h" -#include -#include "esp_log.h" - - -#include - -#include "unity.h" -#include "driver/gpio.h" -#include "soc/io_mux_reg.h" -#include "sdkconfig.h" - -#include "ccomp_timer.h" -#include "esp_rom_gpio.h" -#include "esp_rom_sys.h" -#include "esp_timer.h" - -#if CONFIG_IDF_TARGET_ESP32S2 -#include "esp32s2/rom/cache.h" -#elif CONFIG_IDF_TARGET_ESP32S3 -#include "esp32s3/rom/cache.h" -#elif CONFIG_IDF_TARGET_ESP32C3 -#include "esp32c3/rom/cache.h" -#elif CONFIG_IDF_TARGET_ESP32C2 -#include "esp32c2/rom/cache.h" -#endif - -#define FUNC_SPI 1 - -#define MAX_ADDR_24BIT 0x1000000 -#define TEST_SPI_SPEED 10 -#define TEST_SPI_READ_MODE SPI_FLASH_FASTRD -// #define FORCE_GPIO_MATRIX - -#if CONFIG_IDF_TARGET_ESP32 -#define EXTRA_SPI1_CLK_IO 17 //the pin which is usually used by the PSRAM clk -#define SPI1_CS_IO 16 //the pin which is usually used by the PSRAM cs - -#define HSPI_PIN_NUM_MOSI HSPI_IOMUX_PIN_NUM_MOSI -#define HSPI_PIN_NUM_MISO HSPI_IOMUX_PIN_NUM_MISO -#define HSPI_PIN_NUM_CLK HSPI_IOMUX_PIN_NUM_CLK -#define HSPI_PIN_NUM_HD HSPI_IOMUX_PIN_NUM_HD -#define HSPI_PIN_NUM_WP HSPI_IOMUX_PIN_NUM_WP -#define HSPI_PIN_NUM_CS HSPI_IOMUX_PIN_NUM_CS - -#define VSPI_PIN_NUM_MOSI VSPI_IOMUX_PIN_NUM_MOSI -#define VSPI_PIN_NUM_MISO VSPI_IOMUX_PIN_NUM_MISO -#define VSPI_PIN_NUM_CLK VSPI_IOMUX_PIN_NUM_CLK -#define VSPI_PIN_NUM_HD VSPI_IOMUX_PIN_NUM_HD -#define VSPI_PIN_NUM_WP VSPI_IOMUX_PIN_NUM_WP -#define VSPI_PIN_NUM_CS VSPI_IOMUX_PIN_NUM_CS - -#elif CONFIG_IDF_TARGET_ESP32S2 -#define SPI1_CS_IO 26 //the pin which is usually used by the PSRAM cs -#define SPI1_HD_IO 27 //the pin which is usually used by the PSRAM hd -#define SPI1_WP_IO 28 //the pin which is usually used by the PSRAM wp - -#define FSPI_PIN_NUM_MOSI 35 -#define FSPI_PIN_NUM_MISO 37 -#define FSPI_PIN_NUM_CLK 36 -#define FSPI_PIN_NUM_HD 33 -#define FSPI_PIN_NUM_WP 38 -#define FSPI_PIN_NUM_CS 34 - -// Just use the same pins for HSPI -#define HSPI_PIN_NUM_MOSI FSPI_PIN_NUM_MOSI -#define HSPI_PIN_NUM_MISO FSPI_PIN_NUM_MISO -#define HSPI_PIN_NUM_CLK FSPI_PIN_NUM_CLK -#define HSPI_PIN_NUM_HD FSPI_PIN_NUM_HD -#define HSPI_PIN_NUM_WP FSPI_PIN_NUM_WP -#define HSPI_PIN_NUM_CS FSPI_PIN_NUM_CS - -#elif CONFIG_IDF_TARGET_ESP32S3 -#define SPI1_CS_IO 26 //the pin which is usually used by the PSRAM cs -#define SPI1_HD_IO 27 //the pin which is usually used by the PSRAM hd -#define SPI1_WP_IO 28 //the pin which is usually used by the PSRAM wp - -#define FSPI_PIN_NUM_MOSI 11 -#define FSPI_PIN_NUM_MISO 13 -#define FSPI_PIN_NUM_CLK 12 -#define FSPI_PIN_NUM_HD 9 -#define FSPI_PIN_NUM_WP 14 -#define FSPI_PIN_NUM_CS 10 - -// Just use the same pins for HSPI -#define HSPI_PIN_NUM_MOSI FSPI_PIN_NUM_MOSI -#define HSPI_PIN_NUM_MISO FSPI_PIN_NUM_MISO -#define HSPI_PIN_NUM_CLK FSPI_PIN_NUM_CLK -#define HSPI_PIN_NUM_HD FSPI_PIN_NUM_HD -#define HSPI_PIN_NUM_WP FSPI_PIN_NUM_WP -#define HSPI_PIN_NUM_CS FSPI_PIN_NUM_CS - -#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2 -#define SPI1_CS_IO 26 //the pin which is usually used by the PSRAM cs -#define SPI1_HD_IO 27 //the pin which is usually used by the PSRAM hd -#define SPI1_WP_IO 28 //the pin which is usually used by the PSRAM wp - -#define FSPI_PIN_NUM_MOSI 7 -#define FSPI_PIN_NUM_MISO 2 -#define FSPI_PIN_NUM_CLK 6 -#define FSPI_PIN_NUM_HD 4 -#define FSPI_PIN_NUM_WP 5 -#define FSPI_PIN_NUM_CS 10 - -// Just use the same pins for HSPI -#define HSPI_PIN_NUM_MOSI FSPI_PIN_NUM_MOSI -#define HSPI_PIN_NUM_MISO FSPI_PIN_NUM_MISO -#define HSPI_PIN_NUM_CLK FSPI_PIN_NUM_CLK -#define HSPI_PIN_NUM_HD FSPI_PIN_NUM_HD -#define HSPI_PIN_NUM_WP FSPI_PIN_NUM_WP -#define HSPI_PIN_NUM_CS FSPI_PIN_NUM_CS -#endif - -#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C6, ESP32H2) -#define TEST_CONFIG_NUM (sizeof(config_list)/sizeof(flashtest_config_t)) - -typedef void (*flash_test_func_t)(const esp_partition_t *part); - -/* Use TEST_CASE_FLASH for SPI flash tests that only use the main SPI flash chip -*/ -#define TEST_CASE_FLASH(STR, FUNC_TO_RUN) \ - TEST_CASE(STR, "[esp_flash]") {flash_test_func(FUNC_TO_RUN, 1 /* first index reserved for main flash */ );} - -#define TEST_CASE_FLASH_IGNORE(STR, FUNC_TO_RUN) \ - TEST_CASE(STR, "[esp_flash][ignore]") {flash_test_func(FUNC_TO_RUN, 1 /* first index reserved for main flash */ );} - -/* Use TEST_CASE_MULTI_FLASH for tests which also run on external flash, which sits in the place of PSRAM - (these tests are incompatible with PSRAM) - - These tests run for all the flash chip configs shown in config_list, below (internal and external). - */ - - -#if defined(CONFIG_SPIRAM) -//SPI1 CS1 occupied by PSRAM -#define BYPASS_MULTIPLE_CHIP 1 -#endif - -#if CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 -//chips without PSRAM -#define TEST_CHIP_NUM 2 -#elif CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 -#define TEST_CHIP_NUM 3 -#endif - -#define _STRINGIFY(s) #s -#define STRINGIFY(s) _STRINGIFY(s) -#define TEST_CHIP_NUM_STR STRINGIFY(TEST_CHIP_NUM) - -#if BYPASS_MULTIPLE_CHIP -#define TEST_CASE_MULTI_FLASH TEST_CASE_MULTI_FLASH_IGNORE -#else -#if CONFIG_FREERTOS_SMP // IDF-5260 -#define TEST_CASE_MULTI_FLASH(STR, FUNC_TO_RUN) \ - TEST_CASE(STR", "TEST_CHIP_NUM_STR" chips", "[esp_flash_multi][test_env=UT_T1_ESP_FLASH][timeout=60]") {flash_test_func(FUNC_TO_RUN, TEST_CONFIG_NUM);} -#else -#define TEST_CASE_MULTI_FLASH(STR, FUNC_TO_RUN) \ - TEST_CASE(STR", "TEST_CHIP_NUM_STR" chips", "[esp_flash_multi][test_env=UT_T1_ESP_FLASH][timeout=35]") {flash_test_func(FUNC_TO_RUN, TEST_CONFIG_NUM);} -#endif -#endif - -#define TEST_CASE_MULTI_FLASH_IGNORE(STR, FUNC_TO_RUN) \ - TEST_CASE(STR", "TEST_CHIP_NUM_STR" chips", "[esp_flash_multi][test_env=UT_T1_ESP_FLASH][ignore]") {flash_test_func(FUNC_TO_RUN, TEST_CONFIG_NUM);} - - -//currently all the configs are the same with esp_flash_spi_device_config_t, no more information required -typedef esp_flash_spi_device_config_t flashtest_config_t; - -static const char TAG[] = "test_esp_flash"; - -#define FLASHTEST_CONFIG_COMMON \ - /* 0 always reserved for main flash */ \ - { \ - /* no need to init */ \ - .host_id = -1, \ - } \ - , \ - { \ - .io_mode = TEST_SPI_READ_MODE,\ - .freq_mhz = TEST_SPI_SPEED, \ - .host_id = SPI1_HOST, \ - .cs_id = 1, \ - /* the pin which is usually used by the PSRAM */ \ - .cs_io_num = SPI1_CS_IO, \ - .input_delay_ns = 0, \ - } - -#if CONFIG_IDF_TARGET_ESP32 -flashtest_config_t config_list[] = { - FLASHTEST_CONFIG_COMMON, - /* current runner doesn't have a flash on HSPI */ - // { - // .io_mode = TEST_SPI_READ_MODE, - // .freq_mhz = TEST_SPI_SPEED, - // .host_id = HSPI_HOST, - // .cs_id = 0, - // // uses GPIO matrix on esp32s2 regardless if FORCE_GPIO_MATRIX - // .cs_io_num = HSPI_PIN_NUM_CS, - // .input_delay_ns = 20, - // }, - { - .io_mode = TEST_SPI_READ_MODE, - .freq_mhz = TEST_SPI_SPEED, - .host_id = VSPI_HOST, - .cs_id = 0, - .cs_io_num = VSPI_PIN_NUM_CS, - .input_delay_ns = 0, - }, -}; -#elif CONFIG_IDF_TARGET_ESP32S2 -flashtest_config_t config_list[] = { - FLASHTEST_CONFIG_COMMON, - { - .io_mode = TEST_SPI_READ_MODE, - .freq_mhz = TEST_SPI_SPEED, - .host_id = FSPI_HOST, - .cs_id = 0, - .cs_io_num = FSPI_PIN_NUM_CS, - .input_delay_ns = 0, - }, - { - .io_mode = TEST_SPI_READ_MODE, - .freq_mhz = TEST_SPI_SPEED, - .host_id = HSPI_HOST, - .cs_id = 0, - // uses GPIO matrix on esp32s2 regardless of FORCE_GPIO_MATRIX - .cs_io_num = HSPI_PIN_NUM_CS, - .input_delay_ns = 0, - }, -}; -#elif CONFIG_IDF_TARGET_ESP32S3 -flashtest_config_t config_list[] = { - /* No SPI1 CS1 flash on esp32S3 test */ - { - /* no need to init */ - .host_id = -1, - }, - { - .io_mode = TEST_SPI_READ_MODE, - .freq_mhz = TEST_SPI_SPEED, - .host_id = SPI2_HOST, - .cs_id = 0, - .cs_io_num = FSPI_PIN_NUM_CS, - .input_delay_ns = 0, - }, -}; -#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2 -flashtest_config_t config_list[] = { - /* No SPI1 CS1 flash on esp32c3 test */ - { - /* no need to init */ - .host_id = -1, - }, - { - .io_mode = TEST_SPI_READ_MODE, - .freq_mhz = TEST_SPI_SPEED, - .host_id = SPI2_HOST, - .cs_id = 0, - .cs_io_num = FSPI_PIN_NUM_CS, - .input_delay_ns = 0, - }, -}; -#endif - -static void get_chip_host(esp_flash_t* chip, spi_host_device_t* out_host_id, int* out_cs_id) -{ - spi_host_device_t host_id; - int cs_id; - if (chip == NULL) { - host_id = SPI1_HOST; - cs_id = 0; - } else { - spi_flash_hal_context_t* host_data = (spi_flash_hal_context_t*)chip->host; - host_id = spi_flash_ll_hw_get_id(host_data->spi); - cs_id = host_data->cs_num; - } - if (out_host_id) { - *out_host_id = host_id; - } - if (out_cs_id) { - *out_cs_id = cs_id; - } -} - -#if CONFIG_IDF_TARGET_ESP32 -static void setup_bus(spi_host_device_t host_id) -{ - if (host_id == SPI1_HOST) { - ESP_LOGI(TAG, "setup flash on SPI1 CS1...\n"); - //no need to initialize the bus, however the CLK may need one more output if it's on the usual place of PSRAM - esp_rom_gpio_connect_out_signal(EXTRA_SPI1_CLK_IO, SPICLK_OUT_IDX, 0, 0); - //currently the SPI bus for main flash chip is initialized through GPIO matrix - } else if (host_id == SPI2_HOST) { - ESP_LOGI(TAG, "setup flash on SPI%d (HSPI) CS0...\n", host_id + 1); - spi_bus_config_t hspi_bus_cfg = { - .mosi_io_num = HSPI_PIN_NUM_MOSI, - .miso_io_num = HSPI_PIN_NUM_MISO, - .sclk_io_num = HSPI_PIN_NUM_CLK, - .quadhd_io_num = HSPI_PIN_NUM_HD, - .quadwp_io_num = HSPI_PIN_NUM_WP, - .max_transfer_sz = 64, - }; - esp_err_t ret = spi_bus_initialize(host_id, &hspi_bus_cfg, 0); - TEST_ESP_OK(ret); - } else if (host_id == SPI3_HOST) { - ESP_LOGI(TAG, "setup flash on SPI%d (VSPI) CS0...\n", host_id + 1); - spi_bus_config_t vspi_bus_cfg = { - .mosi_io_num = VSPI_PIN_NUM_MOSI, - .miso_io_num = VSPI_PIN_NUM_MISO, - .sclk_io_num = VSPI_PIN_NUM_CLK, - .quadhd_io_num = VSPI_PIN_NUM_HD, - .quadwp_io_num = VSPI_PIN_NUM_WP, - .max_transfer_sz = 64, - }; - esp_err_t ret = spi_bus_initialize(host_id, &vspi_bus_cfg, 0); - TEST_ESP_OK(ret); - } else { - ESP_LOGE(TAG, "invalid bus"); - } -} -#else // FOR ESP32-S2, ESP32-S3, ESP32-C3 -static void setup_bus(spi_host_device_t host_id) -{ - if (host_id == SPI1_HOST) { - ESP_LOGI(TAG, "setup flash on SPI1 CS1...\n"); -#if !CONFIG_ESPTOOLPY_FLASHMODE_QIO && !CONFIG_ESPTOOLPY_FLASHMODE_QOUT - //Initialize the WP and HD pins, which are not automatically initialized on ESP32-S2. - int wp_pin = spi_periph_signal[host_id].spiwp_iomux_pin; - int hd_pin = spi_periph_signal[host_id].spihd_iomux_pin; - gpio_iomux_in(wp_pin, spi_periph_signal[host_id].spiwp_in); - gpio_iomux_out(wp_pin, spi_periph_signal[host_id].func, false); - gpio_iomux_in(hd_pin, spi_periph_signal[host_id].spihd_in); - gpio_iomux_out(hd_pin, spi_periph_signal[host_id].func, false); -#endif //CONFIG_ESPTOOLPY_FLASHMODE_QIO || CONFIG_ESPTOOLPY_FLASHMODE_QOUT - //currently the SPI bus for main flash chip is initialized through GPIO matrix - } - else if (host_id == SPI2_HOST) { - ESP_LOGI(TAG, "setup flash on SPI%d (FSPI) CS0...\n", host_id + 1); - spi_bus_config_t fspi_bus_cfg = { - .mosi_io_num = FSPI_PIN_NUM_MOSI, - .miso_io_num = FSPI_PIN_NUM_MISO, - .sclk_io_num = FSPI_PIN_NUM_CLK, - .quadhd_io_num = FSPI_PIN_NUM_HD, - .quadwp_io_num = FSPI_PIN_NUM_WP, - .max_transfer_sz = 64, - }; - esp_err_t ret = spi_bus_initialize(host_id, &fspi_bus_cfg, 0); - TEST_ESP_OK(ret); - } -#if SOC_SPI_PERIPH_NUM > 2 - else if (host_id == SPI3_HOST) { - ESP_LOGI(TAG, "setup flash on SPI%d (HSPI) CS0...\n", host_id + 1); - spi_bus_config_t hspi_bus_cfg = { - .mosi_io_num = HSPI_PIN_NUM_MOSI, - .miso_io_num = HSPI_PIN_NUM_MISO, - .sclk_io_num = HSPI_PIN_NUM_CLK, - .quadhd_io_num = HSPI_PIN_NUM_HD, - .quadwp_io_num = HSPI_PIN_NUM_WP, - .max_transfer_sz = 64, - }; - esp_err_t ret = spi_bus_initialize(host_id, &hspi_bus_cfg, 0); - TEST_ESP_OK(ret); - - // HSPI have no multiline mode, use GPIO to pull those pins up - gpio_set_direction(HSPI_PIN_NUM_HD, GPIO_MODE_OUTPUT); - gpio_set_level(HSPI_PIN_NUM_HD, 1); - - gpio_set_direction(HSPI_PIN_NUM_WP, GPIO_MODE_OUTPUT); - gpio_set_level(HSPI_PIN_NUM_WP, 1); - } -#endif - else { - ESP_LOGE(TAG, "invalid bus"); - } -} -#endif // CONFIG_IDF_TARGET_ESP32 - -static void release_bus(int host_id) -{ - //SPI1 bus can't be deinitialized -#if SOC_SPI_PERIPH_NUM > 2 - if (host_id == SPI2_HOST || host_id == SPI3_HOST) -#else - if (host_id == SPI2_HOST) -#endif - { - spi_bus_free(host_id); - } -} - -static void setup_new_chip(const flashtest_config_t* test_cfg, esp_flash_t** out_chip) -{ - //the bus should be initialized before the flash is attached to the bus - if (test_cfg->host_id == -1) { - *out_chip = NULL; - return; - } - setup_bus(test_cfg->host_id); - - esp_flash_spi_device_config_t dev_cfg = { - .host_id = test_cfg->host_id, - .io_mode = test_cfg->io_mode, - .freq_mhz = test_cfg->freq_mhz, - .cs_id = test_cfg->cs_id, - .cs_io_num = test_cfg->cs_io_num, - .input_delay_ns = test_cfg->input_delay_ns, - }; - esp_flash_t* init_chip; - esp_err_t err = spi_bus_add_flash_device(&init_chip, &dev_cfg); - TEST_ESP_OK(err); - err = esp_flash_init(init_chip); - TEST_ESP_OK(err); - *out_chip = init_chip; -} - -static void teardown_test_chip(esp_flash_t* chip) -{ - spi_host_device_t host_id; - get_chip_host(chip, &host_id, NULL); - //happen to work when chip==NULL - spi_bus_remove_flash_device(chip); - release_bus(host_id); -} - -static void flash_test_core(flash_test_func_t func, const flashtest_config_t* config) -{ - esp_flash_t* chip; - setup_new_chip(config, &chip); - - uint32_t size; - esp_err_t err = esp_flash_get_size(chip, &size); - TEST_ESP_OK(err); - ESP_LOGI(TAG, "Flash size: 0x%08X", size); - - const esp_partition_t* test_part = get_test_data_partition(); - TEST_ASSERT_NOT_EQUAL(NULL, test_part->flash_chip); - - esp_partition_t part = *test_part; - part.flash_chip = chip; - - ESP_LOGI(TAG, "Testing chip %p, address 0x%08X...", part.flash_chip, part.address); - (*func)(&part); - - // For flash with size over 16MB, add one extra round of test for the 32-bit address area - if (size > MAX_ADDR_24BIT) { - part.address = 0x1030000; - part.size = 0x0010000; - ESP_LOGI(TAG, "Testing chip %p, address 0x%08X...", part.flash_chip, part.address); - (*func)(&part); - } - - teardown_test_chip(chip); -} - -static void flash_test_func(flash_test_func_t func, int test_num) -{ - esp_log_level_set("gpio", ESP_LOG_NONE); - for (int i = 0; i < test_num; i++) { - ESP_LOGI(TAG, "Testing config %d/%d", i+1, test_num); - flash_test_core(func, &config_list[i]); - } - ESP_LOGI(TAG, "Completed %d configs", test_num); -} - - -typedef struct { - uint32_t us_start; - size_t len; - const char* name; -} time_meas_ctx_t; -static void time_measure_start(time_meas_ctx_t* ctx) -{ - ctx->us_start = esp_timer_get_time(); - ccomp_timer_start(); -} - -static uint32_t time_measure_end(time_meas_ctx_t* ctx) -{ - uint32_t c_time_us = ccomp_timer_stop(); - uint32_t time_us = esp_timer_get_time() - ctx->us_start; - - ESP_LOGI(TAG, "%s: compensated: %.2lf kB/s, typical: %.2lf kB/s", ctx->name, ctx->len / (c_time_us / 1000.), ctx->len / (time_us/1000.)); - return ctx->len * 1000 / (c_time_us / 1000); -} - -#define TEST_TIMES 20 -#define TEST_SECTORS 4 - -static uint32_t measure_erase(const esp_partition_t* part) -{ - const int total_len = SPI_FLASH_SEC_SIZE * TEST_SECTORS; - time_meas_ctx_t time_ctx = {.name = "erase", .len = total_len}; - - time_measure_start(&time_ctx); - esp_err_t err = esp_flash_erase_region(part->flash_chip, part->address, total_len); - TEST_ESP_OK(err); - return time_measure_end(&time_ctx); -} - -// should called after measure_erase -static uint32_t measure_write(const char* name, const esp_partition_t* part, const uint8_t* data_to_write, int seg_len) -{ - const int total_len = SPI_FLASH_SEC_SIZE; - time_meas_ctx_t time_ctx = {.name = name, .len = total_len * TEST_TIMES}; - - time_measure_start(&time_ctx); - for (int i = 0; i < TEST_TIMES; i ++) { - // Erase one time, but write 100 times the same data - size_t len = total_len; - int offset = 0; - - while (len) { - int len_write = MIN(seg_len, len); - esp_err_t err = esp_flash_write(part->flash_chip, data_to_write + offset, part->address + offset, len_write); - TEST_ESP_OK(err); - - offset += len_write; - len -= len_write; - } - } - return time_measure_end(&time_ctx); -} - -static uint32_t measure_read(const char* name, const esp_partition_t* part, uint8_t* data_read, int seg_len) -{ - const int total_len = SPI_FLASH_SEC_SIZE; - time_meas_ctx_t time_ctx = {.name = name, .len = total_len * TEST_TIMES}; - - time_measure_start(&time_ctx); - for (int i = 0; i < TEST_TIMES; i ++) { - size_t len = total_len; - int offset = 0; - - while (len) { - int len_read = MIN(seg_len, len); - esp_err_t err = esp_flash_read(part->flash_chip, data_read + offset, part->address + offset, len_read); - TEST_ESP_OK(err); - - offset += len_read; - len -= len_read; - } - } - return time_measure_end(&time_ctx); -} - -static const char* get_chip_vendor(uint32_t id) -{ - switch (id) - { - case 0x20: - return "XMC"; - break; - case 0x68: - return "BOYA"; - break; - case 0xC8: - return "GigaDevice"; - break; - case 0x9D: - return "ISSI"; - break; - case 0xC2: - return "MXIC"; - break; - case 0xEF: - return "Winbond"; - break; - case 0xA1: - return "Fudan Micro"; - break; - default: - break; - } - return "generic"; -} - -#define MEAS_WRITE(n) (measure_write("write in "#n"-byte chunks", part, data_to_write, n)) -#define MEAS_READ(n) (measure_read("read in "#n"-byte chunks", part, data_read, n)) - -static void test_flash_read_write_performance(const esp_partition_t *part) -{ - esp_flash_t* chip = part->flash_chip; - const int total_len = SPI_FLASH_SEC_SIZE; - uint8_t *data_to_write = heap_caps_malloc(total_len, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); - uint8_t *data_read = heap_caps_malloc(total_len, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); - - srand(777); - for (int i = 0; i < total_len; i++) { - data_to_write[i] = rand(); - } - - uint32_t erase_1 = measure_erase(part); - uint32_t speed_WR_4B = MEAS_WRITE(4); - uint32_t speed_RD_4B = MEAS_READ(4); - uint32_t erase_2 = measure_erase(part); - uint32_t speed_WR_2KB = MEAS_WRITE(2048); - uint32_t speed_RD_2KB = MEAS_READ(2048); - - TEST_ASSERT_EQUAL_HEX8_ARRAY(data_to_write, data_read, total_len); - -#define LOG_DATA(bus, suffix, chip) IDF_LOG_PERFORMANCE("FLASH_SPEED_BYTE_PER_SEC_"#bus#suffix, "%d, flash_chip: %s", speed_##suffix, chip) -#define LOG_ERASE(bus, var, chip) IDF_LOG_PERFORMANCE("FLASH_SPEED_BYTE_PER_SEC_"#bus"ERASE", "%d, flash_chip: %s", var, chip) - -// Erase time may vary a lot, can increase threshold if this fails with a reasonable speed -#define LOG_PERFORMANCE(bus, chip) do {\ - LOG_DATA(bus, WR_4B, chip); \ - LOG_DATA(bus, RD_4B, chip); \ - LOG_DATA(bus, WR_2KB, chip); \ - LOG_DATA(bus, RD_2KB, chip); \ - LOG_ERASE(bus, erase_1, chip); \ - LOG_ERASE(bus, erase_2, chip); \ - } while (0) - - spi_host_device_t host_id; - int cs_id; - uint32_t id; - esp_flash_read_id(chip, &id); - const char *chip_name = get_chip_vendor(id >> 16); - - get_chip_host(chip, &host_id, &cs_id); - if (host_id != SPI1_HOST) { - // Chips on other SPI buses - LOG_PERFORMANCE(EXT_, chip_name); - } else if (cs_id == 0) { - // Main flash - LOG_PERFORMANCE(,chip_name); - } else { - // Other cs pins on SPI1 - LOG_PERFORMANCE(SPI1_, chip_name); - } - free(data_to_write); - free(data_read); -} - -#if !BYPASS_MULTIPLE_CHIP -//To make performance data stable, needs to run on special runner -TEST_CASE("Test esp_flash read/write performance", "[esp_flash][test_env=UT_T1_ESP_FLASH]") {flash_test_func(test_flash_read_write_performance, 1);} -#endif - -TEST_CASE_MULTI_FLASH("Test esp_flash read/write performance", test_flash_read_write_performance); -#endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32C6, ESP32H2) diff --git a/components/spi_flash/test/test_spiram_cache_flush.c b/components/spi_flash/test/test_spiram_cache_flush.c index 5fc89befd9..08bf0b8e50 100644 --- a/components/spi_flash/test/test_spiram_cache_flush.c +++ b/components/spi_flash/test/test_spiram_cache_flush.c @@ -18,10 +18,10 @@ This code tests the interaction between PSRAM and SPI flash routines. #include #include #include +#include "test_utils.h" #include "esp_heap_caps.h" #include "spi_flash_mmap.h" #include "esp_partition.h" -#include "test_utils.h" #include "soc/soc.h" #if CONFIG_SPIRAM @@ -96,7 +96,6 @@ TEST_CASE("Spiram cache flush on mmap", "[spiram]") TEST_ASSERT(err[1]==0); } - #define CYCLES 1024 TEST_CASE("Spiram cache flush on write/read", "[spiram]") diff --git a/components/spi_flash/test_apps/esp_flash/CMakeLists.txt b/components/spi_flash/test_apps/esp_flash/CMakeLists.txt index 2f29d7008a..b18abb0cd0 100644 --- a/components/spi_flash/test_apps/esp_flash/CMakeLists.txt +++ b/components/spi_flash/test_apps/esp_flash/CMakeLists.txt @@ -1,5 +1,8 @@ # This is the project CMakeLists.txt file for the test subproject cmake_minimum_required(VERSION 3.16) +set(EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/tools/unit-test-app/components") + include($ENV{IDF_PATH}/tools/cmake/project.cmake) + project(test_esp_flash_drv) diff --git a/components/spi_flash/test_apps/esp_flash/README.md b/components/spi_flash/test_apps/esp_flash/README.md index b5be4985c5..a8b7833fa3 100644 --- a/components/spi_flash/test_apps/esp_flash/README.md +++ b/components/spi_flash/test_apps/esp_flash/README.md @@ -1,2 +1,2 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | diff --git a/components/spi_flash/test_apps/esp_flash/main/CMakeLists.txt b/components/spi_flash/test_apps/esp_flash/main/CMakeLists.txt index 9058d7ac19..f5377211c6 100644 --- a/components/spi_flash/test_apps/esp_flash/main/CMakeLists.txt +++ b/components/spi_flash/test_apps/esp_flash/main/CMakeLists.txt @@ -1,4 +1,5 @@ set(srcs "test_app_main.c" + "test_spi_flash.c" "test_esp_flash_drv.c") # In order for the cases defined by `TEST_CASE` to be linked into the final elf, diff --git a/components/spi_flash/test_apps/esp_flash/main/idf_component.yml b/components/spi_flash/test_apps/esp_flash/main/idf_component.yml new file mode 100644 index 0000000000..2ae836a935 --- /dev/null +++ b/components/spi_flash/test_apps/esp_flash/main/idf_component.yml @@ -0,0 +1,2 @@ +dependencies: + ccomp_timer: "^1.0.0" diff --git a/components/spi_flash/test_apps/esp_flash/main/test_app_main.c b/components/spi_flash/test_apps/esp_flash/main/test_app_main.c index 01255c9084..dbe134b96a 100644 --- a/components/spi_flash/test_apps/esp_flash/main/test_app_main.c +++ b/components/spi_flash/test_apps/esp_flash/main/test_app_main.c @@ -8,8 +8,8 @@ #include "unity_test_utils.h" #include "esp_heap_caps.h" -// Some resources are lazy allocated in flash encryption, the threadhold is left for that case -#define TEST_MEMORY_LEAK_THRESHOLD (400) +// Some resources are lazy allocated in esp_flash test, especially ccomp timer test, the threshold is left for that case +#define TEST_MEMORY_LEAK_THRESHOLD (700) void setUp(void) { diff --git a/components/spi_flash/test_apps/esp_flash/main/test_esp_flash_def.h b/components/spi_flash/test_apps/esp_flash/main/test_esp_flash_def.h index f28b6f3e69..5761165ed2 100644 --- a/components/spi_flash/test_apps/esp_flash/main/test_esp_flash_def.h +++ b/components/spi_flash/test_apps/esp_flash/main/test_esp_flash_def.h @@ -126,6 +126,19 @@ typedef void (*flash_test_func_t)(const esp_partition_t *part); #define IDF_LOG_PERFORMANCE(item, value_fmt, value, ...) \ printf("[Performance][%s]: " value_fmt "\n", item, value, ##__VA_ARGS__) +#define LOG_DATA(bus, suffix, chip) IDF_LOG_PERFORMANCE("FLASH_SPEED_BYTE_PER_SEC_"#bus#suffix, "%ld, flash_chip: %s", speed_##suffix, chip) +#define LOG_ERASE(bus, var, chip) IDF_LOG_PERFORMANCE("FLASH_SPEED_BYTE_PER_SEC_"#bus"ERASE", "%ld, flash_chip: %s", var, chip) + +// Erase time may vary a lot, can increase threshold if this fails with a reasonable speed +#define LOG_PERFORMANCE(bus, chip) do {\ + LOG_DATA(bus, WR_4B, chip); \ + LOG_DATA(bus, RD_4B, chip); \ + LOG_DATA(bus, WR_2KB, chip); \ + LOG_DATA(bus, RD_2KB, chip); \ + LOG_ERASE(bus, erase_1, chip); \ + LOG_ERASE(bus, erase_2, chip); \ + } while (0) + #if defined(CONFIG_SPIRAM) //SPI1 CS1 occupied by PSRAM @@ -145,6 +158,7 @@ typedef void (*flash_test_func_t)(const esp_partition_t *part); #if BYPASS_MULTIPLE_CHIP #define TEST_CASE_MULTI_FLASH TEST_CASE_MULTI_FLASH_IGNORE +#define TEST_CASE_MULTI_FLASH_LONG TEST_CASE_MULTI_FLASH_IGNORE #else #if CONFIG_FREERTOS_SMP // IDF-5260 #define TEST_CASE_MULTI_FLASH(STR, FUNC_TO_RUN) \ diff --git a/components/spi_flash/test_apps/esp_flash/main/test_esp_flash_drv.c b/components/spi_flash/test_apps/esp_flash/main/test_esp_flash_drv.c index cf72f29859..b65ec55228 100644 --- a/components/spi_flash/test_apps/esp_flash/main/test_esp_flash_drv.c +++ b/components/spi_flash/test_apps/esp_flash/main/test_esp_flash_drv.c @@ -18,7 +18,7 @@ #include "spi_flash_mmap.h" #include #include "esp_log.h" - +#include "test_utils.h" #include "unity.h" #include "driver/gpio.h" #include "soc/io_mux_reg.h" @@ -31,6 +31,7 @@ #include "test_esp_flash_def.h" #include "spi_flash_mmap.h" #include "esp_private/spi_flash_os.h" +#include "ccomp_timer.h" #if CONFIG_IDF_TARGET_ESP32S2 #include "esp32s2/rom/cache.h" @@ -48,15 +49,6 @@ static uint8_t sector_buf[4096]; -const esp_partition_t *get_test_data_partition(void) -{ - /* This finds "flash_test" partition defined in partition_table_unit_test_app.csv */ - const esp_partition_t *result = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, - ESP_PARTITION_SUBTYPE_ANY, "flash_test"); - TEST_ASSERT_NOT_NULL(result); /* means partition table set wrong */ - return result; -} - static void get_chip_host(esp_flash_t* chip, spi_host_device_t* out_host_id, int* out_cs_id) { spi_host_device_t host_id; @@ -799,6 +791,173 @@ static void test_write_large_buffer(const esp_partition_t* part, const uint8_t * read_and_check(part, source, length); } +#if !CONFIG_SPI_FLASH_WARN_SETTING_ZERO_TO_ONE + +typedef struct { + uint32_t us_start; + size_t len; + const char* name; +} time_meas_ctx_t; +static void time_measure_start(time_meas_ctx_t* ctx) +{ + ctx->us_start = esp_timer_get_time(); + ccomp_timer_start(); +} + +static uint32_t time_measure_end(time_meas_ctx_t* ctx) +{ + uint32_t c_time_us = ccomp_timer_stop(); + uint32_t time_us = esp_timer_get_time() - ctx->us_start; + + ESP_LOGI(TAG, "%s: compensated: %.2lf kB/s, typical: %.2lf kB/s", ctx->name, ctx->len / (c_time_us / 1000.), ctx->len / (time_us/1000.)); + return ctx->len * 1000 / (c_time_us / 1000); +} + +#define TEST_TIMES 20 +#define TEST_SECTORS 4 + +static uint32_t measure_erase(const esp_partition_t* part) +{ + const int total_len = SPI_FLASH_SEC_SIZE * TEST_SECTORS; + time_meas_ctx_t time_ctx = {.name = "erase", .len = total_len}; + + time_measure_start(&time_ctx); + esp_err_t err = esp_flash_erase_region(part->flash_chip, part->address, total_len); + TEST_ESP_OK(err); + return time_measure_end(&time_ctx); +} + +// should called after measure_erase +static uint32_t measure_write(const char* name, const esp_partition_t* part, const uint8_t* data_to_write, int seg_len) +{ + const int total_len = SPI_FLASH_SEC_SIZE; + time_meas_ctx_t time_ctx = {.name = name, .len = total_len * TEST_TIMES}; + + time_measure_start(&time_ctx); + for (int i = 0; i < TEST_TIMES; i ++) { + // Erase one time, but write 100 times the same data + size_t len = total_len; + int offset = 0; + + while (len) { + int len_write = MIN(seg_len, len); + esp_err_t err = esp_flash_write(part->flash_chip, data_to_write + offset, part->address + offset, len_write); + TEST_ESP_OK(err); + + offset += len_write; + len -= len_write; + } + } + return time_measure_end(&time_ctx); +} + +static uint32_t measure_read(const char* name, const esp_partition_t* part, uint8_t* data_read, int seg_len) +{ + const int total_len = SPI_FLASH_SEC_SIZE; + time_meas_ctx_t time_ctx = {.name = name, .len = total_len * TEST_TIMES}; + + time_measure_start(&time_ctx); + for (int i = 0; i < TEST_TIMES; i ++) { + size_t len = total_len; + int offset = 0; + + while (len) { + int len_read = MIN(seg_len, len); + esp_err_t err = esp_flash_read(part->flash_chip, data_read + offset, part->address + offset, len_read); + TEST_ESP_OK(err); + + offset += len_read; + len -= len_read; + } + } + return time_measure_end(&time_ctx); +} + +static const char* get_chip_vendor(uint32_t id) +{ + switch (id) + { + case 0x20: + return "XMC"; + break; + case 0x68: + return "BOYA"; + break; + case 0xC8: + return "GigaDevice"; + break; + case 0x9D: + return "ISSI"; + break; + case 0xC2: + return "MXIC"; + break; + case 0xEF: + return "Winbond"; + break; + case 0xA1: + return "Fudan Micro"; + break; + default: + break; + } + return "generic"; +} + +#define MEAS_WRITE(n) (measure_write("write in "#n"-byte chunks", part, data_to_write, n)) +#define MEAS_READ(n) (measure_read("read in "#n"-byte chunks", part, data_read, n)) + +static void test_flash_read_write_performance(const esp_partition_t *part) +{ + esp_flash_t* chip = part->flash_chip; + const int total_len = SPI_FLASH_SEC_SIZE; + uint8_t *data_to_write = heap_caps_malloc(total_len, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); + uint8_t *data_read = heap_caps_malloc(total_len, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); + + srand(777); + for (int i = 0; i < total_len; i++) { + data_to_write[i] = rand(); + } + + uint32_t erase_1 = measure_erase(part); + uint32_t speed_WR_4B = MEAS_WRITE(4); + uint32_t speed_RD_4B = MEAS_READ(4); + uint32_t erase_2 = measure_erase(part); + uint32_t speed_WR_2KB = MEAS_WRITE(2048); + uint32_t speed_RD_2KB = MEAS_READ(2048); + + TEST_ASSERT_EQUAL_HEX8_ARRAY(data_to_write, data_read, total_len); + + spi_host_device_t host_id; + int cs_id; + uint32_t id; + esp_flash_read_id(chip, &id); + const char *chip_name = get_chip_vendor(id >> 16); + + get_chip_host(chip, &host_id, &cs_id); + if (host_id != SPI1_HOST) { + // Chips on other SPI buses + LOG_PERFORMANCE(EXT_, chip_name); + } else if (cs_id == 0) { + // Main flash + LOG_PERFORMANCE(,chip_name); + } else { + // Other cs pins on SPI1 + LOG_PERFORMANCE(SPI1_, chip_name); + } + free(data_to_write); + free(data_read); +} + +#if !BYPASS_MULTIPLE_CHIP +//To make performance data stable, needs to run on special runner +TEST_CASE("Test esp_flash read/write performance", "[esp_flash][test_env=UT_T1_ESP_FLASH]") {flash_test_func(test_flash_read_write_performance, 1);} +#endif + +TEST_CASE_MULTI_FLASH("Test esp_flash read/write performance", test_flash_read_write_performance); + +#endif + #ifdef CONFIG_SPIRAM_USE_MALLOC /* Utility: Read into a small internal RAM buffer using esp_flash_read() and compare what diff --git a/components/spi_flash/test/test_spi_flash.c b/components/spi_flash/test_apps/esp_flash/main/test_spi_flash.c similarity index 57% rename from components/spi_flash/test/test_spi_flash.c rename to components/spi_flash/test_apps/esp_flash/main/test_spi_flash.c index 5879b9b96a..9890ba37d3 100644 --- a/components/spi_flash/test/test_spi_flash.c +++ b/components/spi_flash/test_apps/esp_flash/main/test_spi_flash.c @@ -1,27 +1,30 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ #include #include #include #include #include -#include -#include -#include +#include "unity.h" +#include "spi_flash_mmap.h" +#include "esp_attr.h" #include "esp_intr_alloc.h" -#include "test_utils.h" #include "ccomp_timer.h" #include "esp_log.h" #include "esp_rom_sys.h" #include "esp_rom_spiflash.h" #include "esp_timer.h" - +#include "esp_partition.h" #include "bootloader_flash.h" //for bootloader_flash_xmc_startup - +#include "test_utils.h" #include "sdkconfig.h" +extern const esp_partition_t *get_test_data_partition(void); -#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2) -// TODO: SPI_FLASH IDF-4025 struct flash_test_ctx { uint32_t offset; bool fail; @@ -45,44 +48,44 @@ static void flash_test_task(void *arg) struct flash_test_ctx *ctx = (struct flash_test_ctx *) arg; vTaskDelay(100 / portTICK_PERIOD_MS); const uint32_t sector = start / SPI_FLASH_SEC_SIZE + ctx->offset; - printf("t%d\n", sector); - printf("es%d\n", sector); + printf("t%ld\n", sector); + printf("es%ld\n", sector); if (esp_flash_erase_region(NULL, sector * SPI_FLASH_SEC_SIZE, SPI_FLASH_SEC_SIZE) != ESP_OK) { ctx->fail = true; printf("Erase failed\r\n"); xSemaphoreGive(ctx->done); vTaskDelete(NULL); } - printf("ed%d\n", sector); + printf("ed%ld\n", sector); vTaskDelay(0 / portTICK_PERIOD_MS); uint32_t val = 0xabcd1234; for (uint32_t offset = 0; offset < SPI_FLASH_SEC_SIZE; offset += 4) { if (esp_flash_write(NULL, (const uint8_t *) &val, sector * SPI_FLASH_SEC_SIZE + offset, 4) != ESP_OK) { - printf("Write failed at offset=%d\r\n", offset); + printf("Write failed at offset=%ld\r\n", offset); ctx->fail = true; break; } } - printf("wd%d\n", sector); + printf("wd%ld\n", sector); vTaskDelay(0 / portTICK_PERIOD_MS); uint32_t val_read; for (uint32_t offset = 0; offset < SPI_FLASH_SEC_SIZE; offset += 4) { if (esp_flash_read(NULL, (uint8_t *) &val_read, sector * SPI_FLASH_SEC_SIZE + offset, 4) != ESP_OK) { - printf("Read failed at offset=%d\r\n", offset); + printf("Read failed at offset=%ld\r\n", offset); ctx->fail = true; break; } if (val_read != val) { - printf("Read invalid value=%08x at offset=%d\r\n", val_read, offset); + printf("Read invalid value=%08lx at offset=%ld\r\n", val_read, offset); ctx->fail = true; break; } } - printf("td%d\n", sector); + printf("td%ld\n", sector); xSemaphoreGive(ctx->done); vTaskDelete(NULL); } @@ -116,135 +119,6 @@ TEST_CASE("flash write and erase work both on PRO CPU and on APP CPU", "[spi_fla vSemaphoreDelete(done); } -#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S3) -// TODO ESP32-S3 IDF-2021 - -static const char TAG[] = "test_spi_flash"; - -typedef struct { - uint32_t us_start; - size_t len; - const char* name; -} time_meas_ctx_t; - -static void time_measure_start(time_meas_ctx_t* ctx) -{ - ctx->us_start = esp_timer_get_time(); - ccomp_timer_start(); -} - -static uint32_t time_measure_end(time_meas_ctx_t* ctx) -{ - uint32_t c_time_us = ccomp_timer_stop(); - uint32_t time_us = esp_timer_get_time() - ctx->us_start; - - ESP_LOGI(TAG, "%s: compensated: %.2lf kB/s, typical: %.2lf kB/s", ctx->name, ctx->len / (c_time_us/1000.), ctx->len / (time_us/1000.)); - return ctx->len * 1000 / (c_time_us / 1000); -} - -#define TEST_TIMES 20 -#define TEST_SECTORS 4 - -static uint32_t measure_erase(const esp_partition_t* part) -{ - const int total_len = SPI_FLASH_SEC_SIZE * TEST_SECTORS; - time_meas_ctx_t time_ctx = {.name = "erase", .len = total_len}; - - time_measure_start(&time_ctx); - esp_err_t err = esp_flash_erase_region(NULL, part->address, total_len); - TEST_ESP_OK(err); - return time_measure_end(&time_ctx); -} - -// should called after measure_erase -static uint32_t measure_write(const char* name, const esp_partition_t* part, const uint8_t* data_to_write, int seg_len) -{ - const int total_len = SPI_FLASH_SEC_SIZE; - time_meas_ctx_t time_ctx = {.name = name, .len = total_len * TEST_TIMES}; - - time_measure_start(&time_ctx); - for (int i = 0; i < TEST_TIMES; i ++) { - // Erase one time, but write 100 times the same data - size_t len = total_len; - int offset = 0; - - while (len) { - int len_write = MIN(seg_len, len); - esp_err_t err = esp_flash_write(NULL, data_to_write + offset, part->address + offset, len_write); - TEST_ESP_OK(err); - - offset += len_write; - len -= len_write; - } - } - return time_measure_end(&time_ctx); -} - -static uint32_t measure_read(const char* name, const esp_partition_t* part, uint8_t* data_read, int seg_len) -{ - const int total_len = SPI_FLASH_SEC_SIZE; - time_meas_ctx_t time_ctx = {.name = name, .len = total_len * TEST_TIMES}; - - time_measure_start(&time_ctx); - for (int i = 0; i < TEST_TIMES; i ++) { - size_t len = total_len; - int offset = 0; - - while (len) { - int len_read = MIN(seg_len, len); - esp_err_t err = esp_flash_read(NULL, data_read + offset, part->address + offset, len_read); - TEST_ESP_OK(err); - - offset += len_read; - len -= len_read; - } - } - return time_measure_end(&time_ctx); -} - -#define MEAS_WRITE(n) (measure_write("write in "#n"-byte chunks", part, data_to_write, n)) -#define MEAS_READ(n) (measure_read("read in "#n"-byte chunks", part, data_read, n)) - -TEST_CASE("Test spi_flash read/write performance", "[spi_flash]") -{ - const esp_partition_t *part = get_test_data_partition(); - - const int total_len = SPI_FLASH_SEC_SIZE; - uint8_t *data_to_write = heap_caps_malloc(total_len, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); - uint8_t *data_read = heap_caps_malloc(total_len, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); - - srand(777); - for (int i = 0; i < total_len; i++) { - data_to_write[i] = rand(); - } - - uint32_t erase_1 = measure_erase(part); - uint32_t speed_WR_4B = MEAS_WRITE(4); - uint32_t speed_RD_4B = MEAS_READ(4); - uint32_t erase_2 = measure_erase(part); - uint32_t speed_WR_2KB = MEAS_WRITE(2048); - uint32_t speed_RD_2KB = MEAS_READ(2048); - - TEST_ASSERT_EQUAL_HEX8_ARRAY(data_to_write, data_read, total_len); - -#define LOG_DATA(suffix) IDF_LOG_PERFORMANCE("FLASH_SPEED_BYTE_PER_SEC_LEGACY_"#suffix, "%d", speed_##suffix) -#define LOG_ERASE(var) IDF_LOG_PERFORMANCE("FLASH_SPEED_BYTE_PER_SEC_LEGACY_ERASE", "%d", var) - - LOG_DATA(WR_4B); - LOG_DATA(RD_4B); - LOG_DATA(WR_2KB); - LOG_DATA(RD_2KB); - - // Erase time may vary a lot, can increase threshold if this fails with a reasonable speed - LOG_ERASE(erase_1); - LOG_ERASE(erase_2); - - free(data_to_write); - free(data_read); -} - -#endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32S3) - // TODO: This test is disabled on S3 with legacy impl - IDF-3505 #if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32, ESP32S2, ESP32S3, ESP32C3) @@ -323,14 +197,14 @@ TEST_CASE("rom unlock will not erase QE bit", "[spi_flash]") { esp_rom_spiflash_chip_t *legacy_chip = &g_rom_flashchip; uint32_t status; - printf("dev_id: %08X \n", legacy_chip->device_id); + printf("dev_id: %08lx \n", legacy_chip->device_id); if (((legacy_chip->device_id >> 16) & 0xff) != 0x9D) { TEST_IGNORE_MESSAGE("This test is only for ISSI chips. Ignore."); } bootloader_flash_unlock(); esp_rom_spiflash_read_status(legacy_chip, &status); - printf("status: %08x\n", status); + printf("status: %08lx\n", status); TEST_ASSERT(status & 0x40); } @@ -353,5 +227,3 @@ TEST_CASE("bootloader_flash_xmc_startup can be called when cache disabled", "[sp { test_xmc_startup(); } - -#endif //#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2) diff --git a/components/spi_flash/test_apps/esp_flash/partitions.csv b/components/spi_flash/test_apps/esp_flash/partitions.csv index c941d8f4f1..9903f621fb 100644 --- a/components/spi_flash/test_apps/esp_flash/partitions.csv +++ b/components/spi_flash/test_apps/esp_flash/partitions.csv @@ -2,4 +2,4 @@ # Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap nvs, data, nvs, 0x9000, 0x6000, factory, 0, 0, 0x10000, 1M -flash_test, data, fat, , 528K +flash_test, data, fat, , 700K diff --git a/components/spi_flash/test_apps/esp_flash/pytest_esp_flash.py b/components/spi_flash/test_apps/esp_flash/pytest_esp_flash.py index 4785ffcf0a..c72d1433cd 100644 --- a/components/spi_flash/test_apps/esp_flash/pytest_esp_flash.py +++ b/components/spi_flash/test_apps/esp_flash/pytest_esp_flash.py @@ -5,11 +5,7 @@ import pytest from pytest_embedded import Dut -@pytest.mark.esp32 -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 -@pytest.mark.esp32c3 -@pytest.mark.esp32c2 +@pytest.mark.supported_targets @pytest.mark.generic @pytest.mark.parametrize( 'config', @@ -17,6 +13,7 @@ from pytest_embedded import Dut 'release', 'flash_qio', 'verify', + 'special', ], indirect=True, ) diff --git a/components/spi_flash/test_apps/esp_flash/sdkconfig.ci.special b/components/spi_flash/test_apps/esp_flash/sdkconfig.ci.special new file mode 100644 index 0000000000..586d5e00e9 --- /dev/null +++ b/components/spi_flash/test_apps/esp_flash/sdkconfig.ci.special @@ -0,0 +1,7 @@ +# This config lists merged freertos_flash no_optimization in UT all together. +CONFIG_ESP_TASK_WDT_EN=n +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" +CONFIG_ESP_SYSTEM_MEMPROT_FEATURE=n +CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH=y +CONFIG_COMPILER_OPTIMIZATION_NONE=y diff --git a/components/spi_flash/test_apps/mspi_test/CMakeLists.txt b/components/spi_flash/test_apps/mspi_test/CMakeLists.txt new file mode 100644 index 0000000000..0885202cb3 --- /dev/null +++ b/components/spi_flash/test_apps/mspi_test/CMakeLists.txt @@ -0,0 +1,5 @@ +# This is the project CMakeLists.txt file for the test subproject +cmake_minimum_required(VERSION 3.16) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(mspi_test) diff --git a/components/spi_flash/test_apps/mspi_test/README.md b/components/spi_flash/test_apps/mspi_test/README.md new file mode 100644 index 0000000000..a8b7833fa3 --- /dev/null +++ b/components/spi_flash/test_apps/mspi_test/README.md @@ -0,0 +1,2 @@ +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | diff --git a/components/spi_flash/test_apps/mspi_test/main/CMakeLists.txt b/components/spi_flash/test_apps/mspi_test/main/CMakeLists.txt new file mode 100644 index 0000000000..cfbf0f1b39 --- /dev/null +++ b/components/spi_flash/test_apps/mspi_test/main/CMakeLists.txt @@ -0,0 +1,8 @@ +set(srcs "test_cache_disabled.c" + "test_out_of_bounds_write.c" + "test_read_write.c" + "test_large_flash_writes.c" + "test_app_main.c") + +idf_component_register(SRCS ${srcs} + WHOLE_ARCHIVE) diff --git a/components/spi_flash/test_apps/mspi_test/main/idf_component.yml b/components/spi_flash/test_apps/mspi_test/main/idf_component.yml new file mode 100644 index 0000000000..2ae836a935 --- /dev/null +++ b/components/spi_flash/test_apps/mspi_test/main/idf_component.yml @@ -0,0 +1,2 @@ +dependencies: + ccomp_timer: "^1.0.0" diff --git a/components/spi_flash/test_apps/mspi_test/main/test_app_main.c b/components/spi_flash/test_apps/mspi_test/main/test_app_main.c new file mode 100644 index 0000000000..abb1c1cd7d --- /dev/null +++ b/components/spi_flash/test_apps/mspi_test/main/test_app_main.c @@ -0,0 +1,56 @@ +/* + * 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" + +// Some resources are lazy allocated in mspi bus test, the threshold is left for that case +#define TEST_MEMORY_LEAK_THRESHOLD (-600) + +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/test_cache_disabled.c b/components/spi_flash/test_apps/mspi_test/main/test_cache_disabled.c similarity index 84% rename from components/spi_flash/test/test_cache_disabled.c rename to components/spi_flash/test_apps/mspi_test/main/test_cache_disabled.c index 78a1f439a8..d7f4e236c0 100644 --- a/components/spi_flash/test/test_cache_disabled.c +++ b/components/spi_flash/test_apps/mspi_test/main/test_cache_disabled.c @@ -56,6 +56,7 @@ TEST_CASE("spi_flash_cache_enabled() works on both CPUs", "[spi_flash][esp_flash TEST_ASSERT_EQUAL(!do_disable, result); } } + vTaskDelay(10); vQueueDelete(result_queue); } @@ -67,6 +68,11 @@ TEST_CASE("spi_flash_cache_enabled() works on both CPUs", "[spi_flash][esp_flash // DRAM (e.g. size <= 8 bytes && ARCH == RISCV) static const uint32_t s_in_rodata[8] = { 0x12345678, 0xfedcba98 }; +static void reset_after_invalid_cache(void) +{ + TEST_ASSERT_EQUAL(ESP_RST_PANIC, esp_reset_reason()); +} + static void IRAM_ATTR cache_access_test_func(void* arg) { /* Assert that the array s_in_rodata is in DROM. If not, this test is @@ -79,7 +85,7 @@ static void IRAM_ATTR cache_access_test_func(void* arg) uint32_t v2 = src[1]; bool cache_enabled = spi_flash_cache_enabled(); spi_flash_enable_interrupts_caches_and_other_cpu(); - printf("%d %x %x\n", cache_enabled, v1, v2); + printf("%d %lx %lx\n", cache_enabled, v1, v2); vTaskDelete(NULL); } @@ -93,21 +99,26 @@ 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. -TEST_CASE("invalid access to cache raises panic (PRO CPU)", "[spi_flash][reset="CACHE_ERROR_REASON"]") +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); } +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); + #ifndef CONFIG_FREERTOS_UNICORE -TEST_CASE("invalid access to cache raises panic (APP CPU)", "[spi_flash][reset="CACHE_ERROR_REASON"]") +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); } +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); + #endif // !CONFIG_FREERTOS_UNICORE #endif // !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2) diff --git a/components/spi_flash/test/test_large_flash_writes.c b/components/spi_flash/test_apps/mspi_test/main/test_large_flash_writes.c similarity index 84% rename from components/spi_flash/test/test_large_flash_writes.c rename to components/spi_flash/test_apps/mspi_test/main/test_large_flash_writes.c index cf8ac083b6..a23438e9ec 100644 --- a/components/spi_flash/test/test_large_flash_writes.c +++ b/components/spi_flash/test_apps/mspi_test/main/test_large_flash_writes.c @@ -13,14 +13,14 @@ #include #include -#include -#include -#include -#include +#include "unity.h" +#include "spi_flash_mmap.h" +#include "esp_log.h" #include "esp_rom_spiflash.h" #include "esp_private/cache_utils.h" #include "soc/timer_periph.h" #include "esp_flash.h" +#include "esp_partition.h" static const uint8_t large_const_buffer[16400] = { 203, // first byte @@ -35,6 +35,15 @@ static const uint8_t large_const_buffer[16400] = { static void test_write_large_buffer(const uint8_t *source, size_t length); +const esp_partition_t *get_test_data_partition(void) +{ + /* This finds "flash_test" partition defined in partition_table_unit_test_app.csv */ + const esp_partition_t *result = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, + ESP_PARTITION_SUBTYPE_ANY, "flash_test"); + TEST_ASSERT_NOT_NULL(result); /* means partition table set wrong */ + return result; +} + TEST_CASE("Test flash write large const buffer", "[spi_flash][esp_flash]") { // buffer in flash diff --git a/components/spi_flash/test/test_out_of_bounds_write.c b/components/spi_flash/test_apps/mspi_test/main/test_out_of_bounds_write.c similarity index 90% rename from components/spi_flash/test/test_out_of_bounds_write.c rename to components/spi_flash/test_apps/mspi_test/main/test_out_of_bounds_write.c index 10391bc002..d48a4b23f0 100644 --- a/components/spi_flash/test/test_out_of_bounds_write.c +++ b/components/spi_flash/test_apps/mspi_test/main/test_out_of_bounds_write.c @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ #include #include "unity.h" diff --git a/components/spi_flash/test/test_read_write.c b/components/spi_flash/test_apps/mspi_test/main/test_read_write.c similarity index 97% rename from components/spi_flash/test/test_read_write.c rename to components/spi_flash/test_apps/mspi_test/main/test_read_write.c index d7cd12c2c7..198ad4ec6e 100644 --- a/components/spi_flash/test/test_read_write.c +++ b/components/spi_flash/test_apps/mspi_test/main/test_read_write.c @@ -12,23 +12,22 @@ #include #include -#include -#include -#include +#include "unity.h" +#include "spi_flash_mmap.h" #include "esp_private/cache_utils.h" #include "soc/timer_periph.h" #include "esp_attr.h" #include "esp_heap_caps.h" #include "esp_rom_spiflash.h" #include "esp_flash.h" +#include "esp_partition.h" #if CONFIG_IDF_TARGET_ESP32 // Used for rom_fix function #include "esp32/rom/spi_flash.h" #endif -#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2) -// TODO: SPI_FLASH IDF-4025 +extern const esp_partition_t *get_test_data_partition(void); #define MIN_BLOCK_SIZE 12 /* Base offset in flash for tests. */ @@ -144,7 +143,7 @@ TEST_CASE("Test spi_flash_read", "[spi_flash][esp_flash]") extern void spi_common_set_dummy_output(esp_rom_spiflash_read_mode_t mode); extern void spi_dummy_len_fix(uint8_t spi, uint8_t freqdiv); -#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C6, ESP32H2) + static void IRAM_ATTR fix_rom_func(void) { uint32_t freqdiv = 0; @@ -281,7 +280,7 @@ TEST_CASE("Test esp_flash_write", "[spi_flash][esp_flash]") * NB: At the moment these only support aligned addresses, because memcpy * is not aware of the 32-but load requirements for these regions. */ -#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32C3 +#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C6 #define TEST_SOC_IROM_ADDR (SOC_IROM_LOW) #define TEST_SOC_CACHE_RAM_BANK0_ADDR (SOC_IRAM_LOW) #define TEST_SOC_CACHE_RAM_BANK1_ADDR (SOC_IRAM_LOW + 0x2000) @@ -305,7 +304,6 @@ TEST_CASE("Test esp_flash_write", "[spi_flash][esp_flash]") ESP_ERROR_CHECK(esp_flash_write(NULL, (char *) 0x40080000, start, 16)); #endif } -#endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32C6, ESP32H2) #ifdef CONFIG_SPIRAM @@ -386,5 +384,3 @@ TEST_CASE("spi_flash_read less than 16 bytes into buffer in external RAM", "[spi } #endif // CONFIG_SPIRAM - -#endif // #if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2) diff --git a/components/spi_flash/test_apps/mspi_test/partitions.csv b/components/spi_flash/test_apps/mspi_test/partitions.csv new file mode 100644 index 0000000000..c941d8f4f1 --- /dev/null +++ b/components/spi_flash/test_apps/mspi_test/partitions.csv @@ -0,0 +1,5 @@ +# 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, 0x9000, 0x6000, +factory, 0, 0, 0x10000, 1M +flash_test, data, fat, , 528K diff --git a/components/spi_flash/test_apps/mspi_test/pytest_mspi_test.py b/components/spi_flash/test_apps/mspi_test/pytest_mspi_test.py new file mode 100644 index 0000000000..bf4539c4e3 --- /dev/null +++ b/components/spi_flash/test_apps/mspi_test/pytest_mspi_test.py @@ -0,0 +1,54 @@ +# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: Apache-2.0 + +import pytest +from pytest_embedded import Dut + + +@pytest.mark.esp32 +@pytest.mark.esp32s2 +@pytest.mark.esp32s3 +@pytest.mark.esp32c3 +@pytest.mark.esp32c2 +@pytest.mark.esp32c6 +@pytest.mark.esp32h2 +@pytest.mark.generic +@pytest.mark.parametrize( + 'config', + [ + 'release', + 'special', + ], + indirect=True, +) +def test_mspi_bus(dut: Dut) -> None: + dut.run_all_single_board_cases() + + +@pytest.mark.esp32s2 +@pytest.mark.esp32s3 +@pytest.mark.generic +@pytest.mark.parametrize( + 'config', + [ + 'xip_psram', + ], + indirect=True, +) +def test_mspi_bus_xip_psram(dut: Dut) -> None: + dut.run_all_single_board_cases() + + +@pytest.mark.esp32 +@pytest.mark.esp32s2 +@pytest.mark.esp32s3 +@pytest.mark.generic +@pytest.mark.parametrize( + 'config', + [ + 'psram', + ], + indirect=True, +) +def test_mspi_bus_psram(dut: Dut) -> None: + dut.run_all_single_board_cases() diff --git a/components/spi_flash/test_apps/mspi_test/sdkconfig.ci.psram b/components/spi_flash/test_apps/mspi_test/sdkconfig.ci.psram new file mode 100644 index 0000000000..9e7d22c081 --- /dev/null +++ b/components/spi_flash/test_apps/mspi_test/sdkconfig.ci.psram @@ -0,0 +1,11 @@ +CONFIG_FREERTOS_USE_TICKLESS_IDLE=y +CONFIG_COMPILER_OPTIMIZATION_SIZE=y +CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y +CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y +CONFIG_SPI_FLASH_ENABLE_COUNTERS=y +CONFIG_SPIRAM=y +CONFIG_SPIRAM_USE_CAPS_ALLOC=y +CONFIG_SPIRAM_FETCH_INSTRUCTIONS=y +CONFIG_SPIRAM_RODATA=y +CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY=y +CONFIG_ESP_SYSTEM_MEMPROT_FEATURE=n diff --git a/components/spi_flash/test_apps/mspi_test/sdkconfig.ci.release b/components/spi_flash/test_apps/mspi_test/sdkconfig.ci.release new file mode 100644 index 0000000000..460efd773a --- /dev/null +++ b/components/spi_flash/test_apps/mspi_test/sdkconfig.ci.release @@ -0,0 +1,6 @@ +CONFIG_FREERTOS_USE_TICKLESS_IDLE=y +CONFIG_COMPILER_OPTIMIZATION_SIZE=y +CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y +CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y +CONFIG_SPI_FLASH_ENABLE_COUNTERS=y +CONFIG_ESP_SYSTEM_MEMPROT_FEATURE=n diff --git a/components/spi_flash/test_apps/mspi_test/sdkconfig.ci.special b/components/spi_flash/test_apps/mspi_test/sdkconfig.ci.special new file mode 100644 index 0000000000..90fc924cde --- /dev/null +++ b/components/spi_flash/test_apps/mspi_test/sdkconfig.ci.special @@ -0,0 +1,4 @@ +# This config lists merged freertos_flash no_optimization in UT all together. +CONFIG_ESP_SYSTEM_MEMPROT_FEATURE=n +CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH=y +CONFIG_COMPILER_OPTIMIZATION_NONE=y diff --git a/components/spi_flash/test_apps/mspi_test/sdkconfig.ci.xip_psram b/components/spi_flash/test_apps/mspi_test/sdkconfig.ci.xip_psram new file mode 100644 index 0000000000..e69de29bb2 diff --git a/components/spi_flash/test_apps/mspi_test/sdkconfig.defaults b/components/spi_flash/test_apps/mspi_test/sdkconfig.defaults new file mode 100644 index 0000000000..c35370d656 --- /dev/null +++ b/components/spi_flash/test_apps/mspi_test/sdkconfig.defaults @@ -0,0 +1,4 @@ +CONFIG_ESP_TASK_WDT_EN=n +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" +CONFIG_ESP_SYSTEM_MEMPROT_FEATURE=n diff --git a/tools/unit-test-app/configs/freertos_compliance b/tools/unit-test-app/configs/freertos_compliance deleted file mode 100644 index 183e3cff87..0000000000 --- a/tools/unit-test-app/configs/freertos_compliance +++ /dev/null @@ -1,4 +0,0 @@ -# This config is split between targets since different component needs to be included (esp32, esp32s2) -CONFIG_IDF_TARGET="esp32" -TEST_COMPONENTS=spi_flash -CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE=y diff --git a/tools/unit-test-app/configs/freertos_compliance_c2 b/tools/unit-test-app/configs/freertos_compliance_c2 deleted file mode 100644 index 93fd6c168e..0000000000 --- a/tools/unit-test-app/configs/freertos_compliance_c2 +++ /dev/null @@ -1,4 +0,0 @@ -# This config is split between targets since different component needs to be included (esp32, esp32s2) -CONFIG_IDF_TARGET="esp32c2" -TEST_COMPONENTS=spi_flash -CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE=y diff --git a/tools/unit-test-app/configs/freertos_compliance_c3 b/tools/unit-test-app/configs/freertos_compliance_c3 deleted file mode 100644 index 6754a77bbb..0000000000 --- a/tools/unit-test-app/configs/freertos_compliance_c3 +++ /dev/null @@ -1,4 +0,0 @@ -# This config is split between targets since different component needs to be included (esp32, esp32s2) -CONFIG_IDF_TARGET="esp32c3" -TEST_COMPONENTS=spi_flash -CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE=y diff --git a/tools/unit-test-app/configs/freertos_compliance_c6 b/tools/unit-test-app/configs/freertos_compliance_c6 deleted file mode 100644 index 8f060121bb..0000000000 --- a/tools/unit-test-app/configs/freertos_compliance_c6 +++ /dev/null @@ -1,4 +0,0 @@ -# This config is split between targets since different component needs to be included -CONFIG_IDF_TARGET="esp32c6" -TEST_COMPONENTS=spi_flash -CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE=y diff --git a/tools/unit-test-app/configs/freertos_compliance_h2 b/tools/unit-test-app/configs/freertos_compliance_h2 deleted file mode 100644 index 31558f5d50..0000000000 --- a/tools/unit-test-app/configs/freertos_compliance_h2 +++ /dev/null @@ -1,4 +0,0 @@ -# This config is split between targets since different component needs to be included -CONFIG_IDF_TARGET="esp32h2" -TEST_COMPONENTS=spi_flash -CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE=y diff --git a/tools/unit-test-app/configs/freertos_compliance_s2 b/tools/unit-test-app/configs/freertos_compliance_s2 deleted file mode 100644 index b81e1282e3..0000000000 --- a/tools/unit-test-app/configs/freertos_compliance_s2 +++ /dev/null @@ -1,4 +0,0 @@ -# This config is split between targets since different component needs to be included (esp32, esp32s2) -CONFIG_IDF_TARGET="esp32s2" -TEST_COMPONENTS=spi_flash -CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE=y diff --git a/tools/unit-test-app/configs/freertos_flash b/tools/unit-test-app/configs/freertos_flash deleted file mode 100644 index d3d312b5f0..0000000000 --- a/tools/unit-test-app/configs/freertos_flash +++ /dev/null @@ -1,2 +0,0 @@ -TEST_COMPONENTS=spi_flash -CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH=y diff --git a/tools/unit-test-app/configs/no_optimization_c2 b/tools/unit-test-app/configs/no_optimization_c2 deleted file mode 100644 index 567ec11d78..0000000000 --- a/tools/unit-test-app/configs/no_optimization_c2 +++ /dev/null @@ -1,3 +0,0 @@ -CONFIG_IDF_TARGET="esp32c2" -TEST_COMPONENTS=spi_flash -CONFIG_COMPILER_OPTIMIZATION_NONE=y diff --git a/tools/unit-test-app/configs/no_optimization_c3 b/tools/unit-test-app/configs/no_optimization_c3 deleted file mode 100644 index 462b888eb7..0000000000 --- a/tools/unit-test-app/configs/no_optimization_c3 +++ /dev/null @@ -1,3 +0,0 @@ -CONFIG_IDF_TARGET="esp32c3" -TEST_COMPONENTS=spi_flash -CONFIG_COMPILER_OPTIMIZATION_NONE=y diff --git a/tools/unit-test-app/configs/no_optimization_c6 b/tools/unit-test-app/configs/no_optimization_c6 deleted file mode 100644 index f00f0a8444..0000000000 --- a/tools/unit-test-app/configs/no_optimization_c6 +++ /dev/null @@ -1,3 +0,0 @@ -CONFIG_IDF_TARGET="esp32c6" -TEST_COMPONENTS=spi_flash -CONFIG_COMPILER_OPTIMIZATION_NONE=y diff --git a/tools/unit-test-app/configs/no_optimization_esp32 b/tools/unit-test-app/configs/no_optimization_esp32 deleted file mode 100644 index 79280971d3..0000000000 --- a/tools/unit-test-app/configs/no_optimization_esp32 +++ /dev/null @@ -1,3 +0,0 @@ -CONFIG_IDF_TARGET="esp32" -TEST_COMPONENTS=spi_flash -CONFIG_COMPILER_OPTIMIZATION_NONE=y diff --git a/tools/unit-test-app/configs/no_optimization_h2 b/tools/unit-test-app/configs/no_optimization_h2 deleted file mode 100644 index a705e0cca2..0000000000 --- a/tools/unit-test-app/configs/no_optimization_h2 +++ /dev/null @@ -1,3 +0,0 @@ -CONFIG_IDF_TARGET="esp32h2" -TEST_COMPONENTS=spi_flash -CONFIG_COMPILER_OPTIMIZATION_NONE=y diff --git a/tools/unit-test-app/configs/rom_options_c2 b/tools/unit-test-app/configs/rom_options_c2 deleted file mode 100644 index 6f1d16870c..0000000000 --- a/tools/unit-test-app/configs/rom_options_c2 +++ /dev/null @@ -1,3 +0,0 @@ -CONFIG_IDF_TARGET="esp32c2" -TEST_COMPONENTS=spi_flash -CONFIG_SPI_FLASH_ROM_IMPL=y diff --git a/tools/unit-test-app/configs/rom_options_c3 b/tools/unit-test-app/configs/rom_options_c3 deleted file mode 100644 index f31ad9b6bf..0000000000 --- a/tools/unit-test-app/configs/rom_options_c3 +++ /dev/null @@ -1,3 +0,0 @@ -CONFIG_IDF_TARGET="esp32c3" -TEST_COMPONENTS=spi_flash -CONFIG_SPI_FLASH_ROM_IMPL=y diff --git a/tools/unit-test-app/configs/rom_options_c6 b/tools/unit-test-app/configs/rom_options_c6 deleted file mode 100644 index 1f0439f02a..0000000000 --- a/tools/unit-test-app/configs/rom_options_c6 +++ /dev/null @@ -1,3 +0,0 @@ -CONFIG_IDF_TARGET="esp32c6" -TEST_COMPONENTS=spi_flash -CONFIG_SPI_FLASH_ROM_IMPL=y diff --git a/tools/unit-test-app/configs/rom_options_h2 b/tools/unit-test-app/configs/rom_options_h2 deleted file mode 100644 index c2e3834787..0000000000 --- a/tools/unit-test-app/configs/rom_options_h2 +++ /dev/null @@ -1,3 +0,0 @@ -CONFIG_IDF_TARGET="esp32h2" -TEST_COMPONENTS=spi_flash -CONFIG_SPI_FLASH_ROM_IMPL=y diff --git a/tools/unit-test-app/configs/rom_options_s3 b/tools/unit-test-app/configs/rom_options_s3 deleted file mode 100644 index db50985f39..0000000000 --- a/tools/unit-test-app/configs/rom_options_s3 +++ /dev/null @@ -1,3 +0,0 @@ -CONFIG_IDF_TARGET="esp32s3" -TEST_COMPONENTS=spi_flash -CONFIG_SPI_FLASH_ROM_IMPL=y diff --git a/tools/unit-test-app/configs/spi_flash_config_1_s2 b/tools/unit-test-app/configs/spi_flash_config_1_s2 deleted file mode 100644 index 2cd5632dd5..0000000000 --- a/tools/unit-test-app/configs/spi_flash_config_1_s2 +++ /dev/null @@ -1,5 +0,0 @@ -TEST_COMPONENTS=spi_flash -CONFIG_SPIRAM=y -CONFIG_SPIRAM_FETCH_INSTRUCTIONS=y -CONFIG_SPIRAM_RODATA=n -CONFIG_IDF_TARGET="esp32s2" diff --git a/tools/unit-test-app/configs/spi_flash_config_2_s2 b/tools/unit-test-app/configs/spi_flash_config_2_s2 deleted file mode 100644 index 2c0d0af3b4..0000000000 --- a/tools/unit-test-app/configs/spi_flash_config_2_s2 +++ /dev/null @@ -1,6 +0,0 @@ -TEST_COMPONENTS=spi_flash -CONFIG_SPIRAM=y -CONFIG_SPIRAM_FETCH_INSTRUCTIONS=y -CONFIG_SPIRAM_RODATA=n -CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY=y -CONFIG_IDF_TARGET="esp32s2" diff --git a/tools/unit-test-app/configs/spi_flash_config_3_s2 b/tools/unit-test-app/configs/spi_flash_config_3_s2 deleted file mode 100644 index 2fb4a33d5a..0000000000 --- a/tools/unit-test-app/configs/spi_flash_config_3_s2 +++ /dev/null @@ -1,6 +0,0 @@ -TEST_COMPONENTS=spi_flash -CONFIG_SPIRAM=y -CONFIG_SPIRAM_FETCH_INSTRUCTIONS=n -CONFIG_SPIRAM_RODATA=y -CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY=y -CONFIG_IDF_TARGET="esp32s2" diff --git a/tools/unit-test-app/configs/spi_flash_config_4_s2 b/tools/unit-test-app/configs/spi_flash_config_4_s2 deleted file mode 100644 index 75dd41d2f5..0000000000 --- a/tools/unit-test-app/configs/spi_flash_config_4_s2 +++ /dev/null @@ -1,6 +0,0 @@ -TEST_COMPONENTS=spi_flash -CONFIG_SPIRAM=y -CONFIG_SPIRAM_FETCH_INSTRUCTIONS=y -CONFIG_SPIRAM_RODATA=y -CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY=y -CONFIG_IDF_TARGET="esp32s2" diff --git a/tools/unit-test-app/configs/spi_flash_config_s3 b/tools/unit-test-app/configs/spi_flash_config_s3 deleted file mode 100644 index e3710e87a8..0000000000 --- a/tools/unit-test-app/configs/spi_flash_config_s3 +++ /dev/null @@ -1,5 +0,0 @@ -TEST_COMPONENTS=spi_flash -CONFIG_SPIRAM=y -CONFIG_SPIRAM_FETCH_INSTRUCTIONS=y -CONFIG_SPIRAM_RODATA=y -CONFIG_IDF_TARGET="esp32s3" diff --git a/tools/unit-test-app/configs/spi_flash_qio b/tools/unit-test-app/configs/spi_flash_qio deleted file mode 100644 index 106bae7d66..0000000000 --- a/tools/unit-test-app/configs/spi_flash_qio +++ /dev/null @@ -1,2 +0,0 @@ -TEST_COMPONENTS=spi_flash -CONFIG_ESPTOOLPY_FLASHMODE_QIO=y diff --git a/tools/unit-test-app/configs/spi_flash_suspend b/tools/unit-test-app/configs/spi_flash_suspend deleted file mode 100644 index c021dcbfa5..0000000000 --- a/tools/unit-test-app/configs/spi_flash_suspend +++ /dev/null @@ -1,3 +0,0 @@ -CONFIG_IDF_TARGET="esp32c3" -TEST_COMPONENTS=spi_flash -CONFIG_SPI_FLASH_AUTO_SUSPEND=y