From 70f32e4e63f69513bd9ad5e3cbcde5bcf05ac071 Mon Sep 17 00:00:00 2001 From: Steven Dan Date: Tue, 19 May 2026 16:10:41 +0800 Subject: [PATCH] Added static buffers to lfs_config and changed all lfs_file_open to lfs_file_opencfg --- .../src/extensions/lfs_services.c | 40 +++++++++++----- .../src/extensions/lfs_services.c | 42 ++++++++++++----- .../src/extensions/lfs_services.c | 47 +++++++++++++------ 3 files changed, 92 insertions(+), 37 deletions(-) diff --git a/sw_usb_audio/app_usb_aud_fosi_c1/src/extensions/lfs_services.c b/sw_usb_audio/app_usb_aud_fosi_c1/src/extensions/lfs_services.c index 435d16e..b07c6de 100644 --- a/sw_usb_audio/app_usb_aud_fosi_c1/src/extensions/lfs_services.c +++ b/sw_usb_audio/app_usb_aud_fosi_c1/src/extensions/lfs_services.c @@ -25,6 +25,15 @@ static rtos_qspi_flash_t qspi_flash_ctx_s; #define SECTOR_SIZE 4096 rtos_qspi_flash_t *qspi_flash_ctx = &qspi_flash_ctx_s; +// Static buffers for LFS caches — avoids all malloc/free inside LittleFS. +// xCORE bare-metal newlib malloc is not thread-safe; dynamic allocation in +// multi-core LFS operations can corrupt the heap free-list. +static uint8_t lfs_read_buf[16]; +static uint8_t lfs_prog_buf[16]; +static uint8_t lfs_lookahead_buf[16]; +static uint8_t lfs_file_buf[16]; +static struct lfs_file_config file_cfg = { .buffer = lfs_file_buf }; + __attribute__((fptrgroup("local_block_device_read_fptr_grp"))) int local_block_device_read(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, void *buffer, lfs_size_t size) @@ -73,6 +82,11 @@ const struct lfs_config cfg = { .cache_size = 16, .lookahead_size = 16, .block_cycles = 500, + + // Static buffers — eliminates all malloc/free in LittleFS hot path + .read_buffer = lfs_read_buf, + .prog_buffer = lfs_prog_buf, + .lookahead_buffer = lfs_lookahead_buf, }; // Session-based exclusive flash access: @@ -173,7 +187,7 @@ void lfs_read_config(unsigned char * config, unsigned char * buffer, unsigned si #endif debug_printf("lfs_read_config: %s, size: %d\n", config, size); - int result = lfs_file_open(&lfs, &file, config, LFS_O_RDWR | LFS_O_CREAT); + int result = lfs_file_opencfg(&lfs, &file, config, LFS_O_RDWR | LFS_O_CREAT, &file_cfg); debug_printf("lfs_read_config: %s, result: %d\n", config, result); if (result != 0) { debug_printf("lfs_read_config: %s, open file failed\n", config); @@ -203,7 +217,7 @@ void lfs_write_config(unsigned char * config, unsigned char * buffer, unsigned s #endif debug_printf("lfs_write_config: %s, size: %d\n", config, size); - int result = lfs_file_open(&lfs, &file, config, LFS_O_RDWR | LFS_O_CREAT); + int result = lfs_file_opencfg(&lfs, &file, config, LFS_O_RDWR | LFS_O_CREAT, &file_cfg); if (result != 0) { debug_printf("lfs_write_config: open file failed\n"); return; @@ -223,10 +237,12 @@ void lfs_write_config(unsigned char * config, unsigned char * buffer, unsigned s #pragma stackfunction 1200 int lfs_file_exists(const char * file_path) { - lfs_file_t file; - int result = lfs_file_open(&lfs, &file, file_path, LFS_O_RDONLY); + lfs_file_t local_file; + static uint8_t local_file_buf[16]; + static struct lfs_file_config local_file_cfg = { .buffer = local_file_buf }; + int result = lfs_file_opencfg(&lfs, &local_file, file_path, LFS_O_RDONLY, &local_file_cfg); if (result == 0) { - lfs_file_close(&lfs, &file); + lfs_file_close(&lfs, &local_file); return 1; // 文件存在 } return 0; // 文件不存在 @@ -236,7 +252,7 @@ int lfs_file_exists(const char * file_path) #pragma stackfunction 1200 void lfs_read_eq_config(const char * file_path, unsigned char * buffer, unsigned size) { - lfs_file_open(&lfs, &file, file_path, LFS_O_RDONLY); + lfs_file_opencfg(&lfs, &file, file_path, LFS_O_RDONLY, &file_cfg); lfs_file_read(&lfs, &file, buffer, size); lfs_file_close(&lfs, &file); } @@ -244,7 +260,7 @@ void lfs_read_eq_config(const char * file_path, unsigned char * buffer, unsigned #pragma stackfunction 1500 void lfs_write_eq_config(const char * file_path, unsigned char * buffer, unsigned size) { - lfs_file_open(&lfs, &file, file_path, LFS_O_RDWR | LFS_O_CREAT); + lfs_file_opencfg(&lfs, &file, file_path, LFS_O_RDWR | LFS_O_CREAT, &file_cfg); lfs_file_rewind(&lfs, &file); lfs_file_write(&lfs, &file, buffer, size); lfs_file_close(&lfs, &file); @@ -265,10 +281,12 @@ int lfs_create_directory(const char * dir_path) char temp_file[256]; snprintf(temp_file, sizeof(temp_file), "%s/.dir", dir_path); - lfs_file_t file; - int result = lfs_file_open(&lfs, &file, temp_file, LFS_O_RDWR | LFS_O_CREAT); + lfs_file_t local_file; + static uint8_t local_file_buf[16]; + static struct lfs_file_config local_file_cfg = { .buffer = local_file_buf }; + int result = lfs_file_opencfg(&lfs, &local_file, temp_file, LFS_O_RDWR | LFS_O_CREAT, &local_file_cfg); if (result == 0) { - lfs_file_close(&lfs, &file); + lfs_file_close(&lfs, &local_file); lfs_remove(&lfs, temp_file); return 0; // 成功 } @@ -279,7 +297,7 @@ int lfs_create_directory(const char * dir_path) #if 0 // read current count uint32_t boot_count = 0; - lfs_file_open(&lfs, &file, "boot_count", LFS_O_RDWR | LFS_O_CREAT); + lfs_file_opencfg(&lfs, &file, "boot_count", LFS_O_RDWR | LFS_O_CREAT, &file_cfg); lfs_file_read(&lfs, &file, &boot_count, sizeof(boot_count)); // update boot count diff --git a/sw_usb_audio/app_usb_aud_fosi_c1_lp/src/extensions/lfs_services.c b/sw_usb_audio/app_usb_aud_fosi_c1_lp/src/extensions/lfs_services.c index 139b0a8..b07c6de 100644 --- a/sw_usb_audio/app_usb_aud_fosi_c1_lp/src/extensions/lfs_services.c +++ b/sw_usb_audio/app_usb_aud_fosi_c1_lp/src/extensions/lfs_services.c @@ -25,6 +25,15 @@ static rtos_qspi_flash_t qspi_flash_ctx_s; #define SECTOR_SIZE 4096 rtos_qspi_flash_t *qspi_flash_ctx = &qspi_flash_ctx_s; +// Static buffers for LFS caches — avoids all malloc/free inside LittleFS. +// xCORE bare-metal newlib malloc is not thread-safe; dynamic allocation in +// multi-core LFS operations can corrupt the heap free-list. +static uint8_t lfs_read_buf[16]; +static uint8_t lfs_prog_buf[16]; +static uint8_t lfs_lookahead_buf[16]; +static uint8_t lfs_file_buf[16]; +static struct lfs_file_config file_cfg = { .buffer = lfs_file_buf }; + __attribute__((fptrgroup("local_block_device_read_fptr_grp"))) int local_block_device_read(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, void *buffer, lfs_size_t size) @@ -73,6 +82,11 @@ const struct lfs_config cfg = { .cache_size = 16, .lookahead_size = 16, .block_cycles = 500, + + // Static buffers — eliminates all malloc/free in LittleFS hot path + .read_buffer = lfs_read_buf, + .prog_buffer = lfs_prog_buf, + .lookahead_buffer = lfs_lookahead_buf, }; // Session-based exclusive flash access: @@ -173,7 +187,7 @@ void lfs_read_config(unsigned char * config, unsigned char * buffer, unsigned si #endif debug_printf("lfs_read_config: %s, size: %d\n", config, size); - int result = lfs_file_open(&lfs, &file, config, LFS_O_RDWR | LFS_O_CREAT); + int result = lfs_file_opencfg(&lfs, &file, config, LFS_O_RDWR | LFS_O_CREAT, &file_cfg); debug_printf("lfs_read_config: %s, result: %d\n", config, result); if (result != 0) { debug_printf("lfs_read_config: %s, open file failed\n", config); @@ -203,7 +217,7 @@ void lfs_write_config(unsigned char * config, unsigned char * buffer, unsigned s #endif debug_printf("lfs_write_config: %s, size: %d\n", config, size); - int result = lfs_file_open(&lfs, &file, config, LFS_O_RDWR | LFS_O_CREAT); + int result = lfs_file_opencfg(&lfs, &file, config, LFS_O_RDWR | LFS_O_CREAT, &file_cfg); if (result != 0) { debug_printf("lfs_write_config: open file failed\n"); return; @@ -223,10 +237,12 @@ void lfs_write_config(unsigned char * config, unsigned char * buffer, unsigned s #pragma stackfunction 1200 int lfs_file_exists(const char * file_path) { - lfs_file_t file; - int result = lfs_file_open(&lfs, &file, file_path, LFS_O_RDONLY); + lfs_file_t local_file; + static uint8_t local_file_buf[16]; + static struct lfs_file_config local_file_cfg = { .buffer = local_file_buf }; + int result = lfs_file_opencfg(&lfs, &local_file, file_path, LFS_O_RDONLY, &local_file_cfg); if (result == 0) { - lfs_file_close(&lfs, &file); + lfs_file_close(&lfs, &local_file); return 1; // 文件存在 } return 0; // 文件不存在 @@ -236,7 +252,7 @@ int lfs_file_exists(const char * file_path) #pragma stackfunction 1200 void lfs_read_eq_config(const char * file_path, unsigned char * buffer, unsigned size) { - lfs_file_open(&lfs, &file, file_path, LFS_O_RDONLY); + lfs_file_opencfg(&lfs, &file, file_path, LFS_O_RDONLY, &file_cfg); lfs_file_read(&lfs, &file, buffer, size); lfs_file_close(&lfs, &file); } @@ -244,7 +260,7 @@ void lfs_read_eq_config(const char * file_path, unsigned char * buffer, unsigned #pragma stackfunction 1500 void lfs_write_eq_config(const char * file_path, unsigned char * buffer, unsigned size) { - lfs_file_open(&lfs, &file, file_path, LFS_O_RDWR | LFS_O_CREAT); + lfs_file_opencfg(&lfs, &file, file_path, LFS_O_RDWR | LFS_O_CREAT, &file_cfg); lfs_file_rewind(&lfs, &file); lfs_file_write(&lfs, &file, buffer, size); lfs_file_close(&lfs, &file); @@ -264,11 +280,13 @@ int lfs_create_directory(const char * dir_path) { char temp_file[256]; snprintf(temp_file, sizeof(temp_file), "%s/.dir", dir_path); - - lfs_file_t file; - int result = lfs_file_open(&lfs, &file, temp_file, LFS_O_RDWR | LFS_O_CREAT); + + lfs_file_t local_file; + static uint8_t local_file_buf[16]; + static struct lfs_file_config local_file_cfg = { .buffer = local_file_buf }; + int result = lfs_file_opencfg(&lfs, &local_file, temp_file, LFS_O_RDWR | LFS_O_CREAT, &local_file_cfg); if (result == 0) { - lfs_file_close(&lfs, &file); + lfs_file_close(&lfs, &local_file); lfs_remove(&lfs, temp_file); return 0; // 成功 } @@ -279,7 +297,7 @@ int lfs_create_directory(const char * dir_path) #if 0 // read current count uint32_t boot_count = 0; - lfs_file_open(&lfs, &file, "boot_count", LFS_O_RDWR | LFS_O_CREAT); + lfs_file_opencfg(&lfs, &file, "boot_count", LFS_O_RDWR | LFS_O_CREAT, &file_cfg); lfs_file_read(&lfs, &file, &boot_count, sizeof(boot_count)); // update boot count diff --git a/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/lfs_services.c b/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/lfs_services.c index 8e07f24..0d5d326 100644 --- a/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/lfs_services.c +++ b/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/lfs_services.c @@ -31,6 +31,15 @@ static rtos_qspi_flash_t qspi_flash_ctx_s; #define SECTOR_SIZE 4096 rtos_qspi_flash_t *qspi_flash_ctx = &qspi_flash_ctx_s; +// Static buffers for LFS caches — avoids all malloc/free inside LittleFS. +// xCORE bare-metal newlib malloc is not thread-safe; dynamic allocation in +// multi-core LFS operations can corrupt the heap free-list. +static uint8_t lfs_read_buf[16]; +static uint8_t lfs_prog_buf[16]; +static uint8_t lfs_lookahead_buf[16]; +static uint8_t lfs_file_buf[16]; +static struct lfs_file_config file_cfg = { .buffer = lfs_file_buf }; + __attribute__((fptrgroup("local_block_device_read_fptr_grp"))) int local_block_device_read(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, void *buffer, lfs_size_t size) @@ -79,6 +88,11 @@ const struct lfs_config cfg = { .cache_size = 16, .lookahead_size = 16, .block_cycles = 500, + + // Static buffers — eliminates all malloc/free in LittleFS hot path + .read_buffer = lfs_read_buf, + .prog_buffer = lfs_prog_buf, + .lookahead_buffer = lfs_lookahead_buf, }; // Session-based exclusive flash access: @@ -152,13 +166,13 @@ int lfs_format_all(void) { if (res != 0) { return res; // Already failed and released lock, or blocked } - + // Mount succeeded, but we want to format, so unmount first lfs_unmount(&lfs); - + // 格式化整个LFS分区,清除所有数据 int err = lfs_format(&lfs, &cfg); - + // Even if format fails, we must cleanup the session lfs_session_active = 0; swlock_release(&flash_lock); @@ -180,7 +194,7 @@ void lfs_read_config(unsigned char * config, unsigned char * buffer, unsigned si #endif debug_printf("lfs_read_config: %s, size: %d\n", config, size); - int result = lfs_file_open(&lfs, &file, config, LFS_O_RDWR | LFS_O_CREAT); + int result = lfs_file_opencfg(&lfs, &file, config, LFS_O_RDWR | LFS_O_CREAT, &file_cfg); debug_printf("lfs_read_config: %s, result: %d\n", config, result); if (result != 0) { debug_printf("lfs_read_config: %s, open file failed\n", config); @@ -210,7 +224,7 @@ void lfs_write_config(unsigned char * config, unsigned char * buffer, unsigned s #endif debug_printf("lfs_write_config: %s, size: %d\n", config, size); - int result = lfs_file_open(&lfs, &file, config, LFS_O_RDWR | LFS_O_CREAT); + int result = lfs_file_opencfg(&lfs, &file, config, LFS_O_RDWR | LFS_O_CREAT, &file_cfg); if (result != 0) { debug_printf("lfs_write_config: open file failed\n"); return; @@ -230,10 +244,12 @@ void lfs_write_config(unsigned char * config, unsigned char * buffer, unsigned s #pragma stackfunction 1200 int lfs_file_exists(const char * file_path) { - lfs_file_t file; - int result = lfs_file_open(&lfs, &file, file_path, LFS_O_RDONLY); + lfs_file_t local_file; + static uint8_t local_file_buf[16]; + static struct lfs_file_config local_file_cfg = { .buffer = local_file_buf }; + int result = lfs_file_opencfg(&lfs, &local_file, file_path, LFS_O_RDONLY, &local_file_cfg); if (result == 0) { - lfs_file_close(&lfs, &file); + lfs_file_close(&lfs, &local_file); return 1; // 文件存在 } return 0; // 文件不存在 @@ -243,7 +259,7 @@ int lfs_file_exists(const char * file_path) #pragma stackfunction 1200 void lfs_read_eq_config(const char * file_path, unsigned char * buffer, unsigned size) { - lfs_file_open(&lfs, &file, file_path, LFS_O_RDONLY); + lfs_file_opencfg(&lfs, &file, file_path, LFS_O_RDONLY, &file_cfg); lfs_file_read(&lfs, &file, buffer, size); lfs_file_close(&lfs, &file); } @@ -251,7 +267,7 @@ void lfs_read_eq_config(const char * file_path, unsigned char * buffer, unsigned #pragma stackfunction 1500 void lfs_write_eq_config(const char * file_path, unsigned char * buffer, unsigned size) { - lfs_file_open(&lfs, &file, file_path, LFS_O_RDWR | LFS_O_CREAT); + lfs_file_opencfg(&lfs, &file, file_path, LFS_O_RDWR | LFS_O_CREAT, &file_cfg); lfs_file_rewind(&lfs, &file); lfs_file_write(&lfs, &file, buffer, size); lfs_file_close(&lfs, &file); @@ -272,20 +288,23 @@ int lfs_create_directory(const char * dir_path) char temp_file[256]; snprintf(temp_file, sizeof(temp_file), "%s/.dir", dir_path); - lfs_file_t file; - int result = lfs_file_open(&lfs, &file, temp_file, LFS_O_RDWR | LFS_O_CREAT); + lfs_file_t local_file; + static uint8_t local_file_buf[16]; + static struct lfs_file_config local_file_cfg = { .buffer = local_file_buf }; + int result = lfs_file_opencfg(&lfs, &local_file, temp_file, LFS_O_RDWR | LFS_O_CREAT, &local_file_cfg); if (result == 0) { - lfs_file_close(&lfs, &file); + lfs_file_close(&lfs, &local_file); lfs_remove(&lfs, temp_file); return 0; // 成功 } return -1; // 失败 } + #if 0 // read current count uint32_t boot_count = 0; - lfs_file_open(&lfs, &file, "boot_count", LFS_O_RDWR | LFS_O_CREAT); + lfs_file_opencfg(&lfs, &file, "boot_count", LFS_O_RDWR | LFS_O_CREAT, &file_cfg); lfs_file_read(&lfs, &file, &boot_count, sizeof(boot_count)); // update boot count