Merge branch 'feature/optimize_fatfs_on_sdmmc' into 'master'

feat(examples/storage): update perf benchmark example

Closes IDF-8420

See merge request espressif/esp-idf!27678
pull/13651/head
Tomas Rohlinek 2024-04-09 15:02:06 +08:00
commit f5d49570ee
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.
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
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.
### Note about SPIFFS
The test for SPIFFS is run only once, because SPIFFS has a problem with deleting files.
## How to use example
### 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:
- Set size of data to write
- Test internal SPI flash
- Raw access
- Raw access (through wear-leveling)
- FATFS
- Set cluster size
- SPIFFS
- LittleFS
- Test SD card
- Select SD card interface
@ -85,11 +124,24 @@ See [the document about pullup requirements](https://docs.espressif.com/projects
- SD card test configuration
- Raw access
- FATFS
- LittleFS
- Set SD card frequency
- Set GPIO pins
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 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
```
I (345) example: Start of the example
I (355) example: Internal flash test
I (355) example: Mountig WL layer...
I (415) example: WL layer mounted
I (505) example: Test with 128kiB file
Wrote 131072 bytes in 320.295ms (0.390MiB/s) to address 0
I (895) example: WL layer unmounted
I (895) example: Mounting FATFS partition...
W (895) vfs_fat_spiflash: f_mount failed (13)
I (895) vfs_fat_spiflash: Formatting FATFS partition, allocation unit size=16384
I (1105) vfs_fat_spiflash: Mounting again
I (1105) example: FATFS mounted to /spiflash
I (1205) example: Test with 128kiB file
Wrote 131072 bytes (buffer size 4096B) in 1295.988ms (0.096MiB/s)
Wrote 131072 bytes (buffer size 8192B) in 1277.569ms (0.098MiB/s)
Wrote 131072 bytes (buffer size 16384B) in 1439.405ms (0.087MiB/s)
Read 131072 bytes (buffer size 4096B) in 17.721ms (7.054MiB/s)
Read 131072 bytes (buffer size 8192B) in 16.945ms (7.377MiB/s)
Read 131072 bytes (buffer size 16384B) in 16.596ms (7.532MiB/s)
I (5705) example: Test with 256kiB file
Wrote 262144 bytes (buffer size 4096B) in 2529.380ms (0.099MiB/s)
Wrote 262144 bytes (buffer size 8192B) in 2867.352ms (0.087MiB/s)
Wrote 262144 bytes (buffer size 16384B) in 2879.113ms (0.087MiB/s)
Read 262144 bytes (buffer size 4096B) in 34.809ms (7.182MiB/s)
Read 262144 bytes (buffer size 8192B) in 33.315ms (7.504MiB/s)
Read 262144 bytes (buffer size 16384B) in 32.601ms (7.668MiB/s)
I (14535) example: Test with 512kiB file
Wrote 524288 bytes (buffer size 4096B) in 5119.009ms (0.098MiB/s)
Wrote 524288 bytes (buffer size 8192B) in 5897.010ms (0.085MiB/s)
Wrote 524288 bytes (buffer size 16384B) in 5888.743ms (0.085MiB/s)
Read 524288 bytes (buffer size 4096B) in 68.975ms (7.249MiB/s)
Read 524288 bytes (buffer size 8192B) in 66.063ms (7.569MiB/s)
Read 524288 bytes (buffer size 16384B) in 64.624ms (7.737MiB/s)
I (32295) example: FATFS partition unmounted
I (32295) example: Mounting SPIFFS partition...
W (32295) SPIFFS: mount failed, -10025. formatting...
I (38195) example: SPIFFS mounted to /spiflash
I (41555) example: Partition size: total: 896321, used: 0
I (41645) example: Test with 128kiB file
Wrote 131072 bytes (buffer size 4096B) in 819.950ms (0.152MiB/s)
Wrote 131072 bytes (buffer size 8192B) in 777.949ms (0.161MiB/s)
Wrote 131072 bytes (buffer size 16384B) in 751.682ms (0.166MiB/s)
Read 131072 bytes (buffer size 4096B) in 101.810ms (1.228MiB/s)
Read 131072 bytes (buffer size 8192B) in 99.518ms (1.256MiB/s)
Read 131072 bytes (buffer size 16384B) in 98.472ms (1.269MiB/s)
I (45335) example: Test with 256kiB file
Wrote 262144 bytes (buffer size 4096B) in 1650.525ms (0.151MiB/s)
Wrote 262144 bytes (buffer size 8192B) in 3220.004ms (0.078MiB/s)
Wrote 262144 bytes (buffer size 16384B) in 7139.803ms (0.035MiB/s)
Read 262144 bytes (buffer size 4096B) in 204.933ms (1.220MiB/s)
Read 262144 bytes (buffer size 8192B) in 200.330ms (1.248MiB/s)
Read 262144 bytes (buffer size 16384B) in 198.129ms (1.262MiB/s)
I (60365) example: Test with 512kiB file
Wrote 524288 bytes (buffer size 4096B) in 13917.135ms (0.036MiB/s)
Wrote 524288 bytes (buffer size 8192B) in 14302.046ms (0.035MiB/s)
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
I (302) main_task: Calling app_main()
I (302) example: Starting benchmark test with target size 65536 bytes
I (302) example: Internal flash test
I (302) example: Mountig WL layer...
I (622) example: WL layer mounted
[SPI Flash raw write ] (100x) 96.610 ms 64.00 kB 0.647 MB/s
[SPI Flash raw read ] (100x) 8.076 ms 64.00 kB 7.739 MB/s
I (11242) example: WL layer unmounted
I (11242) example: Mounting FATFS partition, with cluster size 65536 bytes
W (11242) vfs_fat_spiflash: f_mount failed (13)
I (11252) vfs_fat_spiflash: Formatting FATFS partition, allocation unit size=65536
I (11672) vfs_fat_spiflash: Mounting again
I (11672) example: FATFS mounted to /spiflash
[SPI FATFS (new file): write target size ] (100x) 1053.682 ms 64.00 kB 0.059 MB/s
[SPI FATFS (new file): read target size ] (100x) 8.124 ms 64.00 kB 7.694 MB/s
[SPI FATFS (new file): write more than target size ] (100x) 1259.972 ms 76.80 kB 0.060 MB/s
[SPI FATFS (new file): read more than target size ] (100x) 10.728 ms 76.80 kB 6.991 MB/s
[SPI FATFS (new file): write less than target size ] (100x) 850.835 ms 53.33 kB 0.061 MB/s
[SPI FATFS (new file): read less than target size ] (100x) 7.156 ms 53.33 kB 7.278 MB/s
[SPI FATFS (new file): write tiny size ] (100x) 1.180 ms 0.25 kB 0.206 MB/s
[SPI FATFS (new file): read tiny size ] (100x) 0.585 ms 0.25 kB 0.416 MB/s
I (510282) example: FATFS partition unmounted
I (510282) example: Mounting SPIFFS partition...
W (510282) SPIFFS: mount failed, -10025. formatting...
I (530862) example: SPIFFS mounted to /spiflash
[SPI SPIFFS (new file): write target size ] (1x) 464.198 ms 64.00 kB 0.135 MB/s
[SPI SPIFFS (new file): read target size ] (1x) 137.664 ms 64.00 kB 0.454 MB/s
[SPI SPIFFS (new file): write more than target size ] (1x) 555.745 ms 76.80 kB 0.135 MB/s
[SPI SPIFFS (new file): read more than target size ] (1x) 146.080 ms 76.80 kB 0.513 MB/s
[SPI SPIFFS (new file): write less than target size ] (1x) 390.201 ms 53.33 kB 0.133 MB/s
[SPI SPIFFS (new file): read less than target size ] (1x) 128.494 ms 53.33 kB 0.405 MB/s
[SPI SPIFFS (new file): write tiny size ] (1x) 0.050 ms 0.25 kB 4.864 MB/s
[SPI SPIFFS (new file): read tiny size ] (1x) 0.412 ms 0.25 kB 0.590 MB/s
I (534762) example: SPIFFS partition unmounted
I (534762) example: Mounting LittleFS partition...
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}
W (534782) esp_littlefs: mount failed, (-84). formatting...
I (534862) example: LittleFS mounted to /spiflash
[SPI LittleFS (new file): write target size ] (100x) 946.405 ms 64.00 kB 0.066 MB/s
[SPI LittleFS (new file): read target size ] (100x) 28.988 ms 64.00 kB 2.156 MB/s
[SPI LittleFS (new file): write more than target size ] (100x) 1176.518 ms 76.80 kB 0.064 MB/s
[SPI LittleFS (new file): read more than target size ] (100x) 39.843 ms 76.80 kB 1.882 MB/s
[SPI LittleFS (new file): write less than target size ] (100x) 821.555 ms 53.33 kB 0.063 MB/s
[SPI LittleFS (new file): read less than target size ] (100x) 25.848 ms 53.33 kB 2.015 MB/s
[SPI LittleFS (new file): write tiny size ] (100x) 0.043 ms 0.25 kB 5.635 MB/s
[SPI LittleFS (new file): read tiny size ] (100x) 0.036 ms 0.25 kB 6.685 MB/s
I (849202) example: LittleFS partition unmounted
I (849202) example: SD card test
I (849202) example: Initializing SD card
I (849212) sd_utils: Using SDMMC peripheral
I (849212) example: Mounting SD card - raw access
I (849222) gpio: GPIO[13]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0
I (849272) sd_utils: SD card mounted - raw access
Name: SD64G
Type: SDHC/SDXC
Speed: 40.00 MHz (limit: 40.00 MHz)
Size: 15080MB
CSD: ver=2, sector_size=512, capacity=30883840 read_bl_len=9
Size: 59640MB
CSD: ver=2, sector_size=512, capacity=122142720 read_bl_len=9
SSR: bus_width=4
Wrote 65536 bytes in 25.321ms (2.468MiB/s) to sector 415075
Read 65536 bytes in 3.809ms (16.409MiB/s) from sector 415075
Wrote 131072 bytes in 7.415ms (16.858MiB/s) to sector 823598
Read 131072 bytes in 7.149ms (17.485MiB/s) from sector 823598
Wrote 196608 bytes in 10.829ms (17.315MiB/s) to sector 180761
Read 196608 bytes in 10.539ms (17.791MiB/s) from sector 180761
I (109045) example: SD card unmounted - raw access
I (109045) example: Mounting SD card - FATFS
I (109045) gpio: GPIO[36]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0
I (109055) gpio: GPIO[35]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0
I (109065) gpio: GPIO[37]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0
I (109075) gpio: GPIO[38]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0
I (109085) gpio: GPIO[33]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0
I (109095) gpio: GPIO[34]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0
I (109145) gpio: GPIO[34]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0
W (109155) vfs_fat_sdmmc: failed to mount card (13)
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
[SD raw write ] (100x) 6.757 ms 16.00 kB 2.312 MB/s
[SD raw read ] (100x) 3.856 ms 16.00 kB 4.053 MB/s
[SD raw write ] (100x) 13.380 ms 32.00 kB 2.336 MB/s
[SD raw read ] (100x) 3.852 ms 32.00 kB 8.112 MB/s
[SD raw write ] (100x) 13.145 ms 48.00 kB 3.566 MB/s
[SD raw read ] (100x) 3.853 ms 48.00 kB 12.167 MB/s
[SD raw write ] (100x) 4.924 ms 64.00 kB 12.692 MB/s
[SD raw read ] (100x) 3.855 ms 64.00 kB 16.212 MB/s
I (854662) example: SD card unmounted - raw access
I (854662) example: Mounting SD card - FATFS, with cluster size 65536 bytes
I (854672) gpio: GPIO[13]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0
W (854722) vfs_fat_sdmmc: failed to mount card (13)
W (854722) vfs_fat_sdmmc: partitioning card
W (854722) vfs_fat_sdmmc: formatting card, allocation unit size=65536
W (857742) vfs_fat_sdmmc: mounting again
Name: SD64G
Type: SDHC/SDXC
Speed: 40.00 MHz (limit: 40.00 MHz)
Size: 15080MB
CSD: ver=2, sector_size=512, capacity=30883840 read_bl_len=9
Size: 59640MB
CSD: ver=2, sector_size=512, capacity=122142720 read_bl_len=9
SSR: bus_width=4
I (110535) example: SD card mounted - FATFS
I (110715) example: Test with 1MiB file
Wrote 1048576 bytes (buffer size 4096B) in 200.241ms (4.994MiB/s)
Wrote 1048576 bytes (buffer size 8192B) in 129.756ms (7.707MiB/s)
Wrote 1048576 bytes (buffer size 16384B) in 91.955ms (10.875MiB/s)
Wrote 1048576 bytes (buffer size 32768B) in 91.424ms (10.938MiB/s)
Read 1048576 bytes (buffer size 4096B) in 121.086ms (8.259MiB/s)
Read 1048576 bytes (buffer size 8192B) in 87.896ms (11.377MiB/s)
Read 1048576 bytes (buffer size 16384B) in 72.525ms (13.788MiB/s)
Read 1048576 bytes (buffer size 32768B) in 74.664ms (13.393MiB/s)
I (111655) example: Test with 4MiB file
Wrote 4194304 bytes (buffer size 4096B) in 797.167ms (5.018MiB/s)
Wrote 4194304 bytes (buffer size 8192B) in 533.538ms (7.497MiB/s)
Wrote 4194304 bytes (buffer size 16384B) in 530.830ms (7.535MiB/s)
Wrote 4194304 bytes (buffer size 32768B) in 497.953ms (8.033MiB/s)
Read 4194304 bytes (buffer size 4096B) in 473.495ms (8.448MiB/s)
Read 4194304 bytes (buffer size 8192B) in 351.240ms (11.388MiB/s)
Read 4194304 bytes (buffer size 16384B) in 289.767ms (13.804MiB/s)
Read 4194304 bytes (buffer size 32768B) in 287.260ms (13.925MiB/s)
I (115495) example: Test with 16MiB file
Wrote 16777216 bytes (buffer size 4096B) in 4754.141ms (3.365MiB/s)
Wrote 16777216 bytes (buffer size 8192B) in 2290.545ms (6.985MiB/s)
Wrote 16777216 bytes (buffer size 16384B) in 2088.811ms (7.660MiB/s)
Wrote 16777216 bytes (buffer size 32768B) in 2148.595ms (7.447MiB/s)
Read 16777216 bytes (buffer size 4096B) in 1899.620ms (8.423MiB/s)
Read 16777216 bytes (buffer size 8192B) in 1419.345ms (11.273MiB/s)
Read 16777216 bytes (buffer size 16384B) in 1158.909ms (13.806MiB/s)
Read 16777216 bytes (buffer size 32768B) in 1148.426ms (13.932MiB/s)
I (132515) example: SD card unmounted - FATFS
I (132515) example: End of the example
I (857742) example: SD card mounted - FATFS
[SD FATFS (new file): write target size ] (100x) 6.236 ms 64.00 kB 10.022 MB/s
[SD FATFS (new file): read target size ] (100x) 3.923 ms 64.00 kB 15.932 MB/s
[SD FATFS (new file): write more than target size ] (100x) 9.519 ms 76.80 kB 7.879 MB/s
[SD FATFS (new file): read more than target size ] (100x) 5.690 ms 76.80 kB 13.181 MB/s
[SD FATFS (new file): write less than target size ] (100x) 6.953 ms 53.33 kB 7.491 MB/s
[SD FATFS (new file): read less than target size ] (100x) 3.624 ms 53.33 kB 14.372 MB/s
[SD FATFS (new file): write tiny size ] (100x) 0.423 ms 0.25 kB 0.575 MB/s
[SD FATFS (new file): read tiny size ] (100x) 0.345 ms 0.25 kB 0.704 MB/s
[SD FATFS: write target size ] (100x) 5.186 ms 64.00 kB 12.051 MB/s
[SD FATFS: read target size ] (100x) 3.907 ms 64.00 kB 15.995 MB/s
[SD FATFS: write more than target size ] (100x) 136.273 ms 76.80 kB 0.550 MB/s
[SD FATFS: read more than target size ] (100x) 46.052 ms 76.80 kB 1.629 MB/s
[SD FATFS: write less than target size ] (100x) 105.132 ms 53.33 kB 0.495 MB/s
[SD FATFS: read less than target size ] (100x) 31.151 ms 53.33 kB 1.672 MB/s
[SD FATFS: write tiny size ] (100x) 0.456 ms 0.25 kB 0.533 MB/s
[SD FATFS: read tiny size ] (100x) 0.200 ms 0.25 kB 1.217 MB/s
I (899172) example: SD card unmounted - FATFS
I (899172) example: Mounting SD card - LittleFS
I (899182) gpio: GPIO[13]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0
I (899232) sd_utils: SD card mounted - raw access
Name: SD64G
Type: SDHC/SDXC
Speed: 40.00 MHz (limit: 40.00 MHz)
Size: 59640MB
CSD: ver=2, sector_size=512, capacity=122142720 read_bl_len=9
SSR: bus_width=4
I (899232) esp_littlefs: Using SD card handle 0x3ffd8880 for LittleFS mount
W (899242) esp_littlefs: SD card is too big (sector=512, count=122142720; total=62537072640 bytes), throttling to maximum possible 8388607 blocks
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

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 ".")

Wyświetl plik

@ -1,7 +1,27 @@
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
bool "Use megabytes instead of megabits"
config EXAMPLE_TEST_TRIES
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
help
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
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
bool "Test SPIFFS"
default y
help
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"
config EXAMPLE_TEST_SD_CARD
@ -74,6 +111,23 @@ menu "Performance Benchmark Example Configuration"
help
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
prompt "SD card frequency"
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
*/
@ -15,58 +15,37 @@
#include <stdio.h>
#include <stdbool.h>
#include <sys/time.h>
#include "esp_err.h"
#include "esp_log.h"
#include "esp_check.h"
#include "esp_partition.h"
#include "esp_vfs_fat.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 "esp_littlefs.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";
#ifdef CONFIG_EXAMPLE_TEST_SPIFLASH
static const char *flash_partition_label = "storage";
#endif // CONFIG_EXAMPLE_TEST_SPIFLASH
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_fatfs(void);
void test_spiflash_spiffs(void);
void test_spiflash_littlefs(void);
void test_sd_raw(void);
void test_sd_fatfs(void);
void test_sd_littlefs(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
ESP_LOGI(TAG, "Internal flash test");
@ -85,7 +64,12 @@ void app_main(void)
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
#ifdef CONFIG_EXAMPLE_TEST_SD_CARD
ESP_LOGI(TAG, "SD card test");
@ -102,9 +86,17 @@ void app_main(void)
test_sd_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
}
#if CONFIG_EXAMPLE_TEST_SPIFLASH
#ifdef CONFIG_EXAMPLE_TEST_SPIFLASH_RAW
void test_spiflash_raw(void)
{
esp_err_t ret = ESP_OK;
@ -122,21 +114,26 @@ void test_spiflash_raw(void)
}
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);
ESP_ERROR_CHECK(ret);
ESP_LOGI(TAG, "WL layer unmounted");
}
#endif // CONFIG_EXAMPLE_TEST_SPIFLASH_RAW
#ifdef CONFIG_EXAMPLE_TEST_SPIFLASH_FATFS
void test_spiflash_fatfs(void)
{
esp_err_t ret = ESP_OK;
ESP_LOGI(TAG, "Mounting FATFS partition...");
esp_vfs_fat_sdmmc_mount_config_t mount_config_spiflash = {
.format_if_mount_failed = true,
.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);
if (ret == ESP_OK) {
ESP_LOGI(TAG, "FATFS mounted to %s", FLASH_BASE_PATH);
@ -145,14 +142,16 @@ void test_spiflash_fatfs(void)
ESP_ERROR_CHECK(ret);
}
spiflash_speed_test_fs_run();
spiflash_speed_test_fatfs_run(CONFIG_EXAMPLE_TEST_TRIES);
// Unregister FATFS and unmount storage partition
ret = esp_vfs_fat_spiflash_unmount_rw_wl(FLASH_BASE_PATH, s_wl_handle);
ESP_ERROR_CHECK(ret);
ESP_LOGI(TAG, "FATFS partition unmounted");
}
#endif // CONFIG_EXAMPLE_TEST_SPIFLASH_FATFS
#ifdef CONFIG_EXAMPLE_TEST_SPIFLASH_SPIFFS
void test_spiflash_spiffs(void)
{
esp_err_t ret = ESP_OK;
@ -180,69 +179,85 @@ void test_spiflash_spiffs(void)
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
ret = esp_vfs_spiffs_unregister(conf.partition_label);
ESP_ERROR_CHECK(ret);
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)
{
esp_err_t ret = ESP_OK;
sdmmc_card_t *card;
ESP_LOGI(TAG, "Mounting SD card - raw access");
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();
ret = init_sd_card(&card);
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);
sdcard_speed_test_raw_run(card, CONFIG_EXAMPLE_TEST_TRIES);
sdcard_speed_test_raw_run(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);
deinit_sd_card(&card);
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)
{
esp_err_t ret = ESP_OK;
sdmmc_card_t *card;
ESP_LOGI(TAG, "Mounting SD card - FATFS");
esp_vfs_fat_sdmmc_mount_config_t mount_config_sdcard = {
.format_if_mount_failed = true,
.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
ret = esp_vfs_fat_sdmmc_mount(SD_BASE_PATH, &host_g, &slot_config_g, &mount_config_sdcard, &card);
#else // CONFIG_EXAMPLE_USE_SDMMC
@ -258,80 +273,52 @@ void test_sd_fatfs(void)
sdmmc_card_print_info(stdout, card);
ESP_LOGI(TAG, "SD card mounted - FATFS");
sdcard_speed_test_fatfs_run();
sdcard_speed_test_fatfs_run(CONFIG_EXAMPLE_TEST_TRIES);
// Unmount SD card
esp_vfs_fat_sdcard_unmount(SD_BASE_PATH, card);
ESP_LOGI(TAG, "SD card unmounted - FATFS");
}
#endif // CONFIG_EXAMPLE_TEST_SD_CARD_FATFS
#ifdef CONFIG_EXAMPLE_TEST_SD_CARD
#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
#ifdef CONFIG_EXAMPLE_TEST_SD_CARD_LITTLEFS
void test_sd_littlefs(void)
{
esp_err_t ret = ESP_OK;
sdmmc_card_t *card;
// 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;
ESP_LOGI(TAG, "Mounting SD card - LittleFS");
// 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);
ret = init_sd_card(&card);
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_vfs_littlefs_conf_t conf = {
.base_path = SD_BASE_PATH,
.sdcard = card,
.format_if_mount_failed = true,
};
ret = esp_vfs_littlefs_register(&conf);
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

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
*/
@ -15,11 +15,16 @@
#include "driver/sdmmc_types.h"
#include "wear_levelling.h"
#include <stddef.h>
#define FLASH_BASE_PATH "/spiflash"
#define SD_BASE_PATH "/sdcard"
extern wl_handle_t s_wl_handle;
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);
void spiflash_speed_test_raw_run(size_t rounds);
void spiflash_speed_test_spiffs_run(size_t rounds);
void spiflash_speed_test_fatfs_run(size_t rounds);
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,
phy_init, data, phy, 0xf000, 0x1000,
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
import pytest
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 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 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 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.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:
# SD card
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: 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 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.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:
# SD card
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: 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 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
CONFIG_FATFS_VFS_FSTAT_BLKSIZE=4096
# LittleFS
CONFIG_LITTLEFS_SDMMC_SUPPORT=y
# SPI flash
CONFIG_ESPTOOLPY_FLASHMODE_QIO=y
CONFIG_ESPTOOLPY_FLASHMODE="qio"
CONFIG_ESPTOOLPY_FLASHFREQ_80M=y
CONFIG_ESPTOOLPY_FLASHFREQ_80M_DEFAULT=y
CONFIG_ESPTOOLPY_FLASHFREQ="80m"
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y