From bbeb62547e3df4e21f34eb49611f717f4384e69d Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Thu, 29 Nov 2018 01:08:59 +0800 Subject: [PATCH] fatfs: add option to prefer ext. RAM for internal buffers --- components/fatfs/Kconfig | 13 ++++++++++- components/fatfs/src/ffconf.h | 7 ++++++ components/fatfs/src/ffsystem.c | 30 +++++++++++++++++++++---- components/fatfs/src/vfs_fat.c | 14 ++++++------ components/fatfs/src/vfs_fat_sdmmc.c | 3 ++- components/fatfs/src/vfs_fat_spiflash.c | 2 +- tools/unit-test-app/sdkconfig.defaults | 1 + 7 files changed, 56 insertions(+), 14 deletions(-) diff --git a/components/fatfs/Kconfig b/components/fatfs/Kconfig index b708530c3..81e16019a 100644 --- a/components/fatfs/Kconfig +++ b/components/fatfs/Kconfig @@ -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 diff --git a/components/fatfs/src/ffconf.h b/components/fatfs/src/ffconf.h index bf0e1a8e9..9513b5160 100644 --- a/components/fatfs/src/ffconf.h +++ b/components/fatfs/src/ffconf.h @@ -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 ---*/ diff --git a/components/fatfs/src/ffsystem.c b/components/fatfs/src/ffsystem.c index 204ba6f14..ac0236518 100644 --- a/components/fatfs/src/ffsystem.c +++ b/components/fatfs/src/ffsystem.c @@ -4,12 +4,15 @@ /*------------------------------------------------------------------------*/ +#include #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 diff --git a/components/fatfs/src/vfs_fat.c b/components/fatfs/src/vfs_fat.c index 974e0651a..ea74c82ee 100644 --- a/components/fatfs/src/vfs_fat.c +++ b/components/fatfs/src/vfs_fat.c @@ -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"); diff --git a/components/fatfs/src/vfs_fat_sdmmc.c b/components/fatfs/src/vfs_fat_sdmmc.c index f31790e0f..b667aa19f 100644 --- a/components/fatfs/src/vfs_fat_sdmmc.c +++ b/components/fatfs/src/vfs_fat_sdmmc.c @@ -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; diff --git a/components/fatfs/src/vfs_fat_spiflash.c b/components/fatfs/src/vfs_fat_spiflash.c index 50bf9b4e1..9fbe95381 100644 --- a/components/fatfs/src/vfs_fat_spiflash.c +++ b/components/fatfs/src/vfs_fat_spiflash.c @@ -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; diff --git a/tools/unit-test-app/sdkconfig.defaults b/tools/unit-test-app/sdkconfig.defaults index 132255eff..65fdb2c0c 100644 --- a/tools/unit-test-app/sdkconfig.defaults +++ b/tools/unit-test-app/sdkconfig.defaults @@ -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