fatfs: add option to prefer ext. RAM for internal buffers

This commit is contained in:
Ivan Grokhotkov 2018-11-29 01:08:59 +08:00
parent 073dbe6d1d
commit bbeb62547e
7 changed files with 56 additions and 14 deletions

View file

@ -167,6 +167,17 @@ config FATFS_PER_FILE_CACHE
all open files, size is also equal to _MAX_SS variable. This reduces the
amount of heap used when multiple files are open, but increases the number
of read and write operations which FATFS needs to make.
config FATFS_ALLOC_PREFER_EXTRAM
bool "Perfer external RAM when allocating FATFS buffers"
default y
depends on SPIRAM_USE_CAPS_ALLOC || SPIRAM_USE_MALLOC
help
When the option is enabled, internal buffers used by FATFS will be allocated
from external RAM. If the allocation from external RAM fails, the buffer will
be allocated from the internal RAM.
Disable this option if optimizing for performance. Enable this option if
optimizing for internal memory size.
endmenu

View file

@ -301,4 +301,11 @@
#include "freertos/FreeRTOS.h"
#include "freertos/semphr.h"
/* Some memory allocation functions are declared here in addition to ff.h, so that
they can be used also by external code when LFN feature is disabled.
*/
void* ff_memalloc (UINT msize);
void* ff_memcalloc (UINT num, UINT size);
/*--- End of configuration options ---*/

View file

@ -4,12 +4,15 @@
/*------------------------------------------------------------------------*/
#include <string.h>
#include "ff.h"
#include "sdkconfig.h"
#ifdef CONFIG_FATFS_ALLOC_EXTRAM_FIRST
#include "esp_heap_caps.h"
#endif
#if FF_USE_LFN == 3 /* Dynamic memory allocation */
/*------------------------------------------------------------------------*/
/* Allocate a memory block */
/*------------------------------------------------------------------------*/
@ -18,7 +21,27 @@ void* ff_memalloc ( /* Returns pointer to the allocated memory block (null on no
UINT msize /* Number of bytes to allocate */
)
{
return malloc(msize); /* Allocate a new memory block with POSIX API */
#ifdef CONFIG_FATFS_ALLOC_EXTRAM_FIRST
return heap_caps_malloc_prefer(size, 2, MALLOC_CAP_DEFAULT | MALLOC_CAP_SPIRAM,
MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL);
#else
return malloc(msize);
#endif
}
/*------------------------------------------------------------------------*/
/* Allocate and zero out memory block */
/*------------------------------------------------------------------------*/
void* ff_memcalloc (UINT num, UINT size)
{
#ifdef CONFIG_FATFS_ALLOC_EXTRAM_FIRST
return heap_caps_calloc_prefer(num, size, 2, MALLOC_CAP_DEFAULT | MALLOC_CAP_SPIRAM,
MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL);
#else
return calloc(num, size);
#endif
}
@ -33,7 +56,6 @@ void ff_memfree (
free(mblock); /* Free the memory block with POSIX API */
}
#endif

View file

@ -150,11 +150,11 @@ esp_err_t esp_vfs_fat_register(const char* base_path, const char* fat_drive, siz
.utime_p = &vfs_fat_utime,
};
size_t ctx_size = sizeof(vfs_fat_ctx_t) + max_files * sizeof(FIL);
vfs_fat_ctx_t* fat_ctx = (vfs_fat_ctx_t*) calloc(1, ctx_size);
vfs_fat_ctx_t* fat_ctx = (vfs_fat_ctx_t*) ff_memcalloc(1, ctx_size);
if (fat_ctx == NULL) {
return ESP_ERR_NO_MEM;
}
fat_ctx->o_append = malloc(max_files * sizeof(bool));
fat_ctx->o_append = ff_memalloc(max_files * sizeof(bool));
if (fat_ctx->o_append == NULL) {
free(fat_ctx);
return ESP_ERR_NO_MEM;
@ -512,9 +512,9 @@ static int vfs_fat_link(void* ctx, const char* n1, const char* n2)
prepend_drive_to_path(fat_ctx, &n1, &n2);
const size_t copy_buf_size = fat_ctx->fs.csize;
FRESULT res;
FIL* pf1 = calloc(1, sizeof(FIL));
FIL* pf2 = calloc(1, sizeof(FIL));
void* buf = malloc(copy_buf_size);
FIL* pf1 = ff_memcalloc(1, sizeof(FIL));
FIL* pf2 = ff_memcalloc(1, sizeof(FIL));
void* buf = ff_memalloc(copy_buf_size);
if (buf == NULL || pf1 == NULL || pf2 == NULL) {
_lock_release(&fat_ctx->lock);
ESP_LOGD(TAG, "alloc failed, pf1=%p, pf2=%p, buf=%p", pf1, pf2, buf);
@ -591,7 +591,7 @@ static DIR* vfs_fat_opendir(void* ctx, const char* name)
vfs_fat_ctx_t* fat_ctx = (vfs_fat_ctx_t*) ctx;
_lock_acquire(&fat_ctx->lock);
prepend_drive_to_path(fat_ctx, &name, NULL);
vfs_fat_dir_t* fat_dir = calloc(1, sizeof(vfs_fat_dir_t));
vfs_fat_dir_t* fat_dir = ff_memcalloc(1, sizeof(vfs_fat_dir_t));
if (!fat_dir) {
_lock_release(&fat_ctx->lock);
errno = ENOMEM;
@ -766,7 +766,7 @@ static int vfs_fat_truncate(void* ctx, const char *path, off_t length)
_lock_acquire(&fat_ctx->lock);
prepend_drive_to_path(fat_ctx, &path, NULL);
file = (FIL*) calloc(1, sizeof(FIL));
file = (FIL*) ff_memcalloc(1, sizeof(FIL));
if (file == NULL) {
_lock_release(&fat_ctx->lock);
ESP_LOGD(TAG, "truncate alloc failed");

View file

@ -55,6 +55,7 @@ esp_err_t esp_vfs_fat_sdmmc_mount(const char* base_path,
return ESP_ERR_NO_MEM;
}
esp_err_t err = ESP_OK;
// not using ff_memalloc here, as allocation in internal RAM is preferred
s_card = malloc(sizeof(sdmmc_card_t));
if (s_card == NULL) {
err = ESP_ERR_NO_MEM;
@ -113,7 +114,7 @@ esp_err_t esp_vfs_fat_sdmmc_mount(const char* base_path,
goto fail;
}
ESP_LOGW(TAG, "partitioning card");
workbuf = malloc(workbuf_size);
workbuf = ff_memalloc(workbuf_size);
if (workbuf == NULL) {
err = ESP_ERR_NO_MEM;
goto fail;

View file

@ -80,7 +80,7 @@ esp_err_t esp_vfs_fat_spiflash_mount(const char* base_path,
result = ESP_FAIL;
goto fail;
}
workbuf = malloc(workbuf_size);
workbuf = ff_memalloc(workbuf_size);
if (workbuf == NULL) {
result = ESP_ERR_NO_MEM;
goto fail;

View file

@ -29,3 +29,4 @@ CONFIG_ADC2_DISABLE_DAC=n
CONFIG_WARN_WRITE_STRINGS=y
CONFIG_SPI_MASTER_IN_IRAM=y
CONFIG_SPIRAM_BANKSWITCH_ENABLE=n
CONFIG_FATFS_ALLOC_EXTRAM_FIRST=y