LittleFS:嵌入式文件系统代码示例及详解
2026/6/9 5:15:22 网站建设 项目流程

1、介绍

当前移植使用基于BW20的SDK的2.5.0版本为例。

LittleFS 由ARM官方发布,ARM mbedOS的官方推荐文件系统,具有轻量级,掉电安全,读写均衡的特性。主要用在微控制器和flash上,

优点如下:

掉电恢复,在写入时即使复位或者掉电也可以恢复到上一个正确的状态。
擦写均衡,有效延长flash的使用寿命。例如W25QXX系列的spi接口的flash,擦写次数大概在10万次,如果是操作flash比较频繁那么这10万次很快就会到达上限从而导致芯片废掉。
有限的RAM/ROM,相对于FATFS节省ROM和RAM空间
缺点如下:不兼容windows


2.littleFS结构

代码

flash.c

2. 变量定义

2.1 lfs_t lfs;
  • lfs_t是 LittleFS 的主结构体,用于管理文件系统的实例。
  • 变量lfs保存文件系统的上下文信息,例如挂载状态和文件操作的元数据。
2.2 lfs_file_t file;
  • lfs_file_t是 LittleFS 中的文件对象,表示打开的文件。
  • 变量file用于操作具体的文件,例如读写文件内容。
2.3 struct lfs_config lfs_cfg;
  • lfs_config是 LittleFS 的配置结构体,包含所有初始化文件系统所需的参数。
  • 变量lfs_cfg保存配置信息,例如读写函数、块大小、缓存大小等

3. 配置参数解析

3.1 函数指针

这些函数指针定义了文件系统与底层存储设备交互的方法:

  • .read

    • 函数指针:lfs_nor_read
    • 描述:读取存储设备上的数据。
    • 用法:LittleFS 在读取文件或目录时调用此函数。
  • .prog

    • 函数指针:lfs_nor_prog
    • 描述:向存储设备写入数据。
    • 用法:LittleFS 在保存文件或目录时调用此函数。
  • .erase

    • 函数指针:lfs_nor_erase
    • 描述:擦除存储设备的一个块。
    • 用法:在文件系统需要回收空间时调用。
  • .sync

    • 函数指针:lfs_diskio_sync
    • 描述:同步数据,确保缓存中的数据写入存储设备。
    • 用法:在断电之前或写操作完成后调用。

3.2 线程安全配置
  • #ifdef LFS_THREADSAFE
    • 如果启用了线程安全选项(通过定义LFS_THREADSAFE),以下函数将被启用:

    • .lock

      • 函数指针:lfs_diskio_lock
      • 描述:在多线程环境中加锁以保护文件系统操作。
    • .unlock

      • 函数指针:lfs_diskio_unlock
      • 描述:在多线程环境中解锁以恢复文件系统操作。

3.3 存储设备参数
  • .read_size = 1

    • 描述:每次读取操作的最小字节数(单位:字节)。
    • 通常设置为存储设备的最小可读单元。
  • .prog_size = 1

    • 描述:每次写入操作的最小字节数(单位:字节)。
    • 通常设置为存储设备的最小可写单元。
  • .block_size = 4096

    • 描述:每个存储块的大小(单位:字节)。
    • 通常设置为存储设备的擦除单元大小。
  • .block_count = 32

    • 描述:存储设备中的块数量。
    • 这个参数决定了文件系统的总容量: 容量=block_size×block_count=4096×32=128 KB\text{容量} = \text{block\_size} \times \text{block\_count} = 4096 \times 32 = 128\,\text{KB}容量=block_size×block_count=4096×32=128KB
  • .cache_size = 256

    • 描述:用于缓存读写操作的内存大小(单位:字节)。
    • 较大的缓存可以提高性能,但会占用更多 RAM。
  • .lookahead_size = 16

    • 描述:用于文件系统分配空闲块的提前查找缓冲区大小(单位:字节)。
    • 提高性能,减少寻找空闲块时的消耗。
  • .block_cycles = 500

    • 描述:每个块的可写入周期限制。
    • LittleFS 会在块接近磨损极限时自动回收和重分配,确保闪存寿命
lfs_t lfs; lfs_file_t file; struct lfs_config lfs_cfg = { .read = lfs_nor_read, .prog = lfs_nor_prog, .erase = lfs_nor_erase, .sync = lfs_diskio_sync, #ifdef LFS_THREADSAFE .lock = lfs_diskio_lock, .unlock = lfs_diskio_unlock, #endif .read_size = 1, .prog_size = 1, .block_size = 4096, .block_count = 32, .cache_size = 256, .lookahead_size = 16, .block_cycles = 500, }; int write_wifi_data_to_lfs(wifidata_t *wifi_data) { int err; err = lfs_file_open(&lfs, &file, "wifi_data", LFS_O_WRONLY | LFS_O_CREAT); if (err < 0) { printf("Error opening file for writing: %d\n", err); return err; } err = lfs_file_write(&lfs, &file, wifi_data, sizeof(wifidata_t)); if (err < 0) { printf("Error writing wifi_data to file: %d\n", err); lfs_file_close(&lfs, &file); return err; } else { printf("write lfs succ\n"); } lfs_file_close(&lfs, &file); err = lfs_diskio_sync(&lfs_cfg); if (err < 0) { printf("Error syncing filesystem: %d\n", err); return err; } return 0; } int read_wifi_data_from_lfs(wifidata_t *wifi_data) { int err; err = lfs_file_open(&lfs, &file, "wifi_data", LFS_O_RDONLY); if (err < 0) { printf("Error opening file for reading: %d\n", err); return err; } err = lfs_file_read(&lfs, &file, wifi_data, sizeof(wifidata_t)); if (err < 0) { printf("Error reading wifi_data from file: %d\n", err); lfs_file_close(&lfs, &file); return err; } lfs_file_close(&lfs, &file); return 0; } void init_lfs(void) { int err = lfs_mount(&lfs, &lfs_cfg); if (err) { printf("Failed to mount, formatting...\n"); lfs_format(&lfs, &lfs_cfg); lfs_mount(&lfs, &lfs_cfg); } else { printf("init lfs success\n"); } } void read_flash(void) { init_lfs(); if (read_wifi_data_from_lfs(&wifi_data) == 0) { printf("read flash\n"); } else { printf("read NO data\n"); } } void formatting(void) { int err = lfs_format(&lfs, &lfs_cfg); if (err) { printf("Error formatting LFS: %d\n", err); return; } printf("formatting LFS success\n"); } void init_flash(void) { init_lfs(); if (write_wifi_data_to_lfs(&wifi_data) == 0) { printf("Data written successfully\n"); } if (read_wifi_data_from_lfs(&wifi_data) == 0) { printf("Data read successfully\n"); } }

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询