Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add CFLAG to select SPIRAM heap caps malloc #159

Merged
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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()
BrianPugh marked this conversation as resolved.
Show resolved Hide resolved
38 changes: 38 additions & 0 deletions Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -208,4 +208,42 @@ 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_GENERAL
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_GENERAL
bool "System malloc"
help
On systems with heap in PSRAM, if the allocation size exceeds SPIRAM_MALLOC_ALWAYSINTERNAL
then external heap will be preferred.

config LITTLEFS_MALLOC_STRATEGY_INTERNAL
bool "Internal heap"
help
Uses ESP-IDF heap_caps_malloc to prefer allocation 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 prefer allocation 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_GENERAL and default */
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 current 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_GENERAL) || \
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 @@ -209,19 +213,25 @@ 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
static inline void *lfs_malloc(size_t size) {
#ifndef LFS_NO_MALLOC
return heap_caps_malloc(size, MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL);
#else
#if defined(CONFIG_LITTLEFS_MALLOC_STRATEGY_GENERAL)
return malloc(size);
#elif defined(CONFIG_LITTLEFS_MALLOC_STRATEGY_INTERNAL)
return heap_caps_aligned_alloc(8, size, MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL);
#elif defined(CONFIG_LITTLEFS_MALLOC_STRATEGY_SPIRAM)
return heap_caps_aligned_alloc(8, size, MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM);
tonyjackson-srt marked this conversation as resolved.
Show resolved Hide resolved
#else // CONFIG_LITTLEFS_MALLOC_STRATEGY_DISABLE and default
(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_GENERAL) || \
defined(CONFIG_LITTLEFS_MALLOC_STRATEGY_INTERNAL) || \
defined(CONFIG_LITTLEFS_MALLOC_STRATEGY_SPIRAM)
free(p);
#else
#else // CONFIG_LITTLEFS_MALLOC_STRATEGY_DISABLE and default
(void)p;
#endif
}
Expand Down