feat(storage/fatfs): Allow fatfs buffers to be aligned for DMA access

This commit is contained in:
Tomáš Rohlínek
2026-01-08 14:33:35 +01:00
committed by Tomas Rohlinek
parent dfa654c7cf
commit 96f820e535
3 changed files with 36 additions and 9 deletions
+10
View File
@@ -194,6 +194,16 @@ menu "FAT Filesystem support"
Disable this option if optimizing for performance. Enable this option if
optimizing for internal memory size.
config FATFS_ALLOC_PREFER_ALIGNED_WORK_BUFFERS
bool "Prefer aligned, DMA capable RAM when allocating FATFS buffers"
default y if SOC_SDMMC_HOST_SUPPORTED
default n
help
Tries to allocate FATFS heap buffers in a way they can be used directly by the SDMMC driver without
extra copies when DMA is enabled (for example when using PSRAM on ESP32-P4).
Disable this if you need the absolute minimum heap overhead and do not use SDMMC.
This option can be combined with CONFIG_FATFS_ALLOC_PREFER_EXTRAM,
in which case, the following order is tried: DMA capable RAM, external RAM, internal RAM.
config FATFS_USE_FASTSEEK
bool "Enable fast seek algorithm when using lseek function through VFS FAT"
+25 -9
View File
@@ -7,9 +7,7 @@
#include <stdlib.h>
#include "ff.h"
#include "sdkconfig.h"
#ifdef CONFIG_FATFS_ALLOC_PREFER_EXTRAM
#include "esp_heap_caps.h"
#endif
/*------------------------------------------------------------------------*/
/* Allocate/Free a Memory Block */
@@ -19,14 +17,32 @@ void* ff_memalloc ( /* Returns pointer to the allocated memory block (null if
unsigned msize /* Number of bytes to allocate */
)
{
#ifdef CONFIG_FATFS_ALLOC_PREFER_EXTRAM
return heap_caps_malloc_prefer(msize, 2, MALLOC_CAP_DEFAULT | MALLOC_CAP_SPIRAM,
MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL);
#else
return malloc(msize);
#endif
}
void *ptr = NULL;
(void) ptr;
#if CONFIG_FATFS_ALLOC_PREFER_EXTRAM && CONFIG_FATFS_ALLOC_PREFER_ALIGNED_WORK_BUFFERS
ptr = heap_caps_calloc_prefer(1, msize, 2, MALLOC_CAP_DMA | MALLOC_CAP_CACHE_ALIGNED | MALLOC_CAP_SPIRAM, MALLOC_CAP_CACHE_ALIGNED | MALLOC_CAP_SPIRAM);
if (ptr != NULL) {
return ptr;
}
#endif
#if CONFIG_FATFS_ALLOC_PREFER_ALIGNED_WORK_BUFFERS
ptr = heap_caps_calloc_prefer(1, msize, 2, MALLOC_CAP_DMA | MALLOC_CAP_CACHE_ALIGNED, MALLOC_CAP_CACHE_ALIGNED);
if (ptr != NULL) {
return ptr;
}
#endif
#if CONFIG_FATFS_ALLOC_PREFER_ALIGNED_WORK_BUFFERS
ptr = heap_caps_calloc(1, msize, MALLOC_CAP_SPIRAM);
if (ptr != NULL) {
return ptr;
}
#endif
return heap_caps_calloc(1, msize, MALLOC_CAP_DEFAULT);
}
void ff_memfree (
void* mblock /* Pointer to the memory block to free (no effect if null) */
+1
View File
@@ -71,6 +71,7 @@ Configuration options
The following configuration options are available for the FatFs component:
* :ref:`CONFIG_FATFS_ALLOC_PREFER_ALIGNED_WORK_BUFFERS` - If enabled, FatFs tries to allocate its heap work buffers in DMA-capable, cache-aligned memory first so SDMMC transfers can avoid extra copies. This is useful on targets using PSRAM with SDMMC DMA (for example ESP32-P4). If enabled together with :ref:`CONFIG_FATFS_ALLOC_PREFER_EXTRAM`, FatFs will try DMA-capable RAM first, then external RAM, then internal RAM.
* :ref:`CONFIG_FATFS_USE_FASTSEEK` - If enabled, the POSIX :cpp:func:`lseek` function will be performed faster. The fast seek does not work for files in write mode, so to take advantage of fast seek, you should open (or close and then reopen) the file in read-only mode.
* :ref:`CONFIG_FATFS_IMMEDIATE_FSYNC` - If enabled, the FatFs will automatically call :cpp:func:`f_sync` to flush recent file changes after each call of :cpp:func:`write`, :cpp:func:`pwrite`, :cpp:func:`link`, :cpp:func:`truncate` and :cpp:func:`ftruncate` functions. This feature improves file-consistency and size reporting accuracy for the FatFs, at a price of decreased performance due to frequent disk operations.
* :ref:`CONFIG_FATFS_LINK_LOCK` - If enabled, this option guarantees the API thread safety, while disabling this option might be necessary for applications that require fast frequent small file operations (e.g., logging to a file). Note that if this option is disabled, the copying performed by :cpp:func:`link` will be non-atomic. In such case, using :cpp:func:`link` on a large file on the same volume in a different task is not guaranteed to be thread safe.