diff --git a/.gitlab/ci/target-test.yml b/.gitlab/ci/target-test.yml index 31a5e200c7..94c0916b45 100644 --- a/.gitlab/ci/target-test.yml +++ b/.gitlab/ci/target-test.yml @@ -476,6 +476,38 @@ component_ut_pytest_esp32c3_flash_multi: - build_pytest_components_esp32c3 tags: [ esp32c3, flash_mutli ] +component_ut_pytest_esp32_sdmmc: + extends: + - .pytest_components_dir_template + - .rules:test:component_ut-esp32 + needs: + - build_pytest_components_esp32 + tags: [ esp32, sdcard_sdmode ] + +component_ut_pytest_esp32_sdspi: + extends: + - .pytest_components_dir_template + - .rules:test:component_ut-esp32 + needs: + - build_pytest_components_esp32 + tags: [ esp32, sdcard_spimode ] + +component_ut_pytest_esp32s2_sdspi: + extends: + - .pytest_components_dir_template + - .rules:test:component_ut-esp32s2 + needs: + - build_pytest_components_esp32s2 + tags: [ esp32s2, sdcard_spimode ] + +component_ut_pytest_esp32c3_sdspi: + extends: + - .pytest_components_dir_template + - .rules:test:component_ut-esp32c3 + needs: + - build_pytest_components_esp32c3 + tags: [ esp32c3, sdcard_spimode ] + example_test_pytest_openthread_br: extends: - .pytest_examples_dir_template diff --git a/components/fatfs/.build-test-rules.yml b/components/fatfs/.build-test-rules.yml new file mode 100644 index 0000000000..c879f1132b --- /dev/null +++ b/components/fatfs/.build-test-rules.yml @@ -0,0 +1,7 @@ +# Documentation: .gitlab/ci/README.md#manifest-file-to-control-the-buildtest-apps + +components/fatfs/test_apps/sdcard: + disable_test: + - if: IDF_TARGET in ["esp32s3", "esp32c2"] + temporary: true + reason: No sdspi runners for these targets diff --git a/components/fatfs/test/CMakeLists.txt b/components/fatfs/test/CMakeLists.txt deleted file mode 100644 index 518f57c83a..0000000000 --- a/components/fatfs/test/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -idf_component_register(SRC_DIRS . - PRIV_INCLUDE_DIRS . - PRIV_REQUIRES cmock test_utils vfs fatfs - EMBED_TXTFILES fatfs.img - ) -target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format") diff --git a/components/fatfs/test/fatfs.img b/components/fatfs/test/fatfs.img deleted file mode 100644 index d602cc782c..0000000000 Binary files a/components/fatfs/test/fatfs.img and /dev/null differ diff --git a/components/fatfs/test_apps/flash_ro/CMakeLists.txt b/components/fatfs/test_apps/flash_ro/CMakeLists.txt new file mode 100644 index 0000000000..9a1f08ef13 --- /dev/null +++ b/components/fatfs/test_apps/flash_ro/CMakeLists.txt @@ -0,0 +1,8 @@ +cmake_minimum_required(VERSION 3.16) + +set(COMPONENTS main) +set(EXTRA_COMPONENT_DIRS "${CMAKE_CURRENT_LIST_DIR}/../test_fatfs_common") + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) + +project(test_fatfs_flash_ro) diff --git a/components/fatfs/test_apps/flash_ro/README.md b/components/fatfs/test_apps/flash_ro/README.md new file mode 100644 index 0000000000..dd48f82c4d --- /dev/null +++ b/components/fatfs/test_apps/flash_ro/README.md @@ -0,0 +1,14 @@ +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | + +This test app runs a few FATFS test cases in a read-only FAT partition. + +These tests should be possible to run on any ESP development board, not extra hardware is necessary. + +The initial FAT image is generated during the build process in [main/CMakeLists.txt](main/CMakeLists.txt): +- `create_test_files` function creates a set of files expected by the test cases +- `fatfs_create_rawflash_image` generates a FAT image from the set of files (via `fatfsgen.py`) + +The generated FAT image is flashed into `storage` partition when running `idf.py flash`. + +See [../README.md](../README.md) for more information about FATFS test apps. diff --git a/components/fatfs/test_apps/flash_ro/main/CMakeLists.txt b/components/fatfs/test_apps/flash_ro/main/CMakeLists.txt new file mode 100644 index 0000000000..87329220aa --- /dev/null +++ b/components/fatfs/test_apps/flash_ro/main/CMakeLists.txt @@ -0,0 +1,41 @@ +idf_component_register(SRCS "test_fatfs_flash_ro.c" + INCLUDE_DIRS "." + PRIV_REQUIRES unity spi_flash fatfs vfs test_fatfs_common + WHOLE_ARCHIVE) + + +set(out_dir "${CMAKE_CURRENT_BINARY_DIR}/fatfs_image") + +# This helper function creates a set of files expected by the test case. +# The files are then added into the FAT image by 'fatfs_create_rawflash_image' below. +function(create_test_files) + message(STATUS "Generating source files for test_fatfs_flash_ro in ${out_dir}...") + + # used in "(raw) can read file" + file(WRITE "${out_dir}/hello.txt" "Hello, World!\n") + + # used in "(raw) can open maximum number of files" + foreach(i RANGE 1 32) + file(WRITE "${out_dir}/f/${i}.txt") + endforeach() + + # used in "(raw) opendir, readdir, rewinddir, seekdir work as expected" + file(WRITE "${out_dir}/dir/1.txt") + file(WRITE "${out_dir}/dir/2.txt") + file(WRITE "${out_dir}/dir/boo.bin") + file(WRITE "${out_dir}/dir/inner/3.txt") + + # used in "(raw) multiple tasks can use same volume" + foreach(i RANGE 1 4) + string(REPEAT "${i}" 32000 file_content) + file(WRITE "${out_dir}/ccrnt/${i}.txt" ${file_content}) + endforeach() + + # used in "(raw) read speed test" + string(REPEAT "a" 262144 file_content) + file(WRITE "${out_dir}/256k.bin" ${file_content}) +endfunction() + +create_test_files() + +fatfs_create_rawflash_image(storage ${out_dir} FLASH_IN_PROJECT PRESERVE_TIME) diff --git a/components/fatfs/test/test_fatfs_rawflash.c b/components/fatfs/test_apps/flash_ro/main/test_fatfs_flash_ro.c similarity index 78% rename from components/fatfs/test/test_fatfs_rawflash.c rename to components/fatfs/test_apps/flash_ro/main/test_fatfs_flash_ro.c index efb7437198..61786bfe97 100644 --- a/components/fatfs/test/test_fatfs_rawflash.c +++ b/components/fatfs/test_apps/flash_ro/main/test_fatfs_flash_ro.c @@ -11,53 +11,30 @@ #include #include #include "unity.h" -#include "test_utils.h" -#include "esp_log.h" -#include "esp_system.h" #include "esp_vfs.h" #include "esp_vfs_fat.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "test_fatfs_common.h" -#include "esp_partition.h" -#include "ff.h" -#include "esp_rom_sys.h" -#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2) -//IDF-5136 +void app_main(void) +{ + unity_run_menu(); +} + static void test_setup(size_t max_files) { - extern const char fatfs_start[] asm("_binary_fatfs_img_start"); - extern const char fatfs_end[] asm("_binary_fatfs_img_end"); esp_vfs_fat_sdmmc_mount_config_t mount_config = { .format_if_mount_failed = false, .max_files = max_files }; - const esp_partition_t* part = get_test_data_partition(); - - TEST_ASSERT(part->size == (fatfs_end - fatfs_start - 1)); - - spi_flash_mmap_handle_t mmap_handle; - const void* mmap_ptr; - TEST_ESP_OK(esp_partition_mmap(part, 0, part->size, SPI_FLASH_MMAP_DATA, &mmap_ptr, &mmap_handle)); - bool content_valid = memcmp(fatfs_start, mmap_ptr, part->size) == 0; - spi_flash_munmap(mmap_handle); - - if (!content_valid) { - printf("Copying fatfs.img into test partition...\n"); - esp_partition_erase_range(part, 0, part->size); - for (int i = 0; i < part->size; i+= SPI_FLASH_SEC_SIZE) { - ESP_ERROR_CHECK( esp_partition_write(part, i, fatfs_start + i, SPI_FLASH_SEC_SIZE) ); - } - } - - TEST_ESP_OK(esp_vfs_fat_spiflash_mount_ro("/spiflash", "flash_test", &mount_config)); + TEST_ESP_OK(esp_vfs_fat_spiflash_mount_ro("/spiflash", "storage", &mount_config)); } static void test_teardown(void) { - TEST_ESP_OK(esp_vfs_fat_spiflash_unmount_ro("/spiflash","flash_test")); + TEST_ESP_OK(esp_vfs_fat_spiflash_unmount_ro("/spiflash", "storage")); } TEST_CASE("(raw) can read file", "[fatfs]") @@ -94,7 +71,6 @@ TEST_CASE("(raw) can open maximum number of files", "[fatfs]") } - TEST_CASE("(raw) can lseek", "[fatfs]") { test_setup(5); @@ -129,7 +105,7 @@ TEST_CASE("(raw) stat returns correct values", "[fatfs]") printf("Reference time: %s", asctime(&tm)); struct stat st; - TEST_ASSERT_EQUAL(0, stat("/spiflash/stat.txt", &st)); + TEST_ASSERT_EQUAL(0, stat("/spiflash/hello.txt", &st)); time_t mtime = st.st_mtime; struct tm mtm; @@ -148,8 +124,6 @@ TEST_CASE("(raw) stat returns correct values", "[fatfs]") test_teardown(); } - - TEST_CASE("(raw) can opendir root directory of FS", "[fatfs]") { test_setup(5); @@ -161,7 +135,7 @@ TEST_CASE("(raw) can opendir root directory of FS", "[fatfs]") if (!de) { break; } - if (strcasecmp(de->d_name, "test_opd.txt") == 0) { + if (strcasecmp(de->d_name, "hello.txt") == 0) { found = true; break; } @@ -171,6 +145,7 @@ TEST_CASE("(raw) can opendir root directory of FS", "[fatfs]") test_teardown(); } + TEST_CASE("(raw) opendir, readdir, rewinddir, seekdir work as expected", "[fatfs]") { test_setup(5); @@ -229,20 +204,17 @@ TEST_CASE("(raw) opendir, readdir, rewinddir, seekdir work as expected", "[fatfs test_teardown(); } - typedef struct { const char* filename; size_t word_count; - int seed; - int val; + unsigned val; SemaphoreHandle_t done; - int result; + esp_err_t result; } read_test_arg_t; -#define READ_TEST_ARG_INIT(name, seed_, val_) \ +#define READ_TEST_ARG_INIT(name, val_) \ { \ .filename = name, \ - .seed = seed_, \ .word_count = 8000, \ .val = val_, \ .done = xSemaphoreCreateBinary() \ @@ -257,12 +229,11 @@ static void read_task(void* param) goto done; } - srand(args->seed); for (size_t i = 0; i < args->word_count; ++i) { - uint32_t rval; + unsigned rval; int cnt = fread(&rval, sizeof(rval), 1, f); if (cnt != 1 || rval != args->val) { - esp_rom_printf("E(r): i=%d, cnt=%d rval=%d val=%d\n\n", i, cnt, rval, args->val); + printf("E(r): i=%d, cnt=%d rval=0x08%x val=0x%08x\n", i, cnt, rval, args->val); args->result = ESP_FAIL; goto close; } @@ -278,7 +249,6 @@ done: vTaskDelete(NULL); } - TEST_CASE("(raw) multiple tasks can use same volume", "[fatfs]") { test_setup(5); @@ -287,10 +257,10 @@ TEST_CASE("(raw) multiple tasks can use same volume", "[fatfs]") snprintf(names[i], sizeof(names[i]), "/spiflash/ccrnt/%d.txt", i + 1); } - read_test_arg_t args1 = READ_TEST_ARG_INIT(names[0], 1, 0x31313131); - read_test_arg_t args2 = READ_TEST_ARG_INIT(names[1], 2, 0x32323232); - read_test_arg_t args3 = READ_TEST_ARG_INIT(names[2], 3, 0x33333333); - read_test_arg_t args4 = READ_TEST_ARG_INIT(names[3], 4, 0x34343434); + read_test_arg_t args1 = READ_TEST_ARG_INIT(names[0], 0x31313131); + read_test_arg_t args2 = READ_TEST_ARG_INIT(names[1], 0x32323232); + read_test_arg_t args3 = READ_TEST_ARG_INIT(names[2], 0x33333333); + read_test_arg_t args4 = READ_TEST_ARG_INIT(names[3], 0x34343434); const int cpuid_0 = 0; const int cpuid_1 = portNUM_PROCESSORS - 1; @@ -339,10 +309,3 @@ TEST_CASE("(raw) read speed test", "[fatfs][timeout=60]") free(buf); test_teardown(); } -#else //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2) -TEST_CASE("FATFS dummy test", "[spi_flash]") -{ - printf("This test does nothing, just to make the UT build fatfs-fast-seek passed.\n"); - printf("When any case above is supported, remove this test case\n"); -} -#endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2) diff --git a/components/fatfs/test_apps/flash_ro/partitions.csv b/components/fatfs/test_apps/flash_ro/partitions.csv new file mode 100644 index 0000000000..a929971141 --- /dev/null +++ b/components/fatfs/test_apps/flash_ro/partitions.csv @@ -0,0 +1,3 @@ +# Name, Type, SubType, Offset, Size, Flags +factory, app, factory, 0x10000, 1M, +storage, data, fat, , 528k, diff --git a/components/fatfs/test_apps/flash_ro/pytest_fatfs_flash_ro.py b/components/fatfs/test_apps/flash_ro/pytest_fatfs_flash_ro.py new file mode 100644 index 0000000000..eda296ef2e --- /dev/null +++ b/components/fatfs/test_apps/flash_ro/pytest_fatfs_flash_ro.py @@ -0,0 +1,15 @@ +# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: CC0-1.0 + +import pytest +from pytest_embedded import Dut + + +@pytest.mark.supported_targets +@pytest.mark.generic +def test_fatfs_flash_ro(dut: Dut) -> None: + dut.expect_exact('Press ENTER to see the list of tests') + dut.write('') + dut.expect_exact('Enter test for running.') + dut.write('*') + dut.expect_unity_test_output() diff --git a/components/fatfs/test_apps/flash_ro/sdkconfig.defaults b/components/fatfs/test_apps/flash_ro/sdkconfig.defaults new file mode 100644 index 0000000000..c679bc7b4d --- /dev/null +++ b/components/fatfs/test_apps/flash_ro/sdkconfig.defaults @@ -0,0 +1,14 @@ +# General options for additional checks +CONFIG_HEAP_POISONING_COMPREHENSIVE=y +CONFIG_COMPILER_WARN_WRITE_STRINGS=y +CONFIG_BOOTLOADER_LOG_LEVEL_WARN=y +CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK=y +CONFIG_COMPILER_STACK_CHECK_MODE_STRONG=y +CONFIG_COMPILER_STACK_CHECK=y + +# disable task watchdog since this app uses an interactive menu +CONFIG_ESP_TASK_WDT_INIT=n + +# use custom partition table +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" diff --git a/components/fatfs/test_apps/flash_wl/CMakeLists.txt b/components/fatfs/test_apps/flash_wl/CMakeLists.txt new file mode 100644 index 0000000000..3c63fc0c0c --- /dev/null +++ b/components/fatfs/test_apps/flash_wl/CMakeLists.txt @@ -0,0 +1,8 @@ +cmake_minimum_required(VERSION 3.16) + +set(COMPONENTS main) +set(EXTRA_COMPONENT_DIRS "${CMAKE_CURRENT_LIST_DIR}/../test_fatfs_common") + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) + +project(test_fatfs_flash_wl) diff --git a/components/fatfs/test_apps/flash_wl/README.md b/components/fatfs/test_apps/flash_wl/README.md new file mode 100644 index 0000000000..1a530524e6 --- /dev/null +++ b/components/fatfs/test_apps/flash_wl/README.md @@ -0,0 +1,8 @@ +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | + +This test app runs a few FATFS test cases in a wear levelling FAT partition. + +These tests should be possible to run on any ESP development board, not extra hardware is necessary. + +See [../README.md](../README.md) for more information about FATFS test apps. diff --git a/components/fatfs/test_apps/flash_wl/main/CMakeLists.txt b/components/fatfs/test_apps/flash_wl/main/CMakeLists.txt new file mode 100644 index 0000000000..20b600fca2 --- /dev/null +++ b/components/fatfs/test_apps/flash_wl/main/CMakeLists.txt @@ -0,0 +1,4 @@ +idf_component_register(SRCS "test_fatfs_flash_wl.c" + INCLUDE_DIRS "." + PRIV_REQUIRES unity spi_flash fatfs vfs test_fatfs_common + WHOLE_ARCHIVE) diff --git a/components/fatfs/test/test_fatfs_spiflash.c b/components/fatfs/test_apps/flash_wl/main/test_fatfs_flash_wl.c similarity index 95% rename from components/fatfs/test/test_fatfs_spiflash.c rename to components/fatfs/test_apps/flash_wl/main/test_fatfs_flash_wl.c index b1631608a6..a73c6b8aa5 100644 --- a/components/fatfs/test/test_fatfs_spiflash.c +++ b/components/fatfs/test_apps/flash_wl/main/test_fatfs_flash_wl.c @@ -11,7 +11,7 @@ #include #include #include "unity.h" -#include "test_utils.h" +#include "esp_partition.h" #include "esp_log.h" #include "esp_random.h" #include "esp_vfs.h" @@ -23,9 +23,11 @@ #include "esp_partition.h" #include "esp_memory_utils.h" +void app_main(void) +{ + unity_run_menu(); +} -#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2) -//IDF-5136 static wl_handle_t s_test_wl_handle; static void test_setup(void) { @@ -44,7 +46,8 @@ static void test_teardown(void) TEST_CASE("(WL) can format partition", "[fatfs][wear_levelling]") { - const esp_partition_t* part = get_test_data_partition(); + const esp_partition_t* part = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, + ESP_PARTITION_SUBTYPE_DATA_FAT, NULL); esp_partition_erase_range(part, 0, part->size); test_setup(); test_teardown(); @@ -190,7 +193,8 @@ TEST_CASE("(WL) fatfs does not ignore leading spaces", "[fatfs][wear_levelling]" TEST_CASE("(WL) write/read speed test", "[fatfs][wear_levelling][timeout=60]") { /* Erase partition before running the test to get consistent results */ - const esp_partition_t* part = get_test_data_partition(); + const esp_partition_t* part = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, + ESP_PARTITION_SUBTYPE_DATA_FAT, NULL); esp_partition_erase_range(part, 0, part->size); test_setup(); @@ -221,7 +225,6 @@ TEST_CASE("(WL) can get partition info", "[fatfs][wear_levelling]") test_fatfs_info("/spiflash", "/spiflash/test.txt"); test_teardown(); } -#endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2) /* * In FatFs menuconfig, set CONFIG_FATFS_API_ENCODING to UTF-8 and set the @@ -229,9 +232,6 @@ TEST_CASE("(WL) can get partition info", "[fatfs][wear_levelling]") * Ensure that the text editor is UTF-8 compatible when compiling these tests. */ #if defined(CONFIG_FATFS_API_ENCODING_UTF_8) && (CONFIG_FATFS_CODEPAGE == 936) - -#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2) -//IDF-5136 TEST_CASE("(WL) can read file with UTF-8 encoded strings", "[fatfs][wear_levelling]") { test_setup(); @@ -246,7 +246,6 @@ TEST_CASE("(WL) opendir, readdir, rewinddir, seekdir work as expected using UTF- test_fatfs_opendir_readdir_rewinddir_utf_8("/spiflash/目录"); test_teardown(); } -#endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2) #endif //defined(CONFIG_FATFS_API_ENCODING_UTF_8) && (CONFIG_FATFS_CODEPAGE == 936) #ifdef CONFIG_SPIRAM diff --git a/components/fatfs/test_apps/flash_wl/partitions.csv b/components/fatfs/test_apps/flash_wl/partitions.csv new file mode 100644 index 0000000000..a929971141 --- /dev/null +++ b/components/fatfs/test_apps/flash_wl/partitions.csv @@ -0,0 +1,3 @@ +# Name, Type, SubType, Offset, Size, Flags +factory, app, factory, 0x10000, 1M, +storage, data, fat, , 528k, diff --git a/components/fatfs/test_apps/flash_wl/pytest_fatfs_flash_wl.py b/components/fatfs/test_apps/flash_wl/pytest_fatfs_flash_wl.py new file mode 100644 index 0000000000..70b46cbf25 --- /dev/null +++ b/components/fatfs/test_apps/flash_wl/pytest_fatfs_flash_wl.py @@ -0,0 +1,39 @@ +# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: CC0-1.0 + +import pytest +from pytest_embedded import Dut + + +@pytest.mark.supported_targets +@pytest.mark.generic +@pytest.mark.parametrize( + 'config', + [ + 'default', + 'release', + 'fastseek', + ] +) +def test_fatfs_flash_wl_generic(dut: Dut) -> None: + dut.expect_exact('Press ENTER to see the list of tests') + dut.write('') + dut.expect_exact('Enter test for running.') + dut.write('*') + dut.expect_unity_test_output(timeout=120) + + +@pytest.mark.supported_targets +@pytest.mark.psram +@pytest.mark.parametrize( + 'config', + [ + 'psram', + ] +) +def test_fatfs_flash_wl_psram(dut: Dut) -> None: + dut.expect_exact('Press ENTER to see the list of tests') + dut.write('') + dut.expect_exact('Enter test for running.') + dut.write('*') + dut.expect_unity_test_output(timeout=120) diff --git a/components/fatfs/test_apps/flash_wl/sdkconfig.ci.default b/components/fatfs/test_apps/flash_wl/sdkconfig.ci.default new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tools/unit-test-app/configs/fatfs_fast_seek b/components/fatfs/test_apps/flash_wl/sdkconfig.ci.fastseek similarity index 75% rename from tools/unit-test-app/configs/fatfs_fast_seek rename to components/fatfs/test_apps/flash_wl/sdkconfig.ci.fastseek index 0a2037a670..6b1351cf77 100644 --- a/tools/unit-test-app/configs/fatfs_fast_seek +++ b/components/fatfs/test_apps/flash_wl/sdkconfig.ci.fastseek @@ -1,3 +1,2 @@ -TEST_COMPONENTS=fatfs CONFIG_FATFS_USE_FASTSEEK=y CONFIG_FATFS_FAST_SEEK_BUFFER_SIZE=64 diff --git a/components/fatfs/test_apps/flash_wl/sdkconfig.ci.psram b/components/fatfs/test_apps/flash_wl/sdkconfig.ci.psram new file mode 100644 index 0000000000..b3b45db94a --- /dev/null +++ b/components/fatfs/test_apps/flash_wl/sdkconfig.ci.psram @@ -0,0 +1,3 @@ +CONFIG_SPIRAM=y +CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=0 +CONFIG_FATFS_ALLOC_PREFER_EXTRAM=y diff --git a/components/fatfs/test_apps/flash_wl/sdkconfig.ci.release b/components/fatfs/test_apps/flash_wl/sdkconfig.ci.release new file mode 100644 index 0000000000..6a81ea9ab9 --- /dev/null +++ b/components/fatfs/test_apps/flash_wl/sdkconfig.ci.release @@ -0,0 +1,2 @@ +CONFIG_COMPILER_OPTIMIZATION_SIZE=y +CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y diff --git a/components/fatfs/test_apps/flash_wl/sdkconfig.defaults b/components/fatfs/test_apps/flash_wl/sdkconfig.defaults new file mode 100644 index 0000000000..80df3c5ec0 --- /dev/null +++ b/components/fatfs/test_apps/flash_wl/sdkconfig.defaults @@ -0,0 +1,18 @@ +# General options for additional checks +CONFIG_HEAP_POISONING_COMPREHENSIVE=y +CONFIG_COMPILER_WARN_WRITE_STRINGS=y +CONFIG_BOOTLOADER_LOG_LEVEL_WARN=y +CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK=y +CONFIG_COMPILER_STACK_CHECK_MODE_STRONG=y +CONFIG_COMPILER_STACK_CHECK=y + +# disable task watchdog since this app uses an interactive menu +CONFIG_ESP_TASK_WDT_INIT=n + +# use custom partition table +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" + +# some tests verify file name encoding +CONFIG_FATFS_API_ENCODING_UTF_8=y +CONFIG_FATFS_CODEPAGE_936=y diff --git a/components/fatfs/test_apps/sdcard/CMakeLists.txt b/components/fatfs/test_apps/sdcard/CMakeLists.txt new file mode 100644 index 0000000000..a01f216624 --- /dev/null +++ b/components/fatfs/test_apps/sdcard/CMakeLists.txt @@ -0,0 +1,8 @@ +cmake_minimum_required(VERSION 3.16) + +set(COMPONENTS main) +set(EXTRA_COMPONENT_DIRS "${CMAKE_CURRENT_LIST_DIR}/../test_fatfs_common") + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) + +project(test_fatfs_sdcard) diff --git a/components/fatfs/test_apps/sdcard/README.md b/components/fatfs/test_apps/sdcard/README.md new file mode 100644 index 0000000000..237e42a9d6 --- /dev/null +++ b/components/fatfs/test_apps/sdcard/README.md @@ -0,0 +1,14 @@ +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | + +This test app runs a few FATFS test cases in a FAT-formatted SD card. + +These tests require a development board with an SD card slot: + +* ESP32-WROVER-KIT +* ESP32-S2 USB_OTG +* ESP32-C3-DevKit-C with an SD card breakout board + +The test cases are split between `[sdmmc]` and `[sdspi]`. Only a few tests are executed for sdspi, though. The app could be refactored to ensure that a similar set of tests runs for sdmmc and sdspi. + +See [../README.md](../README.md) for more information about FATFS test apps. diff --git a/components/fatfs/test_apps/sdcard/main/CMakeLists.txt b/components/fatfs/test_apps/sdcard/main/CMakeLists.txt new file mode 100644 index 0000000000..be2a969afb --- /dev/null +++ b/components/fatfs/test_apps/sdcard/main/CMakeLists.txt @@ -0,0 +1,8 @@ +idf_component_register(SRCS "test_fatfs_sdcard_main.c" "test_fatfs_sdspi.c" + INCLUDE_DIRS "." + PRIV_REQUIRES unity fatfs vfs sdmmc driver test_fatfs_common + WHOLE_ARCHIVE) + +if(CONFIG_SOC_SDMMC_HOST_SUPPORTED) + target_sources(${COMPONENT_LIB} PRIVATE "test_fatfs_sdmmc.c") +endif() diff --git a/components/fatfs/test_apps/sdcard/main/test_fatfs_sdcard_main.c b/components/fatfs/test_apps/sdcard/main/test_fatfs_sdcard_main.c new file mode 100644 index 0000000000..1b61d31b58 --- /dev/null +++ b/components/fatfs/test_apps/sdcard/main/test_fatfs_sdcard_main.c @@ -0,0 +1,11 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +#include "unity.h" + +void app_main(void) +{ + unity_run_menu(); +} diff --git a/components/fatfs/test/test_fatfs_sdmmc.c b/components/fatfs/test_apps/sdcard/main/test_fatfs_sdmmc.c similarity index 62% rename from components/fatfs/test/test_fatfs_sdmmc.c rename to components/fatfs/test_apps/sdcard/main/test_fatfs_sdmmc.c index a9504d0ace..d18359e121 100644 --- a/components/fatfs/test/test_fatfs_sdmmc.c +++ b/components/fatfs/test_apps/sdcard/main/test_fatfs_sdmmc.c @@ -47,12 +47,10 @@ #endif //SPI_DMA_CHAN #define SDSPI_HOST_ID SPI2_HOST -#if SOC_SDMMC_HOST_SUPPORTED #if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S3) // No runner #include "driver/sdmmc_host.h" - static void test_setup_sdmmc(void) { sdmmc_host_t host = SDMMC_HOST_DEFAULT(); @@ -72,7 +70,7 @@ static void test_teardown_sdmmc(void) static const char* test_filename = "/sdcard/hello.txt"; -TEST_CASE("Mount fails cleanly without card inserted", "[fatfs][sd][ignore]") +TEST_CASE("Mount fails cleanly without card inserted", "[fatfs][ignore]") { size_t heap_size; HEAP_SIZE_CAPTURE(heap_size); @@ -92,14 +90,14 @@ TEST_CASE("Mount fails cleanly without card inserted", "[fatfs][sd][ignore]") HEAP_SIZE_CHECK(heap_size, 0); } -TEST_CASE("(SD) can create and write file", "[fatfs][sd][test_env=UT_T1_SDMODE][timeout=60]") +TEST_CASE("(SD) can create and write file", "[fatfs][sdmmc]") { test_setup_sdmmc(); test_fatfs_create_file_with_text(test_filename, fatfs_test_hello_str); test_teardown_sdmmc(); } -TEST_CASE("(SD) can read file", "[fatfs][test_env=UT_T1_SDMODE][timeout=60]") +TEST_CASE("(SD) can read file", "[fatfs][sdmmc]") { test_setup_sdmmc(); test_fatfs_create_file_with_text(test_filename, fatfs_test_hello_str); @@ -107,7 +105,7 @@ TEST_CASE("(SD) can read file", "[fatfs][test_env=UT_T1_SDMODE][timeout=60]") test_teardown_sdmmc(); } -TEST_CASE("(SD) can read file with pread()", "[fatfs][test_env=UT_T1_SDMODE][timeout=60]") +TEST_CASE("(SD) can read file with pread()", "[fatfs][sdmmc]") { test_setup_sdmmc(); test_fatfs_create_file_with_text(test_filename, fatfs_test_hello_str); @@ -115,91 +113,91 @@ TEST_CASE("(SD) can read file with pread()", "[fatfs][test_env=UT_T1_SDMODE][tim test_teardown_sdmmc(); } -TEST_CASE("(SD) pwrite() works well", "[fatfs][test_env=UT_T1_SDMODE][timeout=60]") +TEST_CASE("(SD) pwrite() works well", "[fatfs][sdmmc]") { test_setup_sdmmc(); test_fatfs_pwrite_file(test_filename); test_teardown_sdmmc(); } -TEST_CASE("(SD) overwrite and append file", "[fatfs][sd][test_env=UT_T1_SDMODE][timeout=60]") +TEST_CASE("(SD) overwrite and append file", "[fatfs][sdmmc]") { test_setup_sdmmc(); test_fatfs_overwrite_append(test_filename); test_teardown_sdmmc(); } -TEST_CASE("(SD) can lseek", "[fatfs][sd][test_env=UT_T1_SDMODE][timeout=60]") +TEST_CASE("(SD) can lseek", "[fatfs][sdmmc]") { test_setup_sdmmc(); test_fatfs_lseek("/sdcard/seek.txt"); test_teardown_sdmmc(); } -TEST_CASE("(SD) can truncate", "[fatfs][sd][test_env=UT_T1_SDMODE][timeout=60]") +TEST_CASE("(SD) can truncate", "[fatfs][sdmmc]") { test_setup_sdmmc(); test_fatfs_truncate_file("/sdcard/truncate.txt"); test_teardown_sdmmc(); } -TEST_CASE("(SD) can ftruncate", "[fatfs][sd][test_env=UT_T1_SDMODE][timeout=60]") +TEST_CASE("(SD) can ftruncate", "[fatfs][sdmmc]") { test_setup_sdmmc(); test_fatfs_ftruncate_file("/sdcard/ftrunc.txt"); test_teardown_sdmmc(); } -TEST_CASE("(SD) stat returns correct values", "[fatfs][test_env=UT_T1_SDMODE][timeout=60]") +TEST_CASE("(SD) stat returns correct values", "[fatfs][sdmmc]") { test_setup_sdmmc(); test_fatfs_stat("/sdcard/stat.txt", "/sdcard"); test_teardown_sdmmc(); } -TEST_CASE("(SD) utime sets modification time", "[fatfs][test_env=UT_T1_SDMODE][timeout=60]") +TEST_CASE("(SD) utime sets modification time", "[fatfs][sdmmc]") { test_setup_sdmmc(); test_fatfs_utime("/sdcard/utime.txt", "/sdcard"); test_teardown_sdmmc(); } -TEST_CASE("(SD) unlink removes a file", "[fatfs][test_env=UT_T1_SDMODE][timeout=60]") +TEST_CASE("(SD) unlink removes a file", "[fatfs][sdmmc]") { test_setup_sdmmc(); test_fatfs_unlink("/sdcard/unlink.txt"); test_teardown_sdmmc(); } -TEST_CASE("(SD) link copies a file, rename moves a file", "[fatfs][test_env=UT_T1_SDMODE][timeout=60]") +TEST_CASE("(SD) link copies a file, rename moves a file", "[fatfs][sdmmc]") { test_setup_sdmmc(); test_fatfs_link_rename("/sdcard/link"); test_teardown_sdmmc(); } -TEST_CASE("(SD) can create and remove directories", "[fatfs][test_env=UT_T1_SDMODE][timeout=60]") +TEST_CASE("(SD) can create and remove directories", "[fatfs][sdmmc]") { test_setup_sdmmc(); test_fatfs_mkdir_rmdir("/sdcard/dir"); test_teardown_sdmmc(); } -TEST_CASE("(SD) can opendir root directory of FS", "[fatfs][test_env=UT_T1_SDMODE][timeout=60]") +TEST_CASE("(SD) can opendir root directory of FS", "[fatfs][sdmmc]") { test_setup_sdmmc(); test_fatfs_can_opendir("/sdcard"); test_teardown_sdmmc(); } -TEST_CASE("(SD) opendir, readdir, rewinddir, seekdir work as expected", "[fatfs][test_env=UT_T1_SDMODE][timeout=60]") +TEST_CASE("(SD) opendir, readdir, rewinddir, seekdir work as expected", "[fatfs][sdmmc]") { test_setup_sdmmc(); test_fatfs_opendir_readdir_rewinddir("/sdcard/dir"); test_teardown_sdmmc(); } -TEST_CASE("(SD) multiple tasks can use same volume", "[fatfs][test_env=UT_T1_SDMODE][timeout=60]") +TEST_CASE("(SD) multiple tasks can use same volume", "[fatfs][sdmmc]") { test_setup_sdmmc(); test_fatfs_concurrent("/sdcard/f"); @@ -208,7 +206,7 @@ TEST_CASE("(SD) multiple tasks can use same volume", "[fatfs][test_env=UT_T1_SDM static void sdmmc_speed_test(void *buf, size_t buf_size, size_t file_size, bool write); -TEST_CASE("(SD) write/read speed test", "[fatfs][sd][test_env=UT_T1_SDMODE][timeout=60]") +TEST_CASE("(SD) write/read speed test", "[fatfs][sdmmc]") { size_t heap_size; HEAP_SIZE_CAPTURE(heap_size); @@ -248,7 +246,7 @@ static void sdmmc_speed_test(void *buf, size_t buf_size, size_t file_size, bool TEST_ESP_OK(esp_vfs_fat_sdmmc_unmount()); } -TEST_CASE("(SD) mount two FAT partitions, SDMMC and WL, at the same time", "[fatfs][sd][test_env=UT_T1_SDMODE][timeout=60]") +TEST_CASE("(SD) mount two FAT partitions, SDMMC and WL, at the same time", "[fatfs][sdmmc]") { esp_vfs_fat_sdmmc_mount_config_t mount_config = { .format_if_mount_failed = true, @@ -260,10 +258,10 @@ TEST_CASE("(SD) mount two FAT partitions, SDMMC and WL, at the same time", "[fat const char* str_sd = "this is sd\n"; const char* str_wl = "this is spiflash\n"; - /* Erase flash before the firs use */ - const esp_partition_t *test_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_ANY, "flash_test"); + /* Erase flash before the first use */ + const esp_partition_t *test_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_FAT, NULL); + TEST_ASSERT_NOT_NULL(test_partition); esp_partition_erase_range(test_partition, 0, test_partition->size); - printf("Partition erased: addr- 0x%08x, size- 0x%08x\n", test_partition->address, test_partition->size); /* Mount FATFS in SD can WL at the same time. Create a file on each FS */ wl_handle_t wl_handle = WL_INVALID_HANDLE; @@ -307,7 +305,7 @@ TEST_CASE("(SD) mount two FAT partitions, SDMMC and WL, at the same time", "[fat static const char* test_filename_utf_8 = "/sdcard/测试文件.txt"; -TEST_CASE("(SD) can read file using UTF-8 encoded strings", "[fatfs][sd][test_env=UT_T1_SDMODE]") +TEST_CASE("(SD) can read file using UTF-8 encoded strings", "[fatfs][sdmmc]") { test_setup_sdmmc(); test_fatfs_create_file_with_text(test_filename_utf_8, fatfs_test_hello_str_utf); @@ -323,7 +321,7 @@ TEST_CASE("(SD) opendir, readdir, rewinddir, seekdir work as expected using UTF- } #endif // CONFIG_FATFS_API_ENCODING_UTF_8 && CONFIG_FATFS_CODEPAGE == 936 -TEST_CASE("(SD) can get partition info", "[fatfs][sd][test_env=UT_T1_SDMODE][timeout=60]") +TEST_CASE("(SD) can get partition info", "[fatfs][sdmmc]") { test_setup_sdmmc(); test_fatfs_info("/sdcard", "/sdcard/test.txt"); @@ -331,122 +329,3 @@ TEST_CASE("(SD) can get partition info", "[fatfs][sd][test_env=UT_T1_SDMODE][tim } #endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32S3) -#endif //SDMMC HOST SUPPORTED - - -#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S3, ESP32C2) -//no runners - -typedef struct sdspi_mem { - size_t heap_size; - uint32_t* buf; -} sdspi_mem_t; - -static void sdspi_speed_test(void *buf, size_t buf_size, size_t file_size, bool write); - -static void test_setup_sdspi(sdspi_mem_t* mem) -{ - HEAP_SIZE_CAPTURE(mem->heap_size); - - const size_t buf_size = 16 * 1024; - mem->buf = (uint32_t*) calloc(1, buf_size); - esp_fill_random(mem->buf, buf_size); - - spi_bus_config_t bus_cfg = { - .mosi_io_num = SDSPI_MOSI_PIN, - .miso_io_num = SDSPI_MISO_PIN, - .sclk_io_num = SDSPI_CLK_PIN, - .quadwp_io_num = -1, - .quadhd_io_num = -1, - .max_transfer_sz = 4000, - }; - esp_err_t err = spi_bus_initialize(SDSPI_HOST_ID, &bus_cfg, SPI_DMA_CHAN); - TEST_ESP_OK(err); -} - -static void test_teardown_sdspi(sdspi_mem_t* mem) -{ - free(mem->buf); - spi_bus_free(SDSPI_HOST_ID); - HEAP_SIZE_CHECK(mem->heap_size, 0); -} - -TEST_CASE("(SDSPI) write/read speed test", "[fatfs][sd][test_env=UT_T1_SPIMODE][timeout=60]") -{ - sdspi_mem_t mem; - size_t file_size = 1 * 1024 * 1024; - - test_setup_sdspi(&mem); - - sdspi_speed_test(mem.buf, 4 * 1024, file_size, true); - sdspi_speed_test(mem.buf, 8 * 1024, file_size, true); - sdspi_speed_test(mem.buf, 16 * 1024, file_size, true); - - sdspi_speed_test(mem.buf, 4 * 1024, file_size, false); - sdspi_speed_test(mem.buf, 8 * 1024, file_size, false); - sdspi_speed_test(mem.buf, 16 * 1024, file_size, false); - - test_teardown_sdspi(&mem); -} - -static void sdspi_speed_test(void *buf, size_t buf_size, size_t file_size, bool write) -{ - const char path[] = "/sdcard"; - sdmmc_card_t *card; - card = NULL; - sdspi_device_config_t device_cfg = { - .gpio_cs = SDSPI_CS_PIN, - .host_id = SDSPI_HOST_ID, - .gpio_cd = SDSPI_SLOT_NO_CD, - .gpio_wp = SDSPI_SLOT_NO_WP, - .gpio_int = SDSPI_SLOT_NO_INT, - }; - - sdmmc_host_t host = SDSPI_HOST_DEFAULT(); - host.slot = SDSPI_HOST_ID; - esp_vfs_fat_sdmmc_mount_config_t mount_config = { - .format_if_mount_failed = write, - .max_files = 5, - .allocation_unit_size = 64 * 1024 - }; - TEST_ESP_OK(esp_vfs_fat_sdspi_mount(path, &host, &device_cfg, &mount_config, &card)); - - test_fatfs_rw_speed("/sdcard/4mb.bin", buf, buf_size, file_size, write); - - TEST_ESP_OK(esp_vfs_fat_sdcard_unmount(path, card)); -} - -TEST_CASE("(SDSPI) can get partition info", "[fatfs][sd][test_env=UT_T1_SPIMODE][timeout=60]") -{ - sdspi_mem_t mem; - - test_setup_sdspi(&mem); - - const char path[] = "/sdcard"; - sdmmc_card_t *card; - card = NULL; - sdspi_device_config_t device_cfg = { - .gpio_cs = SDSPI_CS_PIN, - .host_id = SDSPI_HOST_ID, - .gpio_cd = SDSPI_SLOT_NO_CD, - .gpio_wp = SDSPI_SLOT_NO_WP, - .gpio_int = SDSPI_SLOT_NO_INT, - }; - - sdmmc_host_t host = SDSPI_HOST_DEFAULT(); - host.slot = SDSPI_HOST_ID; - esp_vfs_fat_sdmmc_mount_config_t mount_config = { - .format_if_mount_failed = true, - .max_files = 5, - .allocation_unit_size = 64 * 1024 - }; - TEST_ESP_OK(esp_vfs_fat_sdspi_mount(path, &host, &device_cfg, &mount_config, &card)); - - test_fatfs_info("/sdcard", "/sdcard/test.txt"); - - TEST_ESP_OK(esp_vfs_fat_sdcard_unmount(path, card)); - - test_teardown_sdspi(&mem); -} - -#endif //TEMPORARY_DISABLED_FOR_TARGETS(ESP32S3) diff --git a/components/fatfs/test_apps/sdcard/main/test_fatfs_sdspi.c b/components/fatfs/test_apps/sdcard/main/test_fatfs_sdspi.c new file mode 100644 index 0000000000..d79da9f57b --- /dev/null +++ b/components/fatfs/test_apps/sdcard/main/test_fatfs_sdspi.c @@ -0,0 +1,165 @@ +/* + * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include "unity.h" +#include "esp_log.h" +#include "esp_random.h" +#include "esp_vfs.h" +#include "esp_vfs_fat.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "driver/sdmmc_defs.h" +#include "sdmmc_cmd.h" +#include "ff.h" +#include "test_fatfs_common.h" +#include "soc/soc_caps.h" + +#if CONFIG_IDF_TARGET_ESP32 +#define SDSPI_MISO_PIN 2 +#define SDSPI_MOSI_PIN 15 +#define SDSPI_CLK_PIN 14 +#define SDSPI_CS_PIN 13 +#elif CONFIG_IDF_TARGET_ESP32S2 +// Adapted for internal test board ESP-32-S3-USB-OTG-Ev-BOARD_V1.0 (with ESP32-S2-MINI-1 module) +#define SDSPI_MISO_PIN 37 +#define SDSPI_MOSI_PIN 35 +#define SDSPI_CLK_PIN 36 +#define SDSPI_CS_PIN 34 +#elif CONFIG_IDF_TARGET_ESP32C3 +#define SDSPI_MISO_PIN 6 +#define SDSPI_MOSI_PIN 4 +#define SDSPI_CLK_PIN 5 +#define SDSPI_CS_PIN 1 +#define SPI_DMA_CHAN SPI_DMA_CH_AUTO +#endif //CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32C3 + +#ifndef SPI_DMA_CHAN +#define SPI_DMA_CHAN 1 +#endif //SPI_DMA_CHAN +#define SDSPI_HOST_ID SPI2_HOST + +#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S3, ESP32C2) +//no runners + +typedef struct sdspi_mem { + size_t heap_size; + uint32_t* buf; +} sdspi_mem_t; + +static void sdspi_speed_test(void *buf, size_t buf_size, size_t file_size, bool write); + +static void test_setup_sdspi(sdspi_mem_t* mem) +{ + HEAP_SIZE_CAPTURE(mem->heap_size); + + const size_t buf_size = 16 * 1024; + mem->buf = (uint32_t*) calloc(1, buf_size); + esp_fill_random(mem->buf, buf_size); + + spi_bus_config_t bus_cfg = { + .mosi_io_num = SDSPI_MOSI_PIN, + .miso_io_num = SDSPI_MISO_PIN, + .sclk_io_num = SDSPI_CLK_PIN, + .quadwp_io_num = -1, + .quadhd_io_num = -1, + .max_transfer_sz = 4000, + }; + esp_err_t err = spi_bus_initialize(SDSPI_HOST_ID, &bus_cfg, SPI_DMA_CHAN); + TEST_ESP_OK(err); +} + +static void test_teardown_sdspi(sdspi_mem_t* mem) +{ + free(mem->buf); + spi_bus_free(SDSPI_HOST_ID); + HEAP_SIZE_CHECK(mem->heap_size, 0); +} + +TEST_CASE("(SDSPI) write/read speed test", "[fatfs][sdspi]") +{ + sdspi_mem_t mem; + size_t file_size = 1 * 1024 * 1024; + + test_setup_sdspi(&mem); + + sdspi_speed_test(mem.buf, 4 * 1024, file_size, true); + sdspi_speed_test(mem.buf, 8 * 1024, file_size, true); + sdspi_speed_test(mem.buf, 16 * 1024, file_size, true); + + sdspi_speed_test(mem.buf, 4 * 1024, file_size, false); + sdspi_speed_test(mem.buf, 8 * 1024, file_size, false); + sdspi_speed_test(mem.buf, 16 * 1024, file_size, false); + + test_teardown_sdspi(&mem); +} + +static void sdspi_speed_test(void *buf, size_t buf_size, size_t file_size, bool write) +{ + const char path[] = "/sdcard"; + sdmmc_card_t *card; + card = NULL; + sdspi_device_config_t device_cfg = { + .gpio_cs = SDSPI_CS_PIN, + .host_id = SDSPI_HOST_ID, + .gpio_cd = SDSPI_SLOT_NO_CD, + .gpio_wp = SDSPI_SLOT_NO_WP, + .gpio_int = SDSPI_SLOT_NO_INT, + }; + + sdmmc_host_t host = SDSPI_HOST_DEFAULT(); + host.slot = SDSPI_HOST_ID; + esp_vfs_fat_sdmmc_mount_config_t mount_config = { + .format_if_mount_failed = write, + .max_files = 5, + .allocation_unit_size = 64 * 1024 + }; + TEST_ESP_OK(esp_vfs_fat_sdspi_mount(path, &host, &device_cfg, &mount_config, &card)); + + test_fatfs_rw_speed("/sdcard/4mb.bin", buf, buf_size, file_size, write); + + TEST_ESP_OK(esp_vfs_fat_sdcard_unmount(path, card)); +} + +TEST_CASE("(SDSPI) can get partition info", "[fatfs][sdspi]") +{ + sdspi_mem_t mem; + + test_setup_sdspi(&mem); + + const char path[] = "/sdcard"; + sdmmc_card_t *card; + card = NULL; + sdspi_device_config_t device_cfg = { + .gpio_cs = SDSPI_CS_PIN, + .host_id = SDSPI_HOST_ID, + .gpio_cd = SDSPI_SLOT_NO_CD, + .gpio_wp = SDSPI_SLOT_NO_WP, + .gpio_int = SDSPI_SLOT_NO_INT, + }; + + sdmmc_host_t host = SDSPI_HOST_DEFAULT(); + host.slot = SDSPI_HOST_ID; + esp_vfs_fat_sdmmc_mount_config_t mount_config = { + .format_if_mount_failed = true, + .max_files = 5, + .allocation_unit_size = 64 * 1024 + }; + TEST_ESP_OK(esp_vfs_fat_sdspi_mount(path, &host, &device_cfg, &mount_config, &card)); + + test_fatfs_info("/sdcard", "/sdcard/test.txt"); + + TEST_ESP_OK(esp_vfs_fat_sdcard_unmount(path, card)); + + test_teardown_sdspi(&mem); +} + +#endif //TEMPORARY_DISABLED_FOR_TARGETS(ESP32S3) diff --git a/components/fatfs/test_apps/sdcard/partitions.csv b/components/fatfs/test_apps/sdcard/partitions.csv new file mode 100644 index 0000000000..a929971141 --- /dev/null +++ b/components/fatfs/test_apps/sdcard/partitions.csv @@ -0,0 +1,3 @@ +# Name, Type, SubType, Offset, Size, Flags +factory, app, factory, 0x10000, 1M, +storage, data, fat, , 528k, diff --git a/components/fatfs/test_apps/sdcard/pytest_fatfs_sdcard.py b/components/fatfs/test_apps/sdcard/pytest_fatfs_sdcard.py new file mode 100644 index 0000000000..4ec667dd14 --- /dev/null +++ b/components/fatfs/test_apps/sdcard/pytest_fatfs_sdcard.py @@ -0,0 +1,75 @@ +# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: CC0-1.0 + +import pytest +from pytest_embedded import Dut + + +@pytest.mark.esp32 +@pytest.mark.sdcard_sdmode +@pytest.mark.parametrize( + 'config', + [ + 'default', + 'release', + ] +) +def test_fatfs_sdcard_generic_sdmmc(dut: Dut) -> None: + dut.expect_exact('Press ENTER to see the list of tests') + dut.write('') + dut.expect_exact('Enter test for running.') + dut.write('[sdmmc]') + dut.expect_unity_test_output() + + +@pytest.mark.esp32 +@pytest.mark.esp32s2 +@pytest.mark.esp32c3 +@pytest.mark.sdcard_spimode +@pytest.mark.parametrize( + 'config', + [ + 'default', + 'release', + ] +) +def test_fatfs_sdcard_generic_sdspi(dut: Dut) -> None: + dut.expect_exact('Press ENTER to see the list of tests') + dut.write('') + dut.expect_exact('Enter test for running.') + dut.write('[sdspi]') + dut.expect_unity_test_output() + + +@pytest.mark.esp32 +@pytest.mark.sdcard_sdmode +@pytest.mark.psram +@pytest.mark.parametrize( + 'config', + [ + 'psram', + ] +) +def test_fatfs_sdcard_psram_sdmmc(dut: Dut) -> None: + dut.expect_exact('Press ENTER to see the list of tests') + dut.write('') + dut.expect_exact('Enter test for running.') + dut.write('[sdmmc]') + dut.expect_unity_test_output() + + +@pytest.mark.esp32 +@pytest.mark.sdcard_spimode +@pytest.mark.psram +@pytest.mark.parametrize( + 'config', + [ + 'psram', + ] +) +def test_fatfs_sdcard_psram_sdspi(dut: Dut) -> None: + dut.expect_exact('Press ENTER to see the list of tests') + dut.write('') + dut.expect_exact('Enter test for running.') + dut.write('[sdspi]') + dut.expect_unity_test_output() diff --git a/components/fatfs/test_apps/sdcard/sdkconfig.ci.default b/components/fatfs/test_apps/sdcard/sdkconfig.ci.default new file mode 100644 index 0000000000..e69de29bb2 diff --git a/components/fatfs/test_apps/sdcard/sdkconfig.ci.psram b/components/fatfs/test_apps/sdcard/sdkconfig.ci.psram new file mode 100644 index 0000000000..b3b45db94a --- /dev/null +++ b/components/fatfs/test_apps/sdcard/sdkconfig.ci.psram @@ -0,0 +1,3 @@ +CONFIG_SPIRAM=y +CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=0 +CONFIG_FATFS_ALLOC_PREFER_EXTRAM=y diff --git a/components/fatfs/test_apps/sdcard/sdkconfig.ci.release b/components/fatfs/test_apps/sdcard/sdkconfig.ci.release new file mode 100644 index 0000000000..6a81ea9ab9 --- /dev/null +++ b/components/fatfs/test_apps/sdcard/sdkconfig.ci.release @@ -0,0 +1,2 @@ +CONFIG_COMPILER_OPTIMIZATION_SIZE=y +CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y diff --git a/components/fatfs/test_apps/sdcard/sdkconfig.defaults b/components/fatfs/test_apps/sdcard/sdkconfig.defaults new file mode 100644 index 0000000000..862b5bd85a --- /dev/null +++ b/components/fatfs/test_apps/sdcard/sdkconfig.defaults @@ -0,0 +1,19 @@ +# General options for additional checks +CONFIG_HEAP_POISONING_COMPREHENSIVE=y +CONFIG_COMPILER_WARN_WRITE_STRINGS=y +CONFIG_BOOTLOADER_LOG_LEVEL_WARN=y +CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK=y +CONFIG_COMPILER_STACK_CHECK_MODE_STRONG=y +CONFIG_COMPILER_STACK_CHECK=y + +# disable task watchdog since this app uses an interactive menu +CONFIG_ESP_TASK_WDT_INIT=n + +# some tests verify file name encoding +CONFIG_FATFS_API_ENCODING_UTF_8=y +CONFIG_FATFS_CODEPAGE_936=y + +# some of the tests verify concurrent operation of FAT partitions in +# an SD card and in Flash, so need to use a custom partition table. +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" diff --git a/components/fatfs/test_apps/test_fatfs_common/CMakeLists.txt b/components/fatfs/test_apps/test_fatfs_common/CMakeLists.txt new file mode 100644 index 0000000000..8f06878d30 --- /dev/null +++ b/components/fatfs/test_apps/test_fatfs_common/CMakeLists.txt @@ -0,0 +1,3 @@ +idf_component_register(SRCS "test_fatfs_common.c" + INCLUDE_DIRS "." + PRIV_REQUIRES unity fatfs vfs unity) diff --git a/components/fatfs/test/test_fatfs_common.c b/components/fatfs/test_apps/test_fatfs_common/test_fatfs_common.c similarity index 98% rename from components/fatfs/test/test_fatfs_common.c rename to components/fatfs/test_apps/test_fatfs_common/test_fatfs_common.c index ddb8c5b242..c9b578868e 100644 --- a/components/fatfs/test/test_fatfs_common.c +++ b/components/fatfs/test_apps/test_fatfs_common/test_fatfs_common.c @@ -15,15 +15,11 @@ #include #include #include "unity.h" -#include "esp_log.h" -#include "esp_system.h" #include "esp_vfs.h" #include "esp_vfs_fat.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" -#include "ff.h" #include "test_fatfs_common.h" -#include "esp_rom_sys.h" const char* fatfs_test_hello_str = "Hello, World!\n"; const char* fatfs_test_hello_str_utf = "世界,你好!\n"; @@ -780,9 +776,9 @@ typedef struct { const char* filename; bool write; size_t word_count; - int seed; + unsigned seed; SemaphoreHandle_t done; - int result; + esp_err_t result; } read_write_test_arg_t; #define READ_WRITE_TEST_ARG_INIT(name, seed_) \ @@ -805,19 +801,19 @@ static void read_write_task(void* param) srand(args->seed); for (size_t i = 0; i < args->word_count; ++i) { - uint32_t val = rand(); + unsigned val = rand(); if (args->write) { int cnt = fwrite(&val, sizeof(val), 1, f); if (cnt != 1) { - esp_rom_printf("E(w): i=%d, cnt=%d val=%d\n\n", i, cnt, val); + printf("E(w): i=%d, cnt=%d val=0x08%x\n", i, cnt, val); args->result = ESP_FAIL; goto close; } } else { - uint32_t rval; + unsigned rval; int cnt = fread(&rval, sizeof(rval), 1, f); if (cnt != 1 || rval != val) { - esp_rom_printf("E(r): i=%d, cnt=%d rval=%d val=%d\n\n", i, cnt, rval, val); + printf("E(r): i=%d, cnt=%d rval=0x08%x val=0x08%x\n", i, cnt, rval, val); args->result = ESP_FAIL; goto close; } diff --git a/components/fatfs/test/test_fatfs_common.h b/components/fatfs/test_apps/test_fatfs_common/test_fatfs_common.h similarity index 100% rename from components/fatfs/test/test_fatfs_common.h rename to components/fatfs/test_apps/test_fatfs_common/test_fatfs_common.h diff --git a/tools/unit-test-app/sdkconfig.defaults b/tools/unit-test-app/sdkconfig.defaults index 9623e9f19d..74cb32ef75 100644 --- a/tools/unit-test-app/sdkconfig.defaults +++ b/tools/unit-test-app/sdkconfig.defaults @@ -22,7 +22,6 @@ CONFIG_COMPILER_WARN_WRITE_STRINGS=y CONFIG_SPI_MASTER_IN_IRAM=y CONFIG_EFUSE_VIRTUAL=y CONFIG_SPIRAM_BANKSWITCH_ENABLE=n -CONFIG_FATFS_ALLOC_PREFER_EXTRAM=y CONFIG_UNITY_ENABLE_BACKTRACE_ON_FAIL=y CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=3000 CONFIG_MQTT_TEST_BROKER_URI="mqtt://${EXAMPLE_MQTT_BROKER_TCP}"