feat(examples/storage): update perf benchmark example

pull/13660/head
Tomas Rohlinek 2024-04-09 15:02:05 +08:00
rodzic 859d9a89e1
commit 0c9937570f
13 zmienionych plików z 838 dodań i 535 usunięć

Wyświetl plik

@ -10,6 +10,38 @@
This example demonstrates a benchmark of a storage media such as SPI flash memory and SD card. This example demonstrates a benchmark of a storage media such as SPI flash memory and SD card.
Only ESP32 and ESP32-S3 targets can use SDMMC mode when connecting to a SD card. Only ESP32 and ESP32-S3 targets can use SDMMC mode when connecting to a SD card.
This example provides comparison between different types of storage in terms of speed under various configurable (from menuconfig) conditions
Currently these mediums and file-systems are supported:
- SPI Flash
- Raw access
- FATFS
- SPIFFS
- LittleFS
- SDMMC/SDSPI card
- Raw access
- FATFS
- LittleFS
### Comparison scheme
For each filesystem, four sets of benchmarks are run:
- Target size R/W
- More than target size R/W (about target_size x 1.2)
- Less than target size R/W (about target_size / 1.2)
- Tiny size (255 bytes)
Some filesystems are also tested in two modes:
- New file - new file gets created every time
- Normal - the old file gets overwritten each time (`O_TRUNC`)
Every benchmark (except SPIFFS ones) is run multiple times (can be configuredd) for better accuracy, as the results often vary between runs.
We recommend using at least `100` runs, but default is set to `10` for convenience.
### Disclaimer
While this benchmark tries to give objective results, they may vary by significant amount with different settings, especially for filesystem with large amount of compile time configuration options such as LittleFS.
### Pin assignments for SD card connection ### Pin assignments for SD card connection
The GPIO pin numbers used to connect an SD card can be customized using the following: The GPIO pin numbers used to connect an SD card can be customized using the following:
@ -65,6 +97,10 @@ This command will burn the `XPD_SDIO_TIEH`, `XPD_SDIO_FORCE`, and `XPD_SDIO_REG`
See [the document about pullup requirements](https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/peripherals/sd_pullup_requirements.html) for more details about pullup support and compatibility of modules and development boards. See [the document about pullup requirements](https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/peripherals/sd_pullup_requirements.html) for more details about pullup support and compatibility of modules and development boards.
### Note about SPIFFS
The test for SPIFFS is run only once, because SPIFFS has a problem with deleting files.
## How to use example ## How to use example
### Configure ### Configure
@ -73,10 +109,13 @@ See [the document about pullup requirements](https://docs.espressif.com/projects
1. Configure the example (`idf.py menuconfig` -> "Performance Benchmark Example Configuration") whether you want to: 1. Configure the example (`idf.py menuconfig` -> "Performance Benchmark Example Configuration") whether you want to:
- Set size of data to write
- Test internal SPI flash - Test internal SPI flash
- Raw access - Raw access (through wear-leveling)
- FATFS - FATFS
- Set cluster size
- SPIFFS - SPIFFS
- LittleFS
- Test SD card - Test SD card
- Select SD card interface - Select SD card interface
@ -85,11 +124,24 @@ See [the document about pullup requirements](https://docs.espressif.com/projects
- SD card test configuration - SD card test configuration
- Raw access - Raw access
- FATFS - FATFS
- LittleFS
- Set SD card frequency - Set SD card frequency
- Set GPIO pins - Set GPIO pins
Some configuration options may be available for ESP32 and ESP32-S3 only. Some configuration options may be available for ESP32 and ESP32-S3 only.
#### Note about LittleFS
LittleFS offers many other compile time configuration options which need to be set in it's component config.
These setting will have effect on it's performance.
#### Note about FATFS
To achieve the best performance the cluster should match with the target size, and be as high as possible.
However the higher the cluster size the more space will be wasted by partially filled clusters.
Keep in mind that the cluster size needs to be a multiple of sector size for SPI-flash that's 4096 and for SD-Card it's 512.
Also, the size of the storage medium determines maximum cluster size, for that reason this example uses 2MB of flash just for the filesystem (4MB by default, for smaller cluster sizes (16k) around 1MB should be enough.
### Build and flash ### Build and flash
Build the project and flash it to the board, then run monitor tool to view serial output: Build the project and flash it to the board, then run monitor tool to view serial output:
@ -107,139 +159,140 @@ See the Getting Started Guide for full steps to configure and use ESP-IDF to bui
## Example output ## Example output
``` ```
I (345) example: Start of the example I (302) main_task: Calling app_main()
I (355) example: Internal flash test I (302) example: Starting benchmark test with target size 65536 bytes
I (355) example: Mountig WL layer... I (302) example: Internal flash test
I (415) example: WL layer mounted I (302) example: Mountig WL layer...
I (505) example: Test with 128kiB file I (622) example: WL layer mounted
Wrote 131072 bytes in 320.295ms (0.390MiB/s) to address 0 [SPI Flash raw write ] (100x) 96.610 ms 64.00 kB 0.647 MB/s
I (895) example: WL layer unmounted [SPI Flash raw read ] (100x) 8.076 ms 64.00 kB 7.739 MB/s
I (895) example: Mounting FATFS partition... I (11242) example: WL layer unmounted
W (895) vfs_fat_spiflash: f_mount failed (13) I (11242) example: Mounting FATFS partition, with cluster size 65536 bytes
I (895) vfs_fat_spiflash: Formatting FATFS partition, allocation unit size=16384 W (11242) vfs_fat_spiflash: f_mount failed (13)
I (1105) vfs_fat_spiflash: Mounting again I (11252) vfs_fat_spiflash: Formatting FATFS partition, allocation unit size=65536
I (1105) example: FATFS mounted to /spiflash I (11672) vfs_fat_spiflash: Mounting again
I (1205) example: Test with 128kiB file I (11672) example: FATFS mounted to /spiflash
Wrote 131072 bytes (buffer size 4096B) in 1295.988ms (0.096MiB/s) [SPI FATFS (new file): write target size ] (100x) 1053.682 ms 64.00 kB 0.059 MB/s
Wrote 131072 bytes (buffer size 8192B) in 1277.569ms (0.098MiB/s) [SPI FATFS (new file): read target size ] (100x) 8.124 ms 64.00 kB 7.694 MB/s
Wrote 131072 bytes (buffer size 16384B) in 1439.405ms (0.087MiB/s) [SPI FATFS (new file): write more than target size ] (100x) 1259.972 ms 76.80 kB 0.060 MB/s
Read 131072 bytes (buffer size 4096B) in 17.721ms (7.054MiB/s) [SPI FATFS (new file): read more than target size ] (100x) 10.728 ms 76.80 kB 6.991 MB/s
Read 131072 bytes (buffer size 8192B) in 16.945ms (7.377MiB/s) [SPI FATFS (new file): write less than target size ] (100x) 850.835 ms 53.33 kB 0.061 MB/s
Read 131072 bytes (buffer size 16384B) in 16.596ms (7.532MiB/s) [SPI FATFS (new file): read less than target size ] (100x) 7.156 ms 53.33 kB 7.278 MB/s
I (5705) example: Test with 256kiB file [SPI FATFS (new file): write tiny size ] (100x) 1.180 ms 0.25 kB 0.206 MB/s
Wrote 262144 bytes (buffer size 4096B) in 2529.380ms (0.099MiB/s) [SPI FATFS (new file): read tiny size ] (100x) 0.585 ms 0.25 kB 0.416 MB/s
Wrote 262144 bytes (buffer size 8192B) in 2867.352ms (0.087MiB/s) I (510282) example: FATFS partition unmounted
Wrote 262144 bytes (buffer size 16384B) in 2879.113ms (0.087MiB/s) I (510282) example: Mounting SPIFFS partition...
Read 262144 bytes (buffer size 4096B) in 34.809ms (7.182MiB/s) W (510282) SPIFFS: mount failed, -10025. formatting...
Read 262144 bytes (buffer size 8192B) in 33.315ms (7.504MiB/s) I (530862) example: SPIFFS mounted to /spiflash
Read 262144 bytes (buffer size 16384B) in 32.601ms (7.668MiB/s) [SPI SPIFFS (new file): write target size ] (1x) 464.198 ms 64.00 kB 0.135 MB/s
I (14535) example: Test with 512kiB file [SPI SPIFFS (new file): read target size ] (1x) 137.664 ms 64.00 kB 0.454 MB/s
Wrote 524288 bytes (buffer size 4096B) in 5119.009ms (0.098MiB/s) [SPI SPIFFS (new file): write more than target size ] (1x) 555.745 ms 76.80 kB 0.135 MB/s
Wrote 524288 bytes (buffer size 8192B) in 5897.010ms (0.085MiB/s) [SPI SPIFFS (new file): read more than target size ] (1x) 146.080 ms 76.80 kB 0.513 MB/s
Wrote 524288 bytes (buffer size 16384B) in 5888.743ms (0.085MiB/s) [SPI SPIFFS (new file): write less than target size ] (1x) 390.201 ms 53.33 kB 0.133 MB/s
Read 524288 bytes (buffer size 4096B) in 68.975ms (7.249MiB/s) [SPI SPIFFS (new file): read less than target size ] (1x) 128.494 ms 53.33 kB 0.405 MB/s
Read 524288 bytes (buffer size 8192B) in 66.063ms (7.569MiB/s) [SPI SPIFFS (new file): write tiny size ] (1x) 0.050 ms 0.25 kB 4.864 MB/s
Read 524288 bytes (buffer size 16384B) in 64.624ms (7.737MiB/s) [SPI SPIFFS (new file): read tiny size ] (1x) 0.412 ms 0.25 kB 0.590 MB/s
I (32295) example: FATFS partition unmounted I (534762) example: SPIFFS partition unmounted
I (32295) example: Mounting SPIFFS partition... I (534762) example: Mounting LittleFS partition...
W (32295) SPIFFS: mount failed, -10025. formatting... E (534772) esp_littlefs: /IDF/examples/storage/perf_benchmark/managed_components/joltwallet__littlefs/src/littlefs/lfs.c:1366:error: Corrupted dir pair at {0x0, 0x1}
I (38195) example: SPIFFS mounted to /spiflash
I (41555) example: Partition size: total: 896321, used: 0 W (534782) esp_littlefs: mount failed, (-84). formatting...
I (41645) example: Test with 128kiB file I (534862) example: LittleFS mounted to /spiflash
Wrote 131072 bytes (buffer size 4096B) in 819.950ms (0.152MiB/s) [SPI LittleFS (new file): write target size ] (100x) 946.405 ms 64.00 kB 0.066 MB/s
Wrote 131072 bytes (buffer size 8192B) in 777.949ms (0.161MiB/s) [SPI LittleFS (new file): read target size ] (100x) 28.988 ms 64.00 kB 2.156 MB/s
Wrote 131072 bytes (buffer size 16384B) in 751.682ms (0.166MiB/s) [SPI LittleFS (new file): write more than target size ] (100x) 1176.518 ms 76.80 kB 0.064 MB/s
Read 131072 bytes (buffer size 4096B) in 101.810ms (1.228MiB/s) [SPI LittleFS (new file): read more than target size ] (100x) 39.843 ms 76.80 kB 1.882 MB/s
Read 131072 bytes (buffer size 8192B) in 99.518ms (1.256MiB/s) [SPI LittleFS (new file): write less than target size ] (100x) 821.555 ms 53.33 kB 0.063 MB/s
Read 131072 bytes (buffer size 16384B) in 98.472ms (1.269MiB/s) [SPI LittleFS (new file): read less than target size ] (100x) 25.848 ms 53.33 kB 2.015 MB/s
I (45335) example: Test with 256kiB file [SPI LittleFS (new file): write tiny size ] (100x) 0.043 ms 0.25 kB 5.635 MB/s
Wrote 262144 bytes (buffer size 4096B) in 1650.525ms (0.151MiB/s) [SPI LittleFS (new file): read tiny size ] (100x) 0.036 ms 0.25 kB 6.685 MB/s
Wrote 262144 bytes (buffer size 8192B) in 3220.004ms (0.078MiB/s) I (849202) example: LittleFS partition unmounted
Wrote 262144 bytes (buffer size 16384B) in 7139.803ms (0.035MiB/s) I (849202) example: SD card test
Read 262144 bytes (buffer size 4096B) in 204.933ms (1.220MiB/s) I (849202) example: Initializing SD card
Read 262144 bytes (buffer size 8192B) in 200.330ms (1.248MiB/s) I (849212) sd_utils: Using SDMMC peripheral
Read 262144 bytes (buffer size 16384B) in 198.129ms (1.262MiB/s) I (849212) example: Mounting SD card - raw access
I (60365) example: Test with 512kiB file I (849222) gpio: GPIO[13]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0
Wrote 524288 bytes (buffer size 4096B) in 13917.135ms (0.036MiB/s) I (849272) sd_utils: SD card mounted - raw access
Wrote 524288 bytes (buffer size 8192B) in 14302.046ms (0.035MiB/s) Name: SD64G
Wrote 524288 bytes (buffer size 16384B) in 14411.794ms (0.035MiB/s)
Read 524288 bytes (buffer size 4096B) in 317.944ms (1.573MiB/s)
Read 524288 bytes (buffer size 8192B) in 308.865ms (1.619MiB/s)
Read 524288 bytes (buffer size 16384B) in 304.305ms (1.643MiB/s)
I (108835) example: SPIFFS partition unmounted
I (108835) example: SD card test
I (108845) example: Initializing SD card
I (108845) example: Using SDMMC peripheral
I (108855) example: Mounting SD card - raw access
I (108855) gpio: GPIO[36]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0
I (108865) gpio: GPIO[35]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0
I (108875) gpio: GPIO[37]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0
I (108885) gpio: GPIO[38]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0
I (108895) gpio: GPIO[33]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0
I (108905) gpio: GPIO[34]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0
I (108955) gpio: GPIO[34]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0
I (108965) example: SD card mounted - raw access
Name: USD00
Type: SDHC/SDXC Type: SDHC/SDXC
Speed: 40.00 MHz (limit: 40.00 MHz) Speed: 40.00 MHz (limit: 40.00 MHz)
Size: 15080MB Size: 59640MB
CSD: ver=2, sector_size=512, capacity=30883840 read_bl_len=9 CSD: ver=2, sector_size=512, capacity=122142720 read_bl_len=9
SSR: bus_width=4 SSR: bus_width=4
Wrote 65536 bytes in 25.321ms (2.468MiB/s) to sector 415075 [SD raw write ] (100x) 6.757 ms 16.00 kB 2.312 MB/s
Read 65536 bytes in 3.809ms (16.409MiB/s) from sector 415075 [SD raw read ] (100x) 3.856 ms 16.00 kB 4.053 MB/s
Wrote 131072 bytes in 7.415ms (16.858MiB/s) to sector 823598 [SD raw write ] (100x) 13.380 ms 32.00 kB 2.336 MB/s
Read 131072 bytes in 7.149ms (17.485MiB/s) from sector 823598 [SD raw read ] (100x) 3.852 ms 32.00 kB 8.112 MB/s
Wrote 196608 bytes in 10.829ms (17.315MiB/s) to sector 180761 [SD raw write ] (100x) 13.145 ms 48.00 kB 3.566 MB/s
Read 196608 bytes in 10.539ms (17.791MiB/s) from sector 180761 [SD raw read ] (100x) 3.853 ms 48.00 kB 12.167 MB/s
I (109045) example: SD card unmounted - raw access [SD raw write ] (100x) 4.924 ms 64.00 kB 12.692 MB/s
I (109045) example: Mounting SD card - FATFS [SD raw read ] (100x) 3.855 ms 64.00 kB 16.212 MB/s
I (109045) gpio: GPIO[36]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 I (854662) example: SD card unmounted - raw access
I (109055) gpio: GPIO[35]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 I (854662) example: Mounting SD card - FATFS, with cluster size 65536 bytes
I (109065) gpio: GPIO[37]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 I (854672) gpio: GPIO[13]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0
I (109075) gpio: GPIO[38]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 W (854722) vfs_fat_sdmmc: failed to mount card (13)
I (109085) gpio: GPIO[33]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 W (854722) vfs_fat_sdmmc: partitioning card
I (109095) gpio: GPIO[34]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0 W (854722) vfs_fat_sdmmc: formatting card, allocation unit size=65536
I (109145) gpio: GPIO[34]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 W (857742) vfs_fat_sdmmc: mounting again
W (109155) vfs_fat_sdmmc: failed to mount card (13) Name: SD64G
W (109155) vfs_fat_sdmmc: partitioning card
W (109155) vfs_fat_sdmmc: formatting card, allocation unit size=16384
W (110525) vfs_fat_sdmmc: mounting again
Name: USD00
Type: SDHC/SDXC Type: SDHC/SDXC
Speed: 40.00 MHz (limit: 40.00 MHz) Speed: 40.00 MHz (limit: 40.00 MHz)
Size: 15080MB Size: 59640MB
CSD: ver=2, sector_size=512, capacity=30883840 read_bl_len=9 CSD: ver=2, sector_size=512, capacity=122142720 read_bl_len=9
SSR: bus_width=4 SSR: bus_width=4
I (110535) example: SD card mounted - FATFS I (857742) example: SD card mounted - FATFS
I (110715) example: Test with 1MiB file [SD FATFS (new file): write target size ] (100x) 6.236 ms 64.00 kB 10.022 MB/s
Wrote 1048576 bytes (buffer size 4096B) in 200.241ms (4.994MiB/s) [SD FATFS (new file): read target size ] (100x) 3.923 ms 64.00 kB 15.932 MB/s
Wrote 1048576 bytes (buffer size 8192B) in 129.756ms (7.707MiB/s) [SD FATFS (new file): write more than target size ] (100x) 9.519 ms 76.80 kB 7.879 MB/s
Wrote 1048576 bytes (buffer size 16384B) in 91.955ms (10.875MiB/s) [SD FATFS (new file): read more than target size ] (100x) 5.690 ms 76.80 kB 13.181 MB/s
Wrote 1048576 bytes (buffer size 32768B) in 91.424ms (10.938MiB/s) [SD FATFS (new file): write less than target size ] (100x) 6.953 ms 53.33 kB 7.491 MB/s
Read 1048576 bytes (buffer size 4096B) in 121.086ms (8.259MiB/s) [SD FATFS (new file): read less than target size ] (100x) 3.624 ms 53.33 kB 14.372 MB/s
Read 1048576 bytes (buffer size 8192B) in 87.896ms (11.377MiB/s) [SD FATFS (new file): write tiny size ] (100x) 0.423 ms 0.25 kB 0.575 MB/s
Read 1048576 bytes (buffer size 16384B) in 72.525ms (13.788MiB/s) [SD FATFS (new file): read tiny size ] (100x) 0.345 ms 0.25 kB 0.704 MB/s
Read 1048576 bytes (buffer size 32768B) in 74.664ms (13.393MiB/s) [SD FATFS: write target size ] (100x) 5.186 ms 64.00 kB 12.051 MB/s
I (111655) example: Test with 4MiB file [SD FATFS: read target size ] (100x) 3.907 ms 64.00 kB 15.995 MB/s
Wrote 4194304 bytes (buffer size 4096B) in 797.167ms (5.018MiB/s) [SD FATFS: write more than target size ] (100x) 136.273 ms 76.80 kB 0.550 MB/s
Wrote 4194304 bytes (buffer size 8192B) in 533.538ms (7.497MiB/s) [SD FATFS: read more than target size ] (100x) 46.052 ms 76.80 kB 1.629 MB/s
Wrote 4194304 bytes (buffer size 16384B) in 530.830ms (7.535MiB/s) [SD FATFS: write less than target size ] (100x) 105.132 ms 53.33 kB 0.495 MB/s
Wrote 4194304 bytes (buffer size 32768B) in 497.953ms (8.033MiB/s) [SD FATFS: read less than target size ] (100x) 31.151 ms 53.33 kB 1.672 MB/s
Read 4194304 bytes (buffer size 4096B) in 473.495ms (8.448MiB/s) [SD FATFS: write tiny size ] (100x) 0.456 ms 0.25 kB 0.533 MB/s
Read 4194304 bytes (buffer size 8192B) in 351.240ms (11.388MiB/s) [SD FATFS: read tiny size ] (100x) 0.200 ms 0.25 kB 1.217 MB/s
Read 4194304 bytes (buffer size 16384B) in 289.767ms (13.804MiB/s) I (899172) example: SD card unmounted - FATFS
Read 4194304 bytes (buffer size 32768B) in 287.260ms (13.925MiB/s) I (899172) example: Mounting SD card - LittleFS
I (115495) example: Test with 16MiB file I (899182) gpio: GPIO[13]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0
Wrote 16777216 bytes (buffer size 4096B) in 4754.141ms (3.365MiB/s) I (899232) sd_utils: SD card mounted - raw access
Wrote 16777216 bytes (buffer size 8192B) in 2290.545ms (6.985MiB/s) Name: SD64G
Wrote 16777216 bytes (buffer size 16384B) in 2088.811ms (7.660MiB/s) Type: SDHC/SDXC
Wrote 16777216 bytes (buffer size 32768B) in 2148.595ms (7.447MiB/s) Speed: 40.00 MHz (limit: 40.00 MHz)
Read 16777216 bytes (buffer size 4096B) in 1899.620ms (8.423MiB/s) Size: 59640MB
Read 16777216 bytes (buffer size 8192B) in 1419.345ms (11.273MiB/s) CSD: ver=2, sector_size=512, capacity=122142720 read_bl_len=9
Read 16777216 bytes (buffer size 16384B) in 1158.909ms (13.806MiB/s) SSR: bus_width=4
Read 16777216 bytes (buffer size 32768B) in 1148.426ms (13.932MiB/s) I (899232) esp_littlefs: Using SD card handle 0x3ffd8880 for LittleFS mount
I (132515) example: SD card unmounted - FATFS W (899242) esp_littlefs: SD card is too big (sector=512, count=122142720; total=62537072640 bytes), throttling to maximum possible 8388607 blocks
I (132515) example: End of the example E (899262) esp_littlefs: /IDF/examples/storage/perf_benchmark/managed_components/joltwallet__littlefs/src/littlefs/lfs.c:1366:error: Corrupted dir pair at {0x0, 0x1}
W (899272) esp_littlefs: mount failed, (-84). formatting...
I (901892) esp_littlefs: SD card formatted!
I (901932) example: LittleFS mounted to /sdcard
I (901932) example: SD card mounted - LittleFS
[SD LittleFS (new file): write target size ] (100x) 2723.682 ms 64.00 kB 0.023 MB/s
[SD LittleFS (new file): read target size ] (100x) 235.108 ms 64.00 kB 0.266 MB/s
[SD LittleFS (new file): write more than target size ] (100x) 3312.231 ms 76.80 kB 0.023 MB/s
[SD LittleFS (new file): read more than target size ] (100x) 402.211 ms 76.80 kB 0.186 MB/s
[SD LittleFS (new file): write less than target size ] (100x) 2311.122 ms 53.33 kB 0.023 MB/s
[SD LittleFS (new file): read less than target size ] (100x) 226.808 ms 53.33 kB 0.230 MB/s
[SD LittleFS (new file): write tiny size ] (100x) 17.263 ms 0.25 kB 0.014 MB/s
[SD LittleFS (new file): read tiny size ] (100x) 0.348 ms 0.25 kB 0.699 MB/s
[SD LittleFS: write target size ] (100x) 2928.440 ms 64.00 kB 0.021 MB/s
[SD LittleFS: read target size ] (100x) 692.110 ms 64.00 kB 0.090 MB/s
[SD LittleFS: write more than target size ] (100x) 3547.740 ms 76.80 kB 0.021 MB/s
[SD LittleFS: read more than target size ] (100x) 952.181 ms 76.80 kB 0.079 MB/s
[SD LittleFS: write less than target size ] (100x) 2418.240 ms 53.33 kB 0.022 MB/s
[SD LittleFS: read less than target size ] (100x) 520.300 ms 53.33 kB 0.100 MB/s
[SD LittleFS: write tiny size ] (100x) 10.540 ms 0.25 kB 0.023 MB/s
[SD LittleFS: read tiny size ] (100x) 0.840 ms 0.25 kB 0.289 MB/s
I (2958872) example: SD card unmounted - LittleFS
I (2958872) main_task: Returned from app_main()
``` ```
## Troubleshooting ## Troubleshooting

Wyświetl plik

@ -1,2 +1,3 @@
idf_component_register(SRCS "main.c" "tests.c" idf_component_register(SRCS "perf_benchmark_example_main.c" "perf_benchmark_example_tests.c"
"perf_benchmark_example_sd_utils.c"
INCLUDE_DIRS ".") INCLUDE_DIRS ".")

Wyświetl plik

@ -1,7 +1,27 @@
menu "Performance Benchmark Example Configuration" menu "Performance Benchmark Example Configuration"
config EXAMPLE_TARGET_RW_SIZE
int "Target size for read/write (bytes)"
default 65536
help
This is the target size used for the benchmark,
it represents how much data will be transferred in each test.
(The actual size of the allocated buffer will be larger for "more than target size" cases.)
The test will test will show the performance of reading and writing
of both slightly more and slightly less than this size as well.
This will greatly affect the performance of the benchmark.
In general, the larger the rw size, the better the performance.
For FATFS, the best performance is achieved when the rw size
matches the cluster size or is at least a multiple of the sector size.
config EXAMPLE_USE_MEGABYTES config EXAMPLE_TEST_TRIES
bool "Use megabytes instead of megabits" int "Number of test tries"
default 10
help
The number of times to run the benchmark.
The average value will be displayed.
config EXAMPLE_USE_BYTES
bool "Use bytes instead of bits"
default y default y
help help
If this config item is set, the IO speed will be displayed in megabytes per second If this config item is set, the IO speed will be displayed in megabytes per second
@ -28,12 +48,29 @@ menu "Performance Benchmark Example Configuration"
help help
If this config item is set, FATFS will be tested. If this config item is set, FATFS will be tested.
config EXAMPLE_FATFS_SPIFLASH_CLUSTER_SIZE
depends on EXAMPLE_TEST_SPIFLASH_FATFS
int "Cluster size for FATFS on internal flash"
default EXAMPLE_TARGET_RW_SIZE
help
The cluster size of the FATFS filesystem.
The cluster size must be a multiple of the sector size.
The default value is the same as the target read/write size.
The larger the cluster size, the better the performance,
but the more space will be wasted on the storage medium.
config EXAMPLE_TEST_SPIFLASH_SPIFFS config EXAMPLE_TEST_SPIFLASH_SPIFFS
bool "Test SPIFFS" bool "Test SPIFFS"
default y default y
help help
If this config item is set, SPIFFS will be tested. If this config item is set, SPIFFS will be tested.
config EXAMPLE_TEST_SPIFLASH_LITTLEFS
bool "Test LittleFS"
default y
help
If this config item is set, LittleFS will be tested.
endmenu # "Internal flash test config" endmenu # "Internal flash test config"
config EXAMPLE_TEST_SD_CARD config EXAMPLE_TEST_SD_CARD
@ -74,6 +111,23 @@ menu "Performance Benchmark Example Configuration"
help help
If this config item is set, FATFS will be tested. If this config item is set, FATFS will be tested.
config EXAMPLE_FATFS_SD_CARD_CLUSTER_SIZE
depends on EXAMPLE_TEST_SD_CARD_FATFS
int "Cluster size for FATFS on SD card"
default EXAMPLE_TARGET_RW_SIZE
help
The cluster size of the FATFS filesystem.
The cluster size must be a multiple of the sector size.
The default value is the same as the target read/write size.
The larger the cluster size, the better the performance,
but the more space will be wasted on the storage medium.
config EXAMPLE_TEST_SD_CARD_LITTLEFS
bool "Test LittleFS"
default y
help
If this config item is set, LittleFS will be tested.
choice EXAMPLE_SD_CARD_FREQ_PICKER choice EXAMPLE_SD_CARD_FREQ_PICKER
prompt "SD card frequency" prompt "SD card frequency"
default EXAMPLE_SD_FREQ_HIGHSPEED if EXAMPLE_USE_SDMMC default EXAMPLE_SD_FREQ_HIGHSPEED if EXAMPLE_USE_SDMMC

Wyświetl plik

@ -0,0 +1,3 @@
## IDF Component Manager Manifest File
dependencies:
joltwallet/littlefs: "^1.14.1"

Wyświetl plik

@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Unlicense OR CC0-1.0 * SPDX-License-Identifier: Unlicense OR CC0-1.0
*/ */
@ -15,58 +15,37 @@
#include <stdio.h> #include <stdio.h>
#include <stdbool.h> #include <stdbool.h>
#include <sys/time.h> #include <sys/time.h>
#include "esp_err.h"
#include "esp_log.h" #include "esp_log.h"
#include "esp_check.h" #include "esp_check.h"
#include "esp_partition.h" #include "esp_partition.h"
#include "esp_vfs_fat.h" #include "esp_vfs_fat.h"
#include "esp_spiffs.h" #include "esp_spiffs.h"
#include "soc/soc_caps.h"
#if SOC_SDMMC_HOST_SUPPORTED
#include "driver/sdmmc_host.h"
#endif
#include "driver/sdspi_host.h"
#include "driver/sdmmc_defs.h"
#include "sdmmc_cmd.h"
#include "wear_levelling.h" #include "wear_levelling.h"
#include "esp_littlefs.h"
#include "sdkconfig.h" #include "sdkconfig.h"
#include "tests.h" #include "perf_benchmark_example_tests.h"
#include "perf_benchmark_example_sd_utils.h"
static const char *TAG = "example"; static const char *TAG = "example";
#ifdef CONFIG_EXAMPLE_TEST_SPIFLASH
static const char *flash_partition_label = "storage"; static const char *flash_partition_label = "storage";
#endif // CONFIG_EXAMPLE_TEST_SPIFLASH
wl_handle_t s_wl_handle = WL_INVALID_HANDLE; wl_handle_t s_wl_handle = WL_INVALID_HANDLE;
sdmmc_host_t host_g;
#ifdef CONFIG_EXAMPLE_USE_SDMMC
sdmmc_slot_config_t slot_config_g;
#else // CONFIG_EXAMPLE_USE_SDMMC
sdspi_device_config_t slot_config_g;
#endif // CONFIG_EXAMPLE_USE_SDSPI
#ifdef CONFIG_EXAMPLE_SD_FREQ_PROBING
#define EXAMPLE_SD_FREQ SDMMC_FREQ_PROBING
#elif CONFIG_EXAMPLE_SD_FREQ_DEFAULT
#define EXAMPLE_SD_FREQ SDMMC_FREQ_DEFAULT
#elif CONFIG_EXAMPLE_SD_FREQ_HIGHSPEED
#define EXAMPLE_SD_FREQ SDMMC_FREQ_HIGHSPEED
#elif CONFIG_EXAMPLE_SD_FREQ_CUSTOM
#define EXAMPLE_SD_FREQ CONFIG_EXAMPLE_SD_FREQ_CUSTOM_VAL
#else
#define EXAMPLE_SD_FREQ SDMMC_FREQ_DEFAULT
#endif
#ifdef CONFIG_EXAMPLE_USE_SDMMC
void init_sd_config(sdmmc_host_t *out_host, sdmmc_slot_config_t *out_slot_config, int freq_khz);
#else // CONFIG_EXAMPLE_USE_SDMMC
void init_sd_config(sdmmc_host_t *out_host, sdspi_device_config_t *out_slot_config, int freq_khz);
#endif // CONFIG_EXAMPLE_USE_SDSPI
void test_spiflash_raw(void); void test_spiflash_raw(void);
void test_spiflash_fatfs(void); void test_spiflash_fatfs(void);
void test_spiflash_spiffs(void); void test_spiflash_spiffs(void);
void test_spiflash_littlefs(void);
void test_sd_raw(void); void test_sd_raw(void);
void test_sd_fatfs(void); void test_sd_fatfs(void);
void test_sd_littlefs(void);
void app_main(void) void app_main(void)
{ {
ESP_LOGI(TAG, "Starting benchmark test with target size %d bytes", CONFIG_EXAMPLE_TARGET_RW_SIZE);
#ifdef CONFIG_EXAMPLE_TEST_SPIFLASH #ifdef CONFIG_EXAMPLE_TEST_SPIFLASH
ESP_LOGI(TAG, "Internal flash test"); ESP_LOGI(TAG, "Internal flash test");
@ -85,7 +64,12 @@ void app_main(void)
test_spiflash_spiffs(); test_spiflash_spiffs();
#endif // CONFIG_EXAMPLE_TEST_SPIFLASH_SPIFFS #endif // CONFIG_EXAMPLE_TEST_SPIFLASH_SPIFFS
#ifdef CONFIG_EXAMPLE_TEST_SPIFLASH_LITTLEFS
test_spiflash_littlefs();
#endif // CONFIG_EXAMPLE_TEST_SPIFLASH_LITTLEFS
#endif // CONFIG_EXAMPLE_TEST_SPIFLASH #endif // CONFIG_EXAMPLE_TEST_SPIFLASH
#ifdef CONFIG_EXAMPLE_TEST_SD_CARD #ifdef CONFIG_EXAMPLE_TEST_SD_CARD
ESP_LOGI(TAG, "SD card test"); ESP_LOGI(TAG, "SD card test");
@ -102,9 +86,17 @@ void app_main(void)
test_sd_fatfs(); test_sd_fatfs();
#endif // CONFIG_EXAMPLE_TEST_SD_CARD_FATFS #endif // CONFIG_EXAMPLE_TEST_SD_CARD_FATFS
/* SD card - LittleFS */
#ifdef CONFIG_EXAMPLE_TEST_SD_CARD_LITTLEFS
test_sd_littlefs();
#endif // CONFIG_EXAMPLE_TEST_SD_CARD_LITTLEFS
#endif // CONFIG_EXAMPLE_TEST_SD_CARD #endif // CONFIG_EXAMPLE_TEST_SD_CARD
} }
#if CONFIG_EXAMPLE_TEST_SPIFLASH
#ifdef CONFIG_EXAMPLE_TEST_SPIFLASH_RAW
void test_spiflash_raw(void) void test_spiflash_raw(void)
{ {
esp_err_t ret = ESP_OK; esp_err_t ret = ESP_OK;
@ -122,21 +114,26 @@ void test_spiflash_raw(void)
} }
ESP_LOGI(TAG, "WL layer mounted"); ESP_LOGI(TAG, "WL layer mounted");
spiflash_speed_test_raw_run(); spiflash_speed_test_raw_run(CONFIG_EXAMPLE_TEST_TRIES);
ret = wl_unmount(s_wl_handle); ret = wl_unmount(s_wl_handle);
ESP_ERROR_CHECK(ret); ESP_ERROR_CHECK(ret);
ESP_LOGI(TAG, "WL layer unmounted"); ESP_LOGI(TAG, "WL layer unmounted");
} }
#endif // CONFIG_EXAMPLE_TEST_SPIFLASH_RAW
#ifdef CONFIG_EXAMPLE_TEST_SPIFLASH_FATFS
void test_spiflash_fatfs(void) void test_spiflash_fatfs(void)
{ {
esp_err_t ret = ESP_OK; esp_err_t ret = ESP_OK;
ESP_LOGI(TAG, "Mounting FATFS partition...");
esp_vfs_fat_sdmmc_mount_config_t mount_config_spiflash = { esp_vfs_fat_sdmmc_mount_config_t mount_config_spiflash = {
.format_if_mount_failed = true, .format_if_mount_failed = true,
.max_files = 5, .max_files = 5,
.allocation_unit_size = 16 * 1024}; .allocation_unit_size = CONFIG_EXAMPLE_FATFS_SPIFLASH_CLUSTER_SIZE,
};
ESP_LOGI(TAG, "Mounting FATFS partition, with cluster size %d bytes", mount_config_spiflash.allocation_unit_size);
ret = esp_vfs_fat_spiflash_mount_rw_wl(FLASH_BASE_PATH, flash_partition_label, &mount_config_spiflash, &s_wl_handle); ret = esp_vfs_fat_spiflash_mount_rw_wl(FLASH_BASE_PATH, flash_partition_label, &mount_config_spiflash, &s_wl_handle);
if (ret == ESP_OK) { if (ret == ESP_OK) {
ESP_LOGI(TAG, "FATFS mounted to %s", FLASH_BASE_PATH); ESP_LOGI(TAG, "FATFS mounted to %s", FLASH_BASE_PATH);
@ -145,14 +142,16 @@ void test_spiflash_fatfs(void)
ESP_ERROR_CHECK(ret); ESP_ERROR_CHECK(ret);
} }
spiflash_speed_test_fs_run(); spiflash_speed_test_fatfs_run(CONFIG_EXAMPLE_TEST_TRIES);
// Unregister FATFS and unmount storage partition // Unregister FATFS and unmount storage partition
ret = esp_vfs_fat_spiflash_unmount_rw_wl(FLASH_BASE_PATH, s_wl_handle); ret = esp_vfs_fat_spiflash_unmount_rw_wl(FLASH_BASE_PATH, s_wl_handle);
ESP_ERROR_CHECK(ret); ESP_ERROR_CHECK(ret);
ESP_LOGI(TAG, "FATFS partition unmounted"); ESP_LOGI(TAG, "FATFS partition unmounted");
} }
#endif // CONFIG_EXAMPLE_TEST_SPIFLASH_FATFS
#ifdef CONFIG_EXAMPLE_TEST_SPIFLASH_SPIFFS
void test_spiflash_spiffs(void) void test_spiflash_spiffs(void)
{ {
esp_err_t ret = ESP_OK; esp_err_t ret = ESP_OK;
@ -180,69 +179,85 @@ void test_spiflash_spiffs(void)
ESP_ERROR_CHECK(ret); ESP_ERROR_CHECK(ret);
} }
spiflash_speed_test_fs_run(); spiflash_speed_test_spiffs_run(1); // if run multiple times, it will fail, because spiffs can't delete files
// Unregister SPIFFS and unmount storage partition // Unregister SPIFFS and unmount storage partition
ret = esp_vfs_spiffs_unregister(conf.partition_label); ret = esp_vfs_spiffs_unregister(conf.partition_label);
ESP_ERROR_CHECK(ret); ESP_ERROR_CHECK(ret);
ESP_LOGI(TAG, "SPIFFS partition unmounted"); ESP_LOGI(TAG, "SPIFFS partition unmounted");
} }
#endif // CONFIG_EXAMPLE_TEST_SPIFLASH_SPIFFS
#ifdef CONFIG_EXAMPLE_TEST_SPIFLASH_LITTLEFS
void test_spiflash_littlefs(void)
{
esp_err_t ret = ESP_OK;
ESP_LOGI(TAG, "Mounting LittleFS partition...");
esp_vfs_littlefs_conf_t conf = {
.base_path = FLASH_BASE_PATH,
.partition_label = flash_partition_label,
.format_if_mount_failed = true,
};
// Use settings defined above to initialize and mount LittleFS filesystem.
// Note: esp_vfs_littlefs_register is an all-in-one convenience function.
ret = esp_vfs_littlefs_register(&conf);
if (ret == ESP_OK) {
ESP_LOGI(TAG, "LittleFS mounted to %s", FLASH_BASE_PATH);
} else {
if (ret == ESP_FAIL) {
ESP_LOGE(TAG, "Failed to mount or format filesystem");
} else if (ret == ESP_ERR_NOT_FOUND) {
ESP_LOGE(TAG, "Failed to find LittleFS partition");
} else {
ESP_LOGE(TAG, "Failed to initialize LittleFS (%s)", esp_err_to_name(ret));
}
}
spiflash_speed_test_littlefs_run(CONFIG_EXAMPLE_TEST_TRIES);
// Unregister LittleFS and unmount storage partition
ret = esp_vfs_littlefs_unregister(conf.partition_label);
ESP_ERROR_CHECK(ret);
ESP_LOGI(TAG, "LittleFS partition unmounted");
}
#endif // CONFIG_EXAMPLE_TEST_SPIFLASH_LITTLEFS
#endif // CONFIG_EXAMPLE_TEST_SPIFLASH
#ifdef CONFIG_EXAMPLE_TEST_SD_CARD
#ifdef CONFIG_EXAMPLE_TEST_SD_CARD_RAW
void test_sd_raw(void) void test_sd_raw(void)
{ {
esp_err_t ret = ESP_OK; esp_err_t ret = ESP_OK;
sdmmc_card_t *card; sdmmc_card_t *card;
ESP_LOGI(TAG, "Mounting SD card - raw access"); ESP_LOGI(TAG, "Mounting SD card - raw access");
card = (sdmmc_card_t *)malloc(sizeof(sdmmc_card_t)); ret = init_sd_card(&card);
if (card == NULL) {
ESP_LOGE(TAG, "Failed to allocate sdmmc_card_t structure");
ESP_ERROR_CHECK(ESP_ERR_NO_MEM);
}
// Initialize the interface
#ifdef CONFIG_EXAMPLE_USE_SDMMC
ret = sdmmc_host_init();
ESP_ERROR_CHECK(ret); ESP_ERROR_CHECK(ret);
ret = sdmmc_host_init_slot(SDMMC_HOST_SLOT_1, &slot_config_g);
ESP_ERROR_CHECK(ret);
#elif CONFIG_EXAMPLE_USE_SDSPI // CONFIG_EXAMPLE_USE_SDMMC
int card_handle = -1;
ret = sdspi_host_init_device((const sdspi_device_config_t *)&slot_config_g, &card_handle);
ESP_ERROR_CHECK(ret);
#endif // CONFIG_EXAMPLE_USE_SDSPI
ret = sdmmc_card_init(&host_g, card); sdcard_speed_test_raw_run(card, CONFIG_EXAMPLE_TEST_TRIES);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Failed to initialize SD card (%s)", esp_err_to_name(ret));
ESP_LOGE(TAG, "If you were using SDMMC and switched to SPI reinsert the SD card or power cycle the board");
free(card);
ESP_ERROR_CHECK(ret);
}
ESP_LOGI(TAG, "SD card mounted - raw access");
sdmmc_card_print_info(stdout, card);
sdcard_speed_test_raw_run(card); deinit_sd_card(&card);
// Unmount SD card
#ifdef CONFIG_EXAMPLE_USE_SDMMC
sdmmc_host_deinit();
#else // CONFIG_EXAMPLE_USE_SDMMC
sdspi_host_deinit();
#endif // CONFIG_EXAMPLE_USE_SDSPI
free(card);
ESP_LOGI(TAG, "SD card unmounted - raw access"); ESP_LOGI(TAG, "SD card unmounted - raw access");
} }
#endif // CONFIG_EXAMPLE_TEST_SD_CARD_RAW
#ifdef CONFIG_EXAMPLE_TEST_SD_CARD_FATFS
void test_sd_fatfs(void) void test_sd_fatfs(void)
{ {
esp_err_t ret = ESP_OK; esp_err_t ret = ESP_OK;
sdmmc_card_t *card; sdmmc_card_t *card;
ESP_LOGI(TAG, "Mounting SD card - FATFS");
esp_vfs_fat_sdmmc_mount_config_t mount_config_sdcard = { esp_vfs_fat_sdmmc_mount_config_t mount_config_sdcard = {
.format_if_mount_failed = true, .format_if_mount_failed = true,
.max_files = 5, .max_files = 5,
.allocation_unit_size = 16 * 1024}; .allocation_unit_size = CONFIG_EXAMPLE_FATFS_SD_CARD_CLUSTER_SIZE,
};
ESP_LOGI(TAG, "Mounting SD card - FATFS, with cluster size %d bytes", mount_config_sdcard.allocation_unit_size);
#ifdef CONFIG_EXAMPLE_USE_SDMMC #ifdef CONFIG_EXAMPLE_USE_SDMMC
ret = esp_vfs_fat_sdmmc_mount(SD_BASE_PATH, &host_g, &slot_config_g, &mount_config_sdcard, &card); ret = esp_vfs_fat_sdmmc_mount(SD_BASE_PATH, &host_g, &slot_config_g, &mount_config_sdcard, &card);
#else // CONFIG_EXAMPLE_USE_SDMMC #else // CONFIG_EXAMPLE_USE_SDMMC
@ -258,80 +273,52 @@ void test_sd_fatfs(void)
sdmmc_card_print_info(stdout, card); sdmmc_card_print_info(stdout, card);
ESP_LOGI(TAG, "SD card mounted - FATFS"); ESP_LOGI(TAG, "SD card mounted - FATFS");
sdcard_speed_test_fatfs_run(); sdcard_speed_test_fatfs_run(CONFIG_EXAMPLE_TEST_TRIES);
// Unmount SD card // Unmount SD card
esp_vfs_fat_sdcard_unmount(SD_BASE_PATH, card); esp_vfs_fat_sdcard_unmount(SD_BASE_PATH, card);
ESP_LOGI(TAG, "SD card unmounted - FATFS"); ESP_LOGI(TAG, "SD card unmounted - FATFS");
} }
#endif // CONFIG_EXAMPLE_TEST_SD_CARD_FATFS
#ifdef CONFIG_EXAMPLE_TEST_SD_CARD #ifdef CONFIG_EXAMPLE_TEST_SD_CARD_LITTLEFS
#ifdef CONFIG_EXAMPLE_USE_SDMMC void test_sd_littlefs(void)
void init_sd_config(sdmmc_host_t *out_host, sdmmc_slot_config_t *out_slot_config, int freq_khz) { {
#else // CONFIG_EXAMPLE_USE_SDMMC esp_err_t ret = ESP_OK;
void init_sd_config(sdmmc_host_t *out_host, sdspi_device_config_t *out_slot_config, int freq_khz) { sdmmc_card_t *card;
#endif // CONFIG_EXAMPLE_USE_SDSPI
// By default, SD card frequency is initialized to SDMMC_FREQ_DEFAULT (20MHz) ESP_LOGI(TAG, "Mounting SD card - LittleFS");
// For setting a specific frequency, use host.max_freq_khz
// (range 400kHz - 40MHz for SDMMC, 400kHz - 20MHz for SDSPI)
// Example: for fixed frequency of 10MHz, use host.max_freq_khz = 10000;
#ifdef CONFIG_EXAMPLE_USE_SDMMC
ESP_LOGI(TAG, "Using SDMMC peripheral");
sdmmc_host_t host = SDMMC_HOST_DEFAULT();
host.max_freq_khz = freq_khz;
// This initializes the slot without card detect (CD) and write protect (WP) signals. ret = init_sd_card(&card);
// Modify slot_config.gpio_cd and slot_config.gpio_wp if your board has these signals.
sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT();
// Set bus width to use:
#ifdef CONFIG_EXAMPLE_SDMMC_BUS_WIDTH_4
slot_config.width = 4;
#else
slot_config.width = 1;
#endif
// On chips where the GPIOs used for SD card can be configured, set them in
// the slot_config structure:
#ifdef CONFIG_SOC_SDMMC_USE_GPIO_MATRIX
slot_config.clk = CONFIG_EXAMPLE_PIN_CLK;
slot_config.cmd = CONFIG_EXAMPLE_PIN_CMD;
slot_config.d0 = CONFIG_EXAMPLE_PIN_D0;
#ifdef CONFIG_EXAMPLE_SDMMC_BUS_WIDTH_4
slot_config.d1 = CONFIG_EXAMPLE_PIN_D1;
slot_config.d2 = CONFIG_EXAMPLE_PIN_D2;
slot_config.d3 = CONFIG_EXAMPLE_PIN_D3;
#endif // CONFIG_EXAMPLE_SDMMC_BUS_WIDTH_4
#endif // CONFIG_SOC_SDMMC_USE_GPIO_MATRIX
// Enable internal pullups on enabled pins. The internal pullups
// are insufficient however, please make sure 10k external pullups are
// connected on the bus. This is for debug / example purpose only.
slot_config.flags |= SDMMC_SLOT_FLAG_INTERNAL_PULLUP;
#else // CONFIG_EXAMPLE_USE_SDMMC
ESP_LOGI(TAG, "Using SPI peripheral");
sdmmc_host_t host = SDSPI_HOST_DEFAULT();
host.max_freq_khz = freq_khz;
spi_bus_config_t bus_cfg = {
.mosi_io_num = CONFIG_EXAMPLE_PIN_MOSI,
.miso_io_num = CONFIG_EXAMPLE_PIN_MISO,
.sclk_io_num = CONFIG_EXAMPLE_PIN_CLK,
.quadwp_io_num = -1,
.quadhd_io_num = -1,
.max_transfer_sz = 4000,
};
esp_err_t ret = spi_bus_initialize(host.slot, &bus_cfg, SDSPI_DEFAULT_DMA);
ESP_ERROR_CHECK(ret); ESP_ERROR_CHECK(ret);
// This initializes the slot without card detect (CD) and write protect (WP) signals. esp_vfs_littlefs_conf_t conf = {
// Modify slot_config.gpio_cd and slot_config.gpio_wp if your board has these signals. .base_path = SD_BASE_PATH,
sdspi_device_config_t slot_config = SDSPI_DEVICE_CONFIG_DEFAULT(); .sdcard = card,
slot_config.gpio_cs = CONFIG_EXAMPLE_PIN_CS; .format_if_mount_failed = true,
slot_config.host_id = host.slot; };
#endif // CONFIG_EXAMPLE_USE_SDSPI
*out_host = host; ret = esp_vfs_littlefs_register(&conf);
*out_slot_config = slot_config;
if (ret == ESP_OK) {
ESP_LOGI(TAG, "LittleFS mounted to %s", SD_BASE_PATH);
} else {
if (ret == ESP_FAIL) {
ESP_LOGE(TAG, "Failed to mount or format filesystem");
} else if (ret == ESP_ERR_NOT_FOUND) {
ESP_LOGE(TAG, "Failed to find LittleFS partition");
} else {
ESP_LOGE(TAG, "Failed to initialize LittleFS (%s)", esp_err_to_name(ret));
}
}
ESP_LOGI(TAG, "SD card mounted - LittleFS");
sdcard_speed_test_littlefs_run(CONFIG_EXAMPLE_TEST_TRIES);
// Unmount SD card
esp_vfs_littlefs_unregister_sdmmc(card);
deinit_sd_card(&card);
ESP_LOGI(TAG, "SD card unmounted - LittleFS");
} }
#endif // CONFIG_EXAMPLE_TEST_SD_CARD_LITTLEFS
#endif // CONFIG_EXAMPLE_TEST_SD_CARD #endif // CONFIG_EXAMPLE_TEST_SD_CARD

Wyświetl plik

@ -0,0 +1,144 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#include "perf_benchmark_example_sd_utils.h"
#include "sd_protocol_types.h"
#include "soc/soc_caps.h"
#include "driver/sdspi_host.h"
#include "driver/sdmmc_defs.h"
#include "sdmmc_cmd.h"
#if SOC_SDMMC_HOST_SUPPORTED
#include "driver/sdmmc_host.h"
#endif
#include "esp_log.h"
#ifdef CONFIG_EXAMPLE_TEST_SD_CARD
static const char *TAG = "sd_utils";
sdmmc_host_t host_g;
#ifdef CONFIG_EXAMPLE_USE_SDMMC
sdmmc_slot_config_t slot_config_g;
#else // CONFIG_EXAMPLE_USE_SDMMC
sdspi_device_config_t slot_config_g;
#endif // CONFIG_EXAMPLE_USE_SDSPI
#ifdef CONFIG_EXAMPLE_USE_SDMMC
void init_sd_config(sdmmc_host_t *out_host, sdmmc_slot_config_t *out_slot_config, int freq_khz) {
#else // CONFIG_EXAMPLE_USE_SDMMC
void init_sd_config(sdmmc_host_t *out_host, sdspi_device_config_t *out_slot_config, int freq_khz) {
#endif // CONFIG_EXAMPLE_USE_SDSPI
// By default, SD card frequency is initialized to SDMMC_FREQ_DEFAULT (20MHz)
// For setting a specific frequency, use host.max_freq_khz
// (range 400kHz - 40MHz for SDMMC, 400kHz - 20MHz for SDSPI)
// Example: for fixed frequency of 10MHz, use host.max_freq_khz = 10000;
#ifdef CONFIG_EXAMPLE_USE_SDMMC
ESP_LOGI(TAG, "Using SDMMC peripheral");
sdmmc_host_t host = SDMMC_HOST_DEFAULT();
host.max_freq_khz = freq_khz;
// This initializes the slot without card detect (CD) and write protect (WP) signals.
// Modify slot_config.gpio_cd and slot_config.gpio_wp if your board has these signals.
sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT();
// Set bus width to use:
#ifdef CONFIG_EXAMPLE_SDMMC_BUS_WIDTH_4
slot_config.width = 4;
#else
slot_config.width = 1;
#endif
// On chips where the GPIOs used for SD card can be configured, set them in
// the slot_config structure:
#ifdef CONFIG_SOC_SDMMC_USE_GPIO_MATRIX
slot_config.clk = CONFIG_EXAMPLE_PIN_CLK;
slot_config.cmd = CONFIG_EXAMPLE_PIN_CMD;
slot_config.d0 = CONFIG_EXAMPLE_PIN_D0;
#ifdef CONFIG_EXAMPLE_SDMMC_BUS_WIDTH_4
slot_config.d1 = CONFIG_EXAMPLE_PIN_D1;
slot_config.d2 = CONFIG_EXAMPLE_PIN_D2;
slot_config.d3 = CONFIG_EXAMPLE_PIN_D3;
#endif // CONFIG_EXAMPLE_SDMMC_BUS_WIDTH_4
#endif // CONFIG_SOC_SDMMC_USE_GPIO_MATRIX
// Enable internal pullups on enabled pins. The internal pullups
// are insufficient however, please make sure 10k external pullups are
// connected on the bus. This is for debug / example purpose only.
slot_config.flags |= SDMMC_SLOT_FLAG_INTERNAL_PULLUP;
#else // CONFIG_EXAMPLE_USE_SDMMC
ESP_LOGI(TAG, "Using SPI peripheral");
sdmmc_host_t host = SDSPI_HOST_DEFAULT();
host.max_freq_khz = freq_khz;
spi_bus_config_t bus_cfg = {
.mosi_io_num = CONFIG_EXAMPLE_PIN_MOSI,
.miso_io_num = CONFIG_EXAMPLE_PIN_MISO,
.sclk_io_num = CONFIG_EXAMPLE_PIN_CLK,
.quadwp_io_num = -1,
.quadhd_io_num = -1,
.max_transfer_sz = 4000,
};
esp_err_t ret = spi_bus_initialize(host.slot, &bus_cfg, SDSPI_DEFAULT_DMA);
ESP_ERROR_CHECK(ret);
// This initializes the slot without card detect (CD) and write protect (WP) signals.
// Modify slot_config.gpio_cd and slot_config.gpio_wp if your board has these signals.
sdspi_device_config_t slot_config = SDSPI_DEVICE_CONFIG_DEFAULT();
slot_config.gpio_cs = CONFIG_EXAMPLE_PIN_CS;
slot_config.host_id = host.slot;
#endif // CONFIG_EXAMPLE_USE_SDSPI
*out_host = host;
*out_slot_config = slot_config;
}
esp_err_t init_sd_card(sdmmc_card_t **out_card) {
esp_err_t ret = ESP_OK;
sdmmc_card_t* card = (sdmmc_card_t *)malloc(sizeof(sdmmc_card_t));
if (card == NULL) {
ESP_LOGE(TAG, "Failed to allocate sdmmc_card_t structure");
ESP_ERROR_CHECK(ESP_ERR_NO_MEM);
}
// Initialize the interface
#ifdef CONFIG_EXAMPLE_USE_SDMMC
ret = sdmmc_host_init();
ESP_ERROR_CHECK(ret);
ret = sdmmc_host_init_slot(SDMMC_HOST_SLOT_1, &slot_config_g);
ESP_ERROR_CHECK(ret);
#elif CONFIG_EXAMPLE_USE_SDSPI // CONFIG_EXAMPLE_USE_SDMMC
int card_handle = -1;
ret = sdspi_host_init_device((const sdspi_device_config_t *)&slot_config_g, &card_handle);
ESP_ERROR_CHECK(ret);
#endif // CONFIG_EXAMPLE_USE_SDSPI
ret = sdmmc_card_init(&host_g, card);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Failed to initialize SD card (%s)", esp_err_to_name(ret));
ESP_LOGE(TAG, "If you were using SDMMC and switched to SPI reinsert the SD card or power cycle the board");
free(card);
ESP_ERROR_CHECK(ret);
}
ESP_LOGI(TAG, "SD card mounted - raw access");
sdmmc_card_print_info(stdout, card);
*out_card = card;
return ret;
}
void deinit_sd_card(sdmmc_card_t **card) {
// Unmount SD card
#ifdef CONFIG_EXAMPLE_USE_SDMMC
sdmmc_host_deinit();
#else // CONFIG_EXAMPLE_USE_SDMMC
sdspi_host_deinit();
#endif // CONFIG_EXAMPLE_USE_SDSPI
free(*card);
*card = NULL;
}
#endif // CONFIG_EXAMPLE_TEST_SD_CARD

Wyświetl plik

@ -0,0 +1,48 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#pragma once
#include "sdkconfig.h"
#include "sd_protocol_types.h"
#include "soc/soc_caps.h"
#include "driver/sdspi_host.h"
#include "driver/sdmmc_defs.h"
#include "sdmmc_cmd.h"
#if SOC_SDMMC_HOST_SUPPORTED
#include "driver/sdmmc_host.h"
#endif
extern sdmmc_host_t host_g;
#ifdef CONFIG_EXAMPLE_USE_SDMMC
extern sdmmc_slot_config_t slot_config_g;
#endif // CONFIG_EXAMPLE_USE_SDMMC
#ifdef CONFIG_EXAMPLE_USE_SDSPI
extern sdspi_device_config_t slot_config_g;
#endif // CONFIG_EXAMPLE_USE_SDSPI
#ifdef CONFIG_EXAMPLE_SD_FREQ_PROBING
#define EXAMPLE_SD_FREQ SDMMC_FREQ_PROBING
#elif CONFIG_EXAMPLE_SD_FREQ_DEFAULT
#define EXAMPLE_SD_FREQ SDMMC_FREQ_DEFAULT
#elif CONFIG_EXAMPLE_SD_FREQ_HIGHSPEED
#define EXAMPLE_SD_FREQ SDMMC_FREQ_HIGHSPEED
#elif CONFIG_EXAMPLE_SD_FREQ_CUSTOM
#define EXAMPLE_SD_FREQ CONFIG_EXAMPLE_SD_FREQ_CUSTOM_VAL
#else
#define EXAMPLE_SD_FREQ SDMMC_FREQ_DEFAULT
#endif
#ifdef CONFIG_EXAMPLE_USE_SDMMC
void init_sd_config(sdmmc_host_t *out_host, sdmmc_slot_config_t *out_slot_config, int freq_khz);
#endif // CONFIG_EXAMPLE_USE_SDMMC
#ifdef CONFIG_EXAMPLE_USE_SDSPI
void init_sd_config(sdmmc_host_t *out_host, sdspi_device_config_t *out_slot_config, int freq_khz);
#endif // CONFIG_EXAMPLE_USE_SDSPI
esp_err_t init_sd_card(sdmmc_card_t **out_card);
void deinit_sd_card(sdmmc_card_t **card);

Wyświetl plik

@ -0,0 +1,253 @@
/*
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
/* This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <sys/unistd.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <fcntl.h>
#include <string.h>
#include <assert.h>
#include "esp_err.h"
#include "esp_random.h"
#include "driver/sdmmc_types.h"
#include "sdmmc_cmd.h"
#include "wear_levelling.h"
#include "esp_log.h"
#include "esp_check.h"
#include "sdkconfig.h"
#include "perf_benchmark_example_tests.h"
#if CONFIG_EXAMPLE_USE_BYTES
#define UNIT_STRING "B"
#define UNIT_MULTIPLIER (1)
#else
#define UNIT_STRING "b"
#define UNIT_MULTIPLIER (8)
#endif
static void print_results(const char *name, double time, size_t size, int repeat_count)
{
double average = time / repeat_count;
double speed = (size / average) / (1024 * 1024) * (1000 * 1000);
printf("[%-55s] (%dx) %8.3f ms %8.2f k" UNIT_STRING " %10.3f M" UNIT_STRING "/s\n",
name, repeat_count, (float) average / 1000, (float)size * UNIT_MULTIPLIER / 1024, speed);
}
void spiflash_speed_test_raw_run(size_t repeat_count)
{
const size_t buf_size = CONFIG_EXAMPLE_TARGET_RW_SIZE;
uint32_t* buf = (uint32_t*) calloc(1, buf_size);
assert(buf != NULL);
esp_fill_random(buf, buf_size);
struct timeval tv_start;
struct timeval tv_end;
struct timeval tv_diff;
double time = 0;
for (int i = 0; i < repeat_count; ++i) {
gettimeofday(&tv_start, NULL);
ESP_ERROR_CHECK(wl_write(s_wl_handle, 0, buf, buf_size));
gettimeofday(&tv_end, NULL);
timersub(&tv_end, &tv_start, &tv_diff);
time += (tv_diff.tv_sec * 1000000 + tv_diff.tv_usec);
}
print_results("SPI Flash raw write", time, buf_size, repeat_count);
time = 0;
for (int i = 0; i < repeat_count; ++i) {
gettimeofday(&tv_start, NULL);
ESP_ERROR_CHECK(wl_read(s_wl_handle, 0, buf, buf_size));
gettimeofday(&tv_end, NULL);
timersub(&tv_end, &tv_start, &tv_diff);
time += (tv_diff.tv_sec * 1000000 + tv_diff.tv_usec);
}
print_results("SPI Flash raw read", time, buf_size, repeat_count);
free(buf);
}
static void run_fs_test(const char *name, const char* path, void *buf, size_t buf_size, bool is_write, bool cleanup, bool new_file, size_t repeat_count)
{
struct timeval tv_start;
struct timeval tv_end;
struct timeval tv_diff;
double time = 0;
int fd = -1;
const int flags = is_write ? O_CREAT | O_TRUNC | O_RDWR : O_RDONLY;
if (!new_file) {
fd = open(path, flags, 0666);
assert(fd >= 0);
}
for (int i = 0; i < repeat_count; ++i) {
if (new_file) {
fd = open(path, flags, 0666);
assert(fd >= 0);
}
gettimeofday(&tv_start, NULL);
int ret = is_write ? write(fd, buf, buf_size) : read(fd, buf, buf_size);
gettimeofday(&tv_end, NULL);
if (ret < 0) {
perror(is_write ? "write" : "read");
close(fd);
return;
}
if (ret != buf_size) {
ESP_LOGE("fs_test",
"Could not %s full buffer size. Actually %s bytes: %d.",
is_write ? "write" : "read",
is_write ? "wrote" : "read",
ret);
}
timersub(&tv_end, &tv_start, &tv_diff);
time += (tv_diff.tv_sec * 1000000 + tv_diff.tv_usec);
if (new_file) {
close(fd);
}
}
if (!new_file) {
close(fd);
}
if (cleanup) {
unlink(path);
}
print_results(name, time, buf_size, repeat_count);
}
static void run_fs_tests(const char *base_path, const char *type, bool new_file, size_t repeat_count)
{
char path[256];
snprintf(path, sizeof(path), "%s/test.bin", base_path);
char name[256];
strcpy(name, type);
if (new_file)
strcat(name, " (new file)");
strcat(name, ": ");
size_t name_prefix_len = strlen(name);
const size_t less_than_target_size = CONFIG_EXAMPLE_TARGET_RW_SIZE / 1.2;
const size_t exact_target_size = CONFIG_EXAMPLE_TARGET_RW_SIZE;
const size_t more_than_target_size = CONFIG_EXAMPLE_TARGET_RW_SIZE * 1.2;
const size_t tiny_size = 255;
assert(tiny_size < less_than_target_size);
const size_t buf_size = more_than_target_size;
uint32_t* buf = (uint32_t*) calloc(1, buf_size);
assert(buf != NULL);
esp_fill_random(buf, buf_size);
run_fs_test(strcat(name, "write target size"), path, buf, exact_target_size, true, false, new_file, repeat_count);
name[name_prefix_len] = '\0';
run_fs_test(strcat(name, "read target size"), path, buf, exact_target_size, false, true, new_file, repeat_count);
name[name_prefix_len] = '\0';
run_fs_test(strcat(name, "write more than target size"), path, buf, more_than_target_size, true, false, new_file, repeat_count);
name[name_prefix_len] = '\0';
run_fs_test(strcat(name, "read more than target size"), path, buf, more_than_target_size, false, true, new_file, repeat_count);
name[name_prefix_len] = '\0';
run_fs_test(strcat(name, "write less than target size"), path, buf, less_than_target_size, true, false, new_file, repeat_count);
name[name_prefix_len] = '\0';
run_fs_test(strcat(name, "read less than target size"), path, buf, less_than_target_size, false, true, new_file, repeat_count);
name[name_prefix_len] = '\0';
run_fs_test(strcat(name, "write tiny size"), path, buf, tiny_size, true, false, new_file, repeat_count);
name[name_prefix_len] = '\0';
run_fs_test(strcat(name, "read tiny size"), path, buf, tiny_size, false, true, new_file, repeat_count);
name[name_prefix_len] = '\0';
free(buf);
}
void spiflash_speed_test_spiffs_run(size_t repeat_count)
{
run_fs_tests(FLASH_BASE_PATH, "SPI SPIFFS", true, repeat_count);
}
void spiflash_speed_test_fatfs_run(size_t repeat_count)
{
run_fs_tests(FLASH_BASE_PATH, "SPI FATFS", true, repeat_count);
}
void spiflash_speed_test_littlefs_run(size_t repeat_count)
{
run_fs_tests(FLASH_BASE_PATH, "SPI LittleFS", true, repeat_count);
}
void sdcard_speed_test_fatfs_run(size_t repeat_count)
{
run_fs_tests(SD_BASE_PATH, "SD FATFS", true, repeat_count);
run_fs_tests(SD_BASE_PATH, "SD FATFS", false, repeat_count);
}
void sdcard_speed_test_littlefs_run(size_t repeat_count)
{
run_fs_tests(SD_BASE_PATH, "SD LittleFS", true, repeat_count);
run_fs_tests(SD_BASE_PATH, "SD LittleFS", false, repeat_count);
}
void sdcard_speed_test_raw_run(sdmmc_card_t *card, size_t repeat_count)
{
uint32_t sector_size = card->csd.sector_size;
size_t sector_count = CONFIG_EXAMPLE_TARGET_RW_SIZE / sector_size;
size_t subsection_sector_count = sector_count / 4;
char *buf = (char *) calloc(1, sector_count * sector_size);
assert(buf != NULL);
struct timeval tv_start;
struct timeval tv_end;
struct timeval tv_diff;
for(int i = 0; i < 4; i++) {
const size_t count = subsection_sector_count * (i + 1);
double time = 0;
for (int i = 0; i < repeat_count; ++i) {
gettimeofday(&tv_start, NULL);
ESP_ERROR_CHECK(sdmmc_write_sectors(card, buf, 0, sector_count));
gettimeofday(&tv_end, NULL);
timersub(&tv_end, &tv_start, &tv_diff);
time += (tv_diff.tv_sec * 1000000 + tv_diff.tv_usec);
}
print_results("SD raw write", time, count * sector_size, repeat_count);
time = 0;
for (int i = 0; i < repeat_count; ++i) {
gettimeofday(&tv_start, NULL);
ESP_ERROR_CHECK(sdmmc_read_sectors(card, buf, 0, sector_count));
gettimeofday(&tv_end, NULL);
timersub(&tv_end, &tv_start, &tv_diff);
time += (tv_diff.tv_sec * 1000000 + tv_diff.tv_usec);
}
print_results("SD raw read", time, count * sector_size, repeat_count);
}
free(buf);
}

Wyświetl plik

@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Unlicense OR CC0-1.0 * SPDX-License-Identifier: Unlicense OR CC0-1.0
*/ */
@ -15,11 +15,16 @@
#include "driver/sdmmc_types.h" #include "driver/sdmmc_types.h"
#include "wear_levelling.h" #include "wear_levelling.h"
#include <stddef.h>
#define FLASH_BASE_PATH "/spiflash" #define FLASH_BASE_PATH "/spiflash"
#define SD_BASE_PATH "/sdcard" #define SD_BASE_PATH "/sdcard"
extern wl_handle_t s_wl_handle; extern wl_handle_t s_wl_handle;
void spiflash_speed_test_raw_run(void); void spiflash_speed_test_raw_run(size_t rounds);
void spiflash_speed_test_fs_run(void); void spiflash_speed_test_spiffs_run(size_t rounds);
void sdcard_speed_test_raw_run(sdmmc_card_t *card); void spiflash_speed_test_fatfs_run(size_t rounds);
void sdcard_speed_test_fatfs_run(void); void spiflash_speed_test_littlefs_run(size_t rounds);
void sdcard_speed_test_raw_run(sdmmc_card_t *card, size_t rounds);
void sdcard_speed_test_fatfs_run(size_t rounds);
void sdcard_speed_test_littlefs_run(size_t rounds);

Wyświetl plik

@ -1,254 +0,0 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
/* This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <sys/unistd.h>
#include <sys/stat.h>
#include <sys/time.h>
#include "esp_random.h"
#include "driver/sdmmc_types.h"
#include "sdmmc_cmd.h"
#include "wear_levelling.h"
#include "sdkconfig.h"
#include "tests.h"
static const char *TAG = "example_tests";
void spiflash_speed_test_raw_run(void);
void spiflash_speed_test_fs_run(void);
void sdcard_speed_test_raw_run(sdmmc_card_t *card);
void sdcard_speed_test_fatfs_run(void);
static void print_bench_output(struct timeval tv_start, struct timeval tv_end, size_t size, size_t start_offset, bool is_write)
{
bool use_megabytes;
#ifdef CONFIG_EXAMPLE_USE_MEGABYTES
use_megabytes = true;
#else
use_megabytes = false;
#endif // CONFIG_EXAMPLE_USE_MEGABYTES
float t_s = tv_end.tv_sec - tv_start.tv_sec + 1e-6f * (tv_end.tv_usec - tv_start.tv_usec);
double io_speed = size / (1024.0f * 1024.0f * t_s);
printf("%s %d bytes in %.3fms (%.3f%s) %s address %u\n",
(is_write)?"Wrote":"Read", size, t_s * 1e3, (use_megabytes)?io_speed:io_speed*8.0,
(use_megabytes)?"MiB/s":"Mib/s", (is_write)?"to":"from", start_offset);
}
static void test_rw_raw_spiflash_speed(wl_handle_t handle, size_t src_dest_addr, void *src_dest_buff, size_t size, bool is_write)
{
struct timeval tv_start;
gettimeofday(&tv_start, NULL);
if (is_write) {
wl_write(handle, src_dest_addr, src_dest_buff, size);
} else {
wl_read(handle, src_dest_addr, src_dest_buff, size);
}
struct timeval tv_end;
gettimeofday(&tv_end, NULL);
print_bench_output(tv_start, tv_end, size, src_dest_addr, is_write);
}
static void test_rw_raw_sd_speed(sdmmc_card_t *card, char* buf, uint32_t start_sector, size_t sector_count, size_t sector_size, bool is_write)
{
int file_size = sector_count * sector_size;
struct timeval tv_start;
gettimeofday(&tv_start, NULL);
if (is_write) {
ESP_ERROR_CHECK(sdmmc_write_sectors(card, buf, start_sector, sector_count));
} else {
ESP_ERROR_CHECK(sdmmc_read_sectors(card, buf, start_sector, sector_count));
}
struct timeval tv_end;
gettimeofday(&tv_end, NULL);
print_bench_output(tv_start, tv_end, file_size, start_sector, is_write);
}
static void test_rw_fs_speed(const char* filename, void* buf, size_t buf_size, size_t file_size, bool is_write)
{
bool use_megabytes;
#ifdef CONFIG_EXAMPLE_USE_MEGABYTES
use_megabytes = true;
#else
use_megabytes = false;
#endif // CONFIG_EXAMPLE_USE_MEGABYTES
const size_t buf_count = file_size / buf_size;
FILE* f = fopen(filename, (is_write) ? "wb" : "rb");
struct timeval tv_start;
gettimeofday(&tv_start, NULL);
for (size_t n = 0; n < buf_count; ++n) {
if (is_write) {
write(fileno(f), buf, buf_size);
} else {
if (read(fileno(f), buf, buf_size) != buf_size) {
printf("reading at n=%d, eof=%d", n, feof(f));
}
}
}
struct timeval tv_end;
gettimeofday(&tv_end, NULL);
fclose(f);
float t_s = tv_end.tv_sec - tv_start.tv_sec + 1e-6f * (tv_end.tv_usec - tv_start.tv_usec);
double io_speed = file_size / (1024.0f * 1024.0f * t_s);
printf("%s %d bytes (buffer size %dB) in %.3fms (%.3f%s)\n",
(is_write)?"Wrote":"Read", file_size, buf_size, t_s * 1e3,
(use_megabytes)?io_speed:io_speed*8.0, (use_megabytes)?"MiB/s":"Mib/s");
}
void spiflash_speed_test_raw_run(void)
{
const size_t buf_size = 16 * 1024;
uint32_t* buf = (uint32_t*) calloc(1, buf_size);
esp_fill_random(buf, buf_size);
size_t file_size;
ESP_LOGI(TAG, "Test with 128kiB file");
file_size = 128 * 1024;
test_rw_raw_spiflash_speed(s_wl_handle, 0, buf, file_size, true);
free(buf);
}
static void spiflash_speed_test(void *buf, size_t buf_size, size_t file_size, bool write)
{
test_rw_fs_speed(FLASH_BASE_PATH"/test.bin", buf, buf_size, file_size, write);
}
void spiflash_speed_test_fs_run(void)
{
const size_t buf_size = 16 * 1024;
uint32_t* buf = (uint32_t*) calloc(1, buf_size);
esp_fill_random(buf, buf_size);
size_t file_size;
ESP_LOGI(TAG, "Test with 128kiB file");
file_size = 128 * 1024;
// Write
spiflash_speed_test(buf, 4 * 1024, file_size, true);
spiflash_speed_test(buf, 8 * 1024, file_size, true);
spiflash_speed_test(buf, 16 * 1024, file_size, true);
// Read
spiflash_speed_test(buf, 4 * 1024, file_size, false);
spiflash_speed_test(buf, 8 * 1024, file_size, false);
spiflash_speed_test(buf, 16 * 1024, file_size, false);
ESP_LOGI(TAG, "Test with 256kiB file");
file_size *= 2;
// Write
spiflash_speed_test(buf, 4 * 1024, file_size, true);
spiflash_speed_test(buf, 8 * 1024, file_size, true);
spiflash_speed_test(buf, 16 * 1024, file_size, true);
// Read
spiflash_speed_test(buf, 4 * 1024, file_size, false);
spiflash_speed_test(buf, 8 * 1024, file_size, false);
spiflash_speed_test(buf, 16 * 1024, file_size, false);
ESP_LOGI(TAG, "Test with 512kiB file");
file_size *= 2;
// Write
spiflash_speed_test(buf, 4 * 1024, file_size, true);
spiflash_speed_test(buf, 8 * 1024, file_size, true);
spiflash_speed_test(buf, 16 * 1024, file_size, true);
// Read
spiflash_speed_test(buf, 4 * 1024, file_size, false);
spiflash_speed_test(buf, 8 * 1024, file_size, false);
spiflash_speed_test(buf, 16 * 1024, file_size, false);
free(buf);
}
static void sd_speed_test(void *buf, size_t buf_size, size_t file_size, bool write)
{
test_rw_fs_speed(SD_BASE_PATH"/test.bin", buf, buf_size, file_size, write);
}
void sdcard_speed_test_fatfs_run(void)
{
const size_t buf_size = 32 * 1024;
uint32_t* buf = (uint32_t*) calloc(1, buf_size);
esp_fill_random(buf, buf_size);
size_t file_size;
ESP_LOGI(TAG, "Test with 1MiB file");
file_size = 1 * 1024 * 1024;
// Write
sd_speed_test(buf, 4 * 1024, file_size, true);
sd_speed_test(buf, 8 * 1024, file_size, true);
sd_speed_test(buf, 16 * 1024, file_size, true);
sd_speed_test(buf, 32 * 1024, file_size, true);
// Read
sd_speed_test(buf, 4 * 1024, file_size, false);
sd_speed_test(buf, 8 * 1024, file_size, false);
sd_speed_test(buf, 16 * 1024, file_size, false);
sd_speed_test(buf, 32 * 1024, file_size, false);
ESP_LOGI(TAG, "Test with 4MiB file");
file_size = 4 * 1024 * 1024;
// Write
sd_speed_test(buf, 4 * 1024, file_size, true);
sd_speed_test(buf, 8 * 1024, file_size, true);
sd_speed_test(buf, 16 * 1024, file_size, true);
sd_speed_test(buf, 32 * 1024, file_size, true);
// Read
sd_speed_test(buf, 4 * 1024, file_size, false);
sd_speed_test(buf, 8 * 1024, file_size, false);
sd_speed_test(buf, 16 * 1024, file_size, false);
sd_speed_test(buf, 32 * 1024, file_size, false);
ESP_LOGI(TAG, "Test with 16MiB file");
file_size = 16 * 1024 * 1024;
// Write
sd_speed_test(buf, 4 * 1024, file_size, true);
sd_speed_test(buf, 8 * 1024, file_size, true);
sd_speed_test(buf, 16 * 1024, file_size, true);
sd_speed_test(buf, 32 * 1024, file_size, true);
// Read
sd_speed_test(buf, 4 * 1024, file_size, false);
sd_speed_test(buf, 8 * 1024, file_size, false);
sd_speed_test(buf, 16 * 1024, file_size, false);
sd_speed_test(buf, 32 * 1024, file_size, false);
free(buf);
}
static uint32_t sd_random_start_sector(uint32_t sector_size)
{
// Should be a little less than maximum number of sectors on a 512 MiB card
// (512 Mib - 64 MiB) / sector_size (most probably 512)
uint32_t upper_bound = (536870912 - 67108864) / sector_size;
return (esp_random() % (upper_bound + 1));
}
void sdcard_speed_test_raw_run(sdmmc_card_t *card)
{
size_t sector_count = 128;
uint32_t sector_size = card->csd.sector_size;
char *buf = (char *) calloc(1, sector_count * sector_size);
assert(buf != NULL);
uint32_t start_sector[3] = {sd_random_start_sector(sector_size), sd_random_start_sector(sector_size), sd_random_start_sector(sector_size)};
for(uint8_t i = 0; i < 3; i++) {
test_rw_raw_sd_speed(card, buf, start_sector[i], sector_count*(i+1), sector_size, true);
test_rw_raw_sd_speed(card, buf, start_sector[i], sector_count*(i+1), sector_size, false);
}
free(buf);
}

Wyświetl plik

@ -3,4 +3,4 @@
nvs, data, nvs, 0x9000, 0x6000, nvs, data, nvs, 0x9000, 0x6000,
phy_init, data, phy, 0xf000, 0x1000, phy_init, data, phy, 0xf000, 0x1000,
factory, app, factory, 0x10000, 1M, factory, app, factory, 0x10000, 1M,
storage, data, undefined, , 0xF0000, storage, data, undefined, , 2M,

1 # Name, Type, SubType, Offset, Size, Flags
3 nvs, data, nvs, 0x9000, 0x6000,
4 phy_init, data, phy, 0xf000, 0x1000,
5 factory, app, factory, 0x10000, 1M,
6 storage, data, undefined, , 0xF0000, storage, data, undefined, , 2M,

Wyświetl plik

@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD # SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Unlicense OR CC0-1.0 # SPDX-License-Identifier: Unlicense OR CC0-1.0
import pytest import pytest
from pytest_embedded import Dut from pytest_embedded import Dut
@ -19,14 +19,15 @@ def test_examples_perf_benchmark_spiflash(dut: Dut) -> None:
dut.expect('example: WL layer mounted', timeout=90) dut.expect('example: WL layer mounted', timeout=90)
dut.expect('example: WL layer unmounted', timeout=240) # SPI flash has slow write speed dut.expect('example: WL layer unmounted', timeout=240) # SPI flash has slow write speed
dut.expect('example: Mounting FATFS partition...', timeout=10)
dut.expect('example: FATFS mounted to', timeout=90) # Increased timeout due to formatting dut.expect('example: FATFS mounted to', timeout=90) # Increased timeout due to formatting
dut.expect('example: FATFS partition unmounted', timeout=240) # SPI flash has slow write speed dut.expect('example: FATFS partition unmounted', timeout=240) # SPI flash has slow write speed
dut.expect('example: Mounting SPIFFS partition...', timeout=10)
dut.expect('example: SPIFFS mounted to', timeout=90) # Increased timeout due to formatting dut.expect('example: SPIFFS mounted to', timeout=90) # Increased timeout due to formatting
dut.expect('example: SPIFFS partition unmounted', timeout=240) # SPI flash has slow write speed dut.expect('example: SPIFFS partition unmounted', timeout=240) # SPI flash has slow write speed
dut.expect('example: LittleFS mounted to', timeout=90) # Increased timeout due to formatting
dut.expect('example: LittleFS partition unmounted', timeout=240) # SPI flash has slow write speed
@pytest.mark.esp32 @pytest.mark.esp32
@pytest.mark.sdcard_sdmode @pytest.mark.sdcard_sdmode
@ -41,13 +42,15 @@ def test_examples_perf_benchmark_spiflash(dut: Dut) -> None:
def test_examples_perf_benchmark_sdcard_sdmmc(dut: Dut) -> None: def test_examples_perf_benchmark_sdcard_sdmmc(dut: Dut) -> None:
# SD card # SD card
dut.expect('example: Mounting SD card - raw access', timeout=10) dut.expect('example: Mounting SD card - raw access', timeout=10)
dut.expect('example: SD card mounted - raw access', timeout=10) dut.expect('sd_utils: SD card mounted - raw access', timeout=10)
dut.expect('example: SD card unmounted - raw access', timeout=60) dut.expect('example: SD card unmounted - raw access', timeout=60)
dut.expect('example: Mounting SD card - FATFS', timeout=30)
dut.expect('example: SD card mounted - FATFS', timeout=120) # Increased timeout due to formatting dut.expect('example: SD card mounted - FATFS', timeout=120) # Increased timeout due to formatting
dut.expect('example: SD card unmounted - FATFS', timeout=180) dut.expect('example: SD card unmounted - FATFS', timeout=180)
dut.expect('example: SD card mounted - LittleFS', timeout=120) # Increased timeout due to formatting
dut.expect('example: SD card unmounted - LittleFS', timeout=180)
@pytest.mark.esp32 @pytest.mark.esp32
@pytest.mark.temp_skip_ci(targets=['esp32'], reason='IDFCI-2059, temporary lack runner') @pytest.mark.temp_skip_ci(targets=['esp32'], reason='IDFCI-2059, temporary lack runner')
@ -64,9 +67,11 @@ def test_examples_perf_benchmark_sdcard_sdmmc(dut: Dut) -> None:
def test_examples_perf_benchmark_sdcard_spi(dut: Dut) -> None: def test_examples_perf_benchmark_sdcard_spi(dut: Dut) -> None:
# SD card # SD card
dut.expect('example: Mounting SD card - raw access', timeout=10) dut.expect('example: Mounting SD card - raw access', timeout=10)
dut.expect('example: SD card mounted - raw access', timeout=10) dut.expect('sd_utils: SD card mounted - raw access', timeout=10)
dut.expect('example: SD card unmounted - raw access', timeout=180) dut.expect('example: SD card unmounted - raw access', timeout=180)
dut.expect('example: Mounting SD card - FATFS', timeout=30)
dut.expect('example: SD card mounted - FATFS', timeout=120) # Increased timeout due to formatting dut.expect('example: SD card mounted - FATFS', timeout=120) # Increased timeout due to formatting
dut.expect('example: SD card unmounted - FATFS', timeout=180) dut.expect('example: SD card unmounted - FATFS', timeout=180)
dut.expect('example: SD card mounted - LittleFS', timeout=120) # Increased timeout due to formatting
dut.expect('example: SD card unmounted - LittleFS', timeout=180)

Wyświetl plik

@ -6,9 +6,13 @@ CONFIG_ESP_TASK_WDT_EN=n
# FATFS # FATFS
CONFIG_FATFS_VFS_FSTAT_BLKSIZE=4096 CONFIG_FATFS_VFS_FSTAT_BLKSIZE=4096
# LittleFS
CONFIG_LITTLEFS_SDMMC_SUPPORT=y
# SPI flash # SPI flash
CONFIG_ESPTOOLPY_FLASHMODE_QIO=y CONFIG_ESPTOOLPY_FLASHMODE_QIO=y
CONFIG_ESPTOOLPY_FLASHMODE="qio" CONFIG_ESPTOOLPY_FLASHMODE="qio"
CONFIG_ESPTOOLPY_FLASHFREQ_80M=y CONFIG_ESPTOOLPY_FLASHFREQ_80M=y
CONFIG_ESPTOOLPY_FLASHFREQ_80M_DEFAULT=y CONFIG_ESPTOOLPY_FLASHFREQ_80M_DEFAULT=y
CONFIG_ESPTOOLPY_FLASHFREQ="80m" CONFIG_ESPTOOLPY_FLASHFREQ="80m"
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y