From 16915556a3304f634651aa677a2e89d4d4f7ab5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20M=C3=BAdry?= Date: Tue, 28 Feb 2023 01:50:31 +0100 Subject: [PATCH] fatfs: fstat - enable setting a custom preferred block size Enables setting a custom st_blksize in fatfs vfs fstat function. Directly affects file buffer size for fatfs. Increasing the value helps with fread and fgets speeds, however increases heap usage. Added info to docs about improving I/O performance. --- components/fatfs/Kconfig | 14 ++++++++++++++ components/fatfs/vfs/vfs_fat.c | 1 + docs/en/api-guides/performance/speed.rst | 17 +++++++++++++++++ examples/storage/sd_card/sdmmc/sdkconfig.ci | 1 + .../storage/sd_card/sdmmc/sdkconfig.defaults | 1 + 5 files changed, 34 insertions(+) create mode 100644 examples/storage/sd_card/sdmmc/sdkconfig.defaults diff --git a/components/fatfs/Kconfig b/components/fatfs/Kconfig index 826d1dcaf0..3d62a06b42 100644 --- a/components/fatfs/Kconfig +++ b/components/fatfs/Kconfig @@ -216,4 +216,18 @@ menu "FAT Filesystem support" This value should be chosen based on prior knowledge of maximum elements of each file entry would store. + config FATFS_VFS_FSTAT_BLKSIZE + int "Default block size" + default 0 + help + If set to 0, the 'newlib' library's default size (BLKSIZ) is used (128 B). + If set to a non-zero value, the value is used as the block size. + Default file buffer size is set to this value + and the buffer is allocated when first attempt of reading/writing to a file is made. + Increasing this value improves fread() speed, however the heap usage is increased as well. + + NOTE: The block size value is shared by all the filesystem functions + accessing target media for given file descriptor! + See 'Improving I/O performance' section of 'Maximizing Execution Speed' documentation page + for more details. endmenu diff --git a/components/fatfs/vfs/vfs_fat.c b/components/fatfs/vfs/vfs_fat.c index aea07f2da2..6cfd1145c0 100644 --- a/components/fatfs/vfs/vfs_fat.c +++ b/components/fatfs/vfs/vfs_fat.c @@ -600,6 +600,7 @@ static int vfs_fat_fstat(void* ctx, int fd, struct stat * st) st->st_mtime = 0; st->st_atime = 0; st->st_ctime = 0; + st->st_blksize = CONFIG_FATFS_VFS_FSTAT_BLKSIZE; return 0; } diff --git a/docs/en/api-guides/performance/speed.rst b/docs/en/api-guides/performance/speed.rst index b90782c5f0..bb1874024d 100644 --- a/docs/en/api-guides/performance/speed.rst +++ b/docs/en/api-guides/performance/speed.rst @@ -240,3 +240,20 @@ Improving Network Speed :SOC_WIFI_SUPPORTED: * For Wi-Fi, see :ref:`How-to-improve-Wi-Fi-performance` and :ref:`wifi-buffer-usage` * For lwIP TCP/IP (Wi-Fi and Ethernet), see :ref:`lwip-performance` :SOC_WIFI_SUPPORTED: * The :example:`wifi/iperf` example contains a configuration that is heavily optimized for Wi-Fi TCP/IP throughput. Append the contents of the files :example_file:`wifi/iperf/sdkconfig.defaults`, :example_file:`wifi/iperf/sdkconfig.defaults.{IDF_TARGET_PATH_NAME}` and :example_file:`wifi/iperf/sdkconfig.ci.99` to your project ``sdkconfig`` file in order to add all of these options. Note that some of these options may have trade-offs in terms of reduced debuggability, increased firmware size, increased memory usage, or reduced performance of other features. To get the best result, read the documentation pages linked above and use this information to determine exactly which options are best suited for your app. + +Improving I/O performance +------------------------- + +Using standard C library functions like ``fread`` and ``fwrite`` instead of platform specific unbuffered syscalls such as ``read`` and ``write`` can be slow. +These functions are designed to be portable, so they are not necessarily optimized for speed, have a certain overhead and are buffered. + +:doc:`FatFS ` specific information and tips: + +.. list:: + + - Maximum size of the R/W request == FatFS cluster size (allocation unit size) + - Use ``read`` and ``write`` instead of ``fread`` and ``fwrite`` + - To increase speed of buffered reading functions like ``fread`` and ``fgets``, you can increase a size of the file buffer (Newlib's default is 128 bytes) to a higher number like 4096, 8192 or 16384. This can be done locally via ``setvbuf`` function used on a certain file pointer or globally applied to all files via modifying :ref:`CONFIG_FATFS_VFS_FSTAT_BLKSIZE`. + + .. note:: + Setting a bigger buffer size will also increase the heap memory usage. \ No newline at end of file diff --git a/examples/storage/sd_card/sdmmc/sdkconfig.ci b/examples/storage/sd_card/sdmmc/sdkconfig.ci index 7847e636ee..21cf9cd2a0 100644 --- a/examples/storage/sd_card/sdmmc/sdkconfig.ci +++ b/examples/storage/sd_card/sdmmc/sdkconfig.ci @@ -1 +1,2 @@ CONFIG_EXAMPLE_FORMAT_IF_MOUNT_FAILED=y +CONFIG_FATFS_VFS_FSTAT_BLKSIZE=4096 diff --git a/examples/storage/sd_card/sdmmc/sdkconfig.defaults b/examples/storage/sd_card/sdmmc/sdkconfig.defaults new file mode 100644 index 0000000000..88020f762a --- /dev/null +++ b/examples/storage/sd_card/sdmmc/sdkconfig.defaults @@ -0,0 +1 @@ +CONFIG_FATFS_VFS_FSTAT_BLKSIZE=4096