Skip to content

Commit

Permalink
Merge pull request #159 from tonyjackson-srt/add_spiram_malloc_support
Browse files Browse the repository at this point in the history
Add CFLAG to select SPIRAM heap caps malloc
  • Loading branch information
BrianPugh authored Nov 30, 2023
2 parents b671069 + e63e049 commit 266017e
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 18 deletions.
8 changes: 8 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,11 @@ endif()
if(CONFIG_LITTLEFS_MULTIVERSION)
target_compile_definitions(${COMPONENT_LIB} PUBLIC -DLFS_MULTIVERSION)
endif()

if(CONFIG_LITTLEFS_MALLOC_STRATEGY_DISABLE)
target_compile_definitions(${COMPONENT_LIB} PUBLIC -DLFS_NO_MALLOC)
endif()

if(NOT CONFIG_LITTLEFS_ASSERTS)
target_compile_definitions(${COMPONENT_LIB} PUBLIC -DLFS_NO_ASSERT)
endif()
40 changes: 40 additions & 0 deletions Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -208,4 +208,44 @@ menu "LittleFS"
bool "Write LittleFS 2.0 (no forward-looking erase-state CRCs)"

endchoice

choice LITTLEFS_MALLOC_STRATEGY
prompt "Buffer allocation strategy"
default LITTLEFS_MALLOC_STRATEGY_DEFAULT
help
Maps lfs_malloc to ESP-IDF capabilities-based memory allocator or
disables dynamic allocation in favour of user-provided static buffers.

config LITTLEFS_MALLOC_STRATEGY_DISABLE
bool "Static buffers only"
help
Disallow dynamic allocation, static buffers must be provided by the calling application.

config LITTLEFS_MALLOC_STRATEGY_DEFAULT
bool "Default heap selection"
help
Uses an automatic allocation strategy. On systems with heap in SPIRAM, if
the allocation size does not exceed SPIRAM_MALLOC_ALWAYSINTERNAL then internal
heap allocation if preferred, otherwise allocation will be attempted from SPIRAM
heap.

config LITTLEFS_MALLOC_STRATEGY_INTERNAL
bool "Internal heap"
help
Uses ESP-IDF heap_caps_malloc to allocate from internal heap.

config LITTLEFS_MALLOC_STRATEGY_SPIRAM
bool "SPIRAM heap"
depends on SPIRAM_USE_MALLOC && ESP32_SPIRAM_SUPPORT
help
Uses ESP-IDF heap_caps_malloc to allocate from SPIRAM heap.

endchoice

config LITTLEFS_ASSERTS
bool "Enable asserts"
default "y"
help
Selects whether littlefs performs runtime assert checks.

endmenu
28 changes: 21 additions & 7 deletions src/esp_littlefs.c
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,16 @@ static esp_littlefs_t * _efs[CONFIG_LITTLEFS_MAX_PARTITIONS] = { 0 };
static const char * esp_littlefs_errno(enum lfs_error lfs_errno);
#endif

static inline void * esp_littlefs_calloc(size_t __nmemb, size_t __size) {
/* Used internally by this wrapper only */
#if defined(CONFIG_LITTLEFS_MALLOC_STRATEGY_INTERNAL)
return heap_caps_calloc(__nmemb, __size, MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL);
#elif defined(CONFIG_LITTLEFS_MALLOC_STRATEGY_SPIRAM)
return heap_caps_calloc(__nmemb, __size, MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM);
#else /* CONFIG_LITTLEFS_MALLOC_STRATEGY_DISABLE, CONFIG_LITTLEFS_MALLOC_STRATEGY_DEFAULT or not defined */
return calloc(__nmemb, __size);
#endif
}

static void esp_littlefs_free_fds(esp_littlefs_t * efs) {
/* Need to free all files that were opened */
Expand Down Expand Up @@ -239,7 +249,7 @@ esp_err_t format_from_efs(esp_littlefs_t *efs)
return ESP_FAIL;
}
efs->cache_size = CONFIG_LITTLEFS_FD_CACHE_MIN_SIZE; // Initial size of cache; will resize ondemand
efs->cache = calloc(sizeof(*efs->cache), efs->cache_size);
efs->cache = esp_littlefs_calloc(sizeof(*efs->cache), efs->cache_size);
}
ESP_LOGV(ESP_LITTLEFS_TAG, "Format Success!");

Expand Down Expand Up @@ -686,7 +696,7 @@ static void esp_littlefs_take_efs_lock(void) {
static esp_err_t esp_littlefs_init_efs(esp_littlefs_t** efs, const esp_partition_t* partition, bool read_only)
{
/* Allocate Context */
*efs = calloc(1, sizeof(esp_littlefs_t));
*efs = esp_littlefs_calloc(1, sizeof(esp_littlefs_t));
if (*efs == NULL) {
ESP_LOGE(ESP_LITTLEFS_TAG, "esp_littlefs could not be malloced");
return ESP_ERR_NO_MEM;
Expand Down Expand Up @@ -730,7 +740,7 @@ static esp_err_t esp_littlefs_init_efs(esp_littlefs_t** efs, const esp_partition
return ESP_ERR_NO_MEM;
}

(*efs)->fs = calloc(1, sizeof(lfs_t));
(*efs)->fs = esp_littlefs_calloc(1, sizeof(lfs_t));
if ((*efs)->fs == NULL) {
ESP_LOGE(ESP_LITTLEFS_TAG, "littlefs could not be malloced");
return ESP_ERR_NO_MEM;
Expand Down Expand Up @@ -829,7 +839,7 @@ static esp_err_t esp_littlefs_init(const esp_vfs_littlefs_conf_t* conf)
goto exit;
}
efs->cache_size = 4;
efs->cache = calloc(sizeof(*efs->cache), efs->cache_size);
efs->cache = esp_littlefs_calloc(sizeof(*efs->cache), efs->cache_size);

if(conf->grow_on_mount){
res = lfs_fs_grow(efs->fs, efs->partition->size / efs->cfg.block_size);
Expand Down Expand Up @@ -935,9 +945,9 @@ static int esp_littlefs_allocate_fd(esp_littlefs_t *efs, vfs_littlefs_file_t **

/* Allocate file descriptor here now */
#ifndef CONFIG_LITTLEFS_USE_ONLY_HASH
*file = calloc(1, sizeof(**file) + path_len);
*file = esp_littlefs_calloc(1, sizeof(**file) + path_len);
#else
*file = calloc(1, sizeof(**file));
*file = esp_littlefs_calloc(1, sizeof(**file));
#endif

if (*file == NULL) {
Expand Down Expand Up @@ -1156,8 +1166,12 @@ static int vfs_littlefs_open(void* ctx, const char * path, int flags, int mode)
mkdirs(efs, path);
#endif // CONFIG_LITTLEFS_SPIFFS_COMPAT

#ifndef CONFIG_LITTLEFS_MALLOC_STRATEGY_DISABLE
/* Open File */
res = lfs_file_open(efs->fs, &file->file, path, lfs_flags);
#else
#error "The use of static buffers is not currently supported by this VFS wrapper"
#endif

#if CONFIG_LITTLEFS_OPEN_DIR
if ( flags & O_DIRECTORY && res == LFS_ERR_ISDIR) {
Expand Down Expand Up @@ -1692,7 +1706,7 @@ static DIR* vfs_littlefs_opendir(void* ctx, const char* name) {
int res;
vfs_littlefs_dir_t *dir = NULL;

dir = calloc(1, sizeof(vfs_littlefs_dir_t));
dir = esp_littlefs_calloc(1, sizeof(vfs_littlefs_dir_t));
if( dir == NULL ) {
ESP_LOGE(ESP_LITTLEFS_TAG, "dir struct could not be malloced");
errno = ENOMEM;
Expand Down
32 changes: 21 additions & 11 deletions src/lfs_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,21 @@
#include <stdbool.h>
#include <string.h>
#include <inttypes.h>
#include "esp_heap_caps.h"
#include "sdkconfig.h"
#include "esp_log.h"

#ifndef LFS_NO_MALLOC

#if defined(CONFIG_LITTLEFS_MALLOC_STRATEGY_DEFAULT) || \
defined(CONFIG_LITTLEFS_MALLOC_STRATEGY_INTERNAL) || \
defined(CONFIG_LITTLEFS_MALLOC_STRATEGY_SPIRAM)
#include <stdlib.h>
#include "esp_heap_caps.h"
#endif
#ifndef LFS_NO_ASSERT

#ifdef CONFIG_LITTLEFS_ASSERTS
#include <assert.h>
#endif

#if !defined(LFS_NO_DEBUG) || \
!defined(LFS_NO_WARN) || \
!defined(LFS_NO_ERROR) || \
Expand Down Expand Up @@ -81,13 +87,11 @@ extern const char ESP_LITTLEFS_TAG[];
#endif

// Runtime assertions
#ifndef LFS_ASSERT
#ifndef LFS_NO_ASSERT
#ifdef CONFIG_LITTLEFS_ASSERTS
#define LFS_ASSERT(test) assert(test)
#else
#define LFS_ASSERT(test)
#endif
#endif


// Builtin functions, these may be replaced by more efficient
Expand Down Expand Up @@ -207,21 +211,27 @@ static inline uint32_t lfs_tobe32(uint32_t a) {
uint32_t lfs_crc(uint32_t crc, const void *buffer, size_t size);

// Allocate memory, only used if buffers are not provided to littlefs
// Note, memory must be 64-bit aligned
// For the lookahead buffer, memory must be 32-bit aligned
static inline void *lfs_malloc(size_t size) {
#ifndef LFS_NO_MALLOC
#if defined(CONFIG_LITTLEFS_MALLOC_STRATEGY_DEFAULT)
return malloc(size); // Equivalent to heap_caps_malloc_default(size);
#elif defined(CONFIG_LITTLEFS_MALLOC_STRATEGY_INTERNAL)
return heap_caps_malloc(size, MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL);
#else
#elif defined(CONFIG_LITTLEFS_MALLOC_STRATEGY_SPIRAM)
return heap_caps_malloc(size, MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM);
#else // CONFIG_LITTLEFS_MALLOC_STRATEGY_DISABLE or not defined
(void)size;
return NULL;
#endif
}

// Deallocate memory, only used if buffers are not provided to littlefs
static inline void lfs_free(void *p) {
#ifndef LFS_NO_MALLOC
#if defined(CONFIG_LITTLEFS_MALLOC_STRATEGY_DEFAULT) || \
defined(CONFIG_LITTLEFS_MALLOC_STRATEGY_INTERNAL) || \
defined(CONFIG_LITTLEFS_MALLOC_STRATEGY_SPIRAM)
free(p);
#else
#else // CONFIG_LITTLEFS_MALLOC_STRATEGY_DISABLE or not defined
(void)p;
#endif
}
Expand Down

0 comments on commit 266017e

Please sign in to comment.