返回首页

LittleFS 文件系统学习笔记

本笔记学习 Zephyr 的 LittleFS 文件系统,用于嵌入式设备上的文件存储。


示例路径

zephyr/samples/subsys/fs/littlefs/

核心概念

LittleFS 特点

特性说明
断电安全原子操作,断电不损坏
低内存内存占用小
损耗平衡均匀使用 Flash 块
目录支持支持多级目录

与 FATFS 对比

特性LittleFSFATFS
断电安全
内存占用通常较小通常更高,取决于配置
Flash 优化
大文件支持一般更好

核心 API

头文件

#include <zephyr/fs/fs.h>
#include <zephyr/fs/littlefs.h>

文件系统挂载

struct fs_mount_t lfs_mnt = {
    .type = FS_LITTLEFS,
    .fs_data = &storage,      // LittleFS 配置
    .mnt_point = "/lfs",     // 挂载点
    .storage_dev = (void *)FIXED_PARTITION_ID(storage_partition),
};

int rc = fs_mount(&lfs_mnt);
if (rc < 0) {
    printk("Mount failed: %d\n", rc);
}

LittleFS 配置

FS_LITTLEFS_DECLARE_DEFAULT_CONFIG(storage);

struct fs_mount_t lfs_mnt = {
    .type = FS_LITTLEFS,
    .fs_data = &storage,
    .mnt_point = "/lfs",
};

文件操作

打开文件

struct fs_file_t file;
fs_file_t_init(&file);

int rc = fs_open(&file, "/lfs/test.txt", FS_O_CREATE | FS_O_RDWR);
if (rc < 0) {
    printk("Open failed: %d\n", rc);
}

写入文件

const char *data = "Hello, LittleFS!";
int rc = fs_write(&file, data, strlen(data));
if (rc < 0) {
    printk("Write failed: %d\n", rc);
}

读取文件

char buf[128];
int rc = fs_read(&file, buf, sizeof(buf));
if (rc > 0) {
    buf[rc] = '\0';
    printk("Read: %s\n", buf);
}

关闭文件

fs_close(&file);

文件指针操作

// 移动到文件开头
fs_seek(&file, 0, FS_SEEK_SET);

// 移动到文件末尾
fs_seek(&file, 0, FS_SEEK_END);

// 获取当前偏移
off_t pos = fs_tell(&file);

目录操作

列出目录

int lsdir(const char *path)
{
    struct fs_dir_t dirp;
    struct fs_dirent entry;
    
    fs_dir_t_init(&dirp);
    
    int res = fs_opendir(&dirp, path);
    if (res) {
        return res;
    }
    
    while (1) {
        res = fs_readdir(&dirp, &entry);
        if (res || entry.name[0] == 0) {
            break;
        }
        
        if (entry.type == FS_DIR_ENTRY_DIR) {
            printk("[DIR ] %s\n", entry.name);
        } else {
            printk("[FILE] %s (%zu bytes)\n", entry.name, entry.size);
        }
    }
    
    fs_closedir(&dirp);
    return res;
}

// 使用
lsdir("/lfs");

创建目录

fs_mkdir("/lfs/data");

删除文件

fs_unlink("/lfs/test.txt");

获取文件系统信息

struct fs_statvfs sbuf;

int rc = fs_statvfs("/lfs", &sbuf);
if (rc == 0) {
    printk("Block size: %lu\n", sbuf.f_bsize);
    printk("Free blocks: %lu\n", sbuf.f_bfree);
}

完整示例

#include <zephyr/fs/fs.h>
#include <zephyr/fs/littlefs.h>

FS_LITTLEFS_DECLARE_DEFAULT_CONFIG(storage);

static struct fs_mount_t lfs_mnt = {
    .type = FS_LITTLEFS,
    .fs_data = &storage,
    .mnt_point = "/lfs",
    .storage_dev = (void *)FIXED_PARTITION_ID(storage_partition),
};

int main(void)
{
    struct fs_file_t file;
    char buf[64];
    
    // 挂载文件系统
    if (fs_mount(&lfs_mnt) < 0) {
        printk("Mount failed\n");
        return 0;
    }
    
    // 写文件
    fs_file_t_init(&file);
    fs_open(&file, "/lfs/hello.txt", FS_O_CREATE | FS_O_WRONLY);
    fs_write(&file, "Hello, World!", 13);
    fs_close(&file);
    
    // 读文件
    fs_file_t_init(&file);
    fs_open(&file, "/lfs/hello.txt", FS_O_RDONLY);
    fs_read(&file, buf, sizeof(buf));
    printk("Content: %s\n", buf);
    fs_close(&file);
    
    // 卸载
    fs_unmount(&lfs_mnt);
    
    return 0;
}

设备树配置

/ {
    partitions {
        storage_partition: partition@0 {
            label = "storage";
            reg = <0x00000000 0x00010000>;
        };
    };
};

&flash0 {
    partitions {
        compatible = "fixed-partitions";
        #address-cells = <1>;
        #size-cells = <1>;
        
        storage_partition: partition@0 {
            label = "storage";
            reg = <0x00000000 0x00010000>;
        };
    };
};

配置选项

# prj.conf
CONFIG_FILE_SYSTEM=y
CONFIG_LITTLEFS=y
CONFIG_LITTLEFS_CACHE_SIZE=64
CONFIG_LITTLEFS_LOOKAHEAD_SIZE=64

应用场景

  1. 配置存储: 保存设备配置参数
  2. 数据日志: 存储传感器数据
  3. 固件缓存: OTA 更新临时存储
  4. 用户数据: 存储用户文件

注意事项

  1. Flash 块大小: 需要与实际 Flash 对齐
  2. 格式化: 首次使用需要格式化
  3. 空间预留: 建议预留部分空间
  4. 断电保护: LittleFS 本身支持,需要 Flash 支持

*小白 🤖 - 2026-03-16*