littlefs-project/littlefs

GitHub: littlefs-project/littlefs

专为微控制器设计的轻量级容错文件系统,具备断电恢复和闪存磨损均衡能力。

Stars: 6454 | Forks: 968

## littlefs 一个专为微控制器设计的小型容错文件系统。 ``` | | | .---._____ .-----. | | --|o |---| littlefs | --| |---| | '-----' '----------' | | | ``` **断电恢复能力** - littlefs 旨在处理随机的电源故障。所有文件操作都具有强有力的写时复制保障,如果发生断电,文件系统将回退到上一个已知的良好状态。 **动态磨损均衡** - littlefs 专为闪存设计,并在动态块上提供磨损均衡。此外,littlefs 可以检测坏块并对其进行处理。 **有限的 RAM/ROM** - littlefs 设计用于在少量内存下工作。RAM 使用量受到严格限制,这意味着 RAM 消耗不会随着文件系统的增长而改变。文件系统不包含无界递归,动态内存仅限于可静态提供的可配置缓冲区。 ## 示例 这是一个简单的示例,每次运行 main 时都会更新一个名为 `boot_count` 的文件。该程序可以在任何时候被中断,而不会丢失其启动次数的记录,也不会损坏文件系统: ``` #include "lfs.h" // variables used by the filesystem lfs_t lfs; lfs_file_t file; // configuration of the filesystem is provided by this struct const struct lfs_config cfg = { // block device operations .read = user_provided_block_device_read, .prog = user_provided_block_device_prog, .erase = user_provided_block_device_erase, .sync = user_provided_block_device_sync, // block device configuration .read_size = 16, .prog_size = 16, .block_size = 4096, .block_count = 128, .cache_size = 16, .lookahead_size = 16, .block_cycles = 500, }; // entry point int main(void) { // mount the filesystem int err = lfs_mount(&lfs, &cfg); // reformat if we can't mount the filesystem // this should only happen on the first boot if (err) { lfs_format(&lfs, &cfg); lfs_mount(&lfs, &cfg); } // read current count uint32_t boot_count = 0; lfs_file_open(&lfs, &file, "boot_count", LFS_O_RDWR | LFS_O_CREAT); lfs_file_read(&lfs, &file, &boot_count, sizeof(boot_count)); // update boot count boot_count += 1; lfs_file_rewind(&lfs, &file); lfs_file_write(&lfs, &file, &boot_count, sizeof(boot_count)); // remember the storage is not updated until the file is closed successfully lfs_file_close(&lfs, &file); // release any resources we were using lfs_unmount(&lfs); // print the boot count printf("boot_count: %d\n", boot_count); } ``` ## 用法 详细的文档(或者至少是目前可用的详细程度)可以在 [lfs.h](lfs.h) 的注释中找到。 littlefs 接受一个定义文件系统如何运行的配置结构。该配置结构体为文件系统提供块设备操作和维度、用于在内存使用和性能之间进行权衡的可调参数,以及可选的静态缓冲区(如果用户希望避免动态内存分配)。 littlefs 的状态存储在 `lfs_t` 类型中,该类型由用户自行分配,允许同时使用多个文件系统。使用 `lfs_t` 和配置结构体,用户可以格式化块设备或挂载文件系统。 一旦挂载,littlefs 提供一套完整的类 POSIX 文件和目录函数,其不同之处在于文件系统结构的分配必须由用户提供。 所有 POSIX 操作(例如 remove 和 rename)都是原子的,即使在发生断电时也是如此。此外,在调用 sync 或 close 之前,文件更新实际上并未提交到文件系统。 ## 其他说明 Littlefs 使用 C 语言编写,特别是应该可以通过任何符合 `C99` 标准的编译器进行编译。 所有 littlefs 调用都有可能返回负错误代码。这些错误可以是 [lfs.h](lfs.h) 中 `enum lfs_error` 中的错误之一,或者是用户块设备操作返回的错误。 在配置结构体中,如果实现已经可以检测到损坏的块,用户提供的 `prog` 和 `erase` 函数可能会返回 `LFS_ERR_CORRUPT` 错误。但是,磨损均衡不依赖于这些函数的返回代码,而是会回读所有数据并检查其完整性。 如果您的存储设备缓存写入,请确保提供的 `sync` 函数将所有数据刷新到内存,并确保下一次读取是从内存中获取数据,否则无法保证数据完整性。如果 `write` 函数不执行缓存,因此每次 `read` 或 `write` 调用都直接访问内存,则 `sync` 函数可以简单地返回 0。 ## 设计 从高层次来看,littlefs 是一个基于块的文件系统,它使用小型日志来存储元数据,并使用较大的写时复制(COW)结构来存储文件数据。 在 littlefs 中,这些组件形成了一个双层结构,小型日志(称为元数据对)提供对存储上任何位置元数据的快速更新,而 COW 结构紧凑地存储文件数据,且没有任何写入放大开销。 这两种数据结构都由块构成,这些块由公共块分配器提供。通过限制每个分配周期内块上允许的擦除次数,分配器在整个文件系统上提供动态磨损均衡。 ``` root .--------.--------. | A'| B'| | | | |-> | | | | | '--------'--------' .----' '--------------. A v B v .--------.--------. .--------.--------. | C'| D'| | | E'|new| | | | |-> | | | E'|-> | | | | | | | | | '--------'--------' '--------'--------' .-' '--. | '------------------. v v .-' v .--------. .--------. v .--------. | C | | D | .--------. write | new E | | | | | | E | ==> | | | | | | | | | | '--------' '--------' | | '--------' '--------' .-' | .-' '-. .-------------|------' v v v v .--------. .--------. .--------. | F | | G | | new F | | | | | | | | | | | | | '--------' '--------' '--------' ``` 关于 littlefs 如何工作的更多细节可以在 [DESIGN.md](DESIGN.md) 和 [SPEC.md](SPEC.md) 中找到。 - [DESIGN.md](DESIGN.md) - 深入探讨 littlefs 工作原理的完整详细文档。 我建议阅读它,因为其中的权衡设计非常有趣。 - [SPEC.md](SPEC.md) - littlefs 的磁盘规范,包含所有具体的细节。可能对工具开发有用。 ## 测试 littlefs 附带一个测试套件,旨在使用 `bd` 目录中的 [模拟块设备](bd/lfs_testbd.h) 在 PC 上运行。 测试假设使用 Linux 环境,可以通过 make 启动: ``` make test ``` 测试是用 C 语言在 `tests` 目录中的 .toml 文件中实现的。 在开发功能或修复错误时,运行单个测试用例或测试套件通常很有用: ``` ./scripts/test.py -l runners/test_runner # list available test suites ./scripts/test.py -L runners/test_runner test_dirs # list available test cases ./scripts/test.py runners/test_runner test_dirs # run a specific test suite ``` 如果测试中的断言失败,test.py 将尝试打印有关失败的信息: ``` tests/test_dirs.toml:1:failure: test_dirs_root:1g12gg2 (PROG_SIZE=16, ERASE_SIZE=512) failed tests/test_dirs.toml:5:assert: assert failed with 0, expected eq 42 lfs_mount(&lfs, cfg) => 42; ``` 这包括测试 ID,可以将其传递给 test.py 以仅运行该特定的测试排列: ``` ./scripts/test.py runners/test_runner test_dirs_root:1g12gg2 # run a specific test permutation ./scripts/test.py runners/test_runner test_dirs_root:1g12gg2 --gdb # drop into gdb on failure ``` 其他一些可能有用的标志: ``` ./scripts/test.py runners/test_runner -b -j # run tests in parallel ./scripts/test.py runners/test_runner -v -O- # redirect stdout to stdout ./scripts/test.py runners/test_runner -ddisk # capture resulting disk image ``` 有关可用标志的完整列表,请参阅 `-h/--help`: ``` ./scripts/test.py --help ``` ## 许可证 littlefs 是在 [BSD-3-Clause] 许可证下提供的。有关更多信息,请参阅 [LICENSE.md](LICENSE.md)。对本项目的贡献是在相同的许可证下接受的。 单个文件包含以下标签,而不是完整的许可证文本。 ``` SPDX-License-Identifier: BSD-3-Clause ``` 这使得基于 SPDX 许可证标识符的许可证信息机器处理成为可能,这些标识符可在此处获得:http://spdx.org/licenses/ ## 相关项目 - [littlefs-fuse] - littlefs 的一个 [FUSE] 封装。该项目允许您直接在 Linux 机器上挂载 littlefs。如果您手头有 SD 卡,这对于调试 littlefs 很有用。 - [littlefs-js] - littlefs 的一个 JavaScript 封装。我不确定您为什么会需要这个,但它对于演示很方便。您可以在 [这里][littlefs-js-demo] 看到它的实际效果。 - [littlefs-python] - littlefs 的一个 Python 封装。该项目允许您在 PC 上创建文件系统镜像。检查 littlefs 是否满足您的需求,为稍后下载到目标存储器创建镜像,或检查目标存储器的二进制镜像内容。 - [littlefs-toy] - 一个用于创建和处理 littlefs 镜像的命令行工具。使用类似于 tar 命令的语法以易于使用。支持处理嵌入在另一个文件中的 littlefs 镜像(固件镜像等)。 - [littlefs2-rust] - littlefs 的一个 Rust 封装。该项目允许您在 Rust 友好的 API 中使用 littlefs,享受 Rust 的内存安全和其他保证带来的好处。 - [nim-littlefs] - littlefs 的一个 Nim 封装和 API。包括基于 [littlefs-fuse] 的 fuse 实现。 - [chamelon] - 一个(大部分)littlefs 的纯 OCaml 实现,专为 MirageOS 库操作系统项目设计。它与参考实现互操作,但有一些注意事项。 - [littlefs-disk-img-viewer] - 一个用于在 Web 浏览器中查看 littlefs 磁盘镜像的内存高效 Web 应用程序。 - [mklfs] - 一个用于创建 littlefs 镜像的命令行工具。用于 Lua RTOS 生态系统。 - [mklittlefs] - 一个用于创建 littlefs 镜像的命令行工具。用于 ESP8266 和 RP2040 生态系统。 - [pico-littlefs-usb] - 一个 littlefs 接口,通过 USB 模拟 FAT12 文件系统。允许在主机 PC 上挂载 littlefs 而无需额外的驱动程序。 - [ramcrc32bd] - 一个使用 littlefs 的 32 位 CRC 进行纠错的示例块设备。 - [ramrsbd] - 一个使用 Reed-Solomon 码进行纠错的示例块设备。 - [Mbed OS] - 开始使用 littlefs 的最简单方法是进入 Mbed,它已经拥有大多数形式嵌入式存储的块设备驱动程序。 littlefs 在 Mbed OS 中作为 [LittleFileSystem] 类提供。 - [SPIFFS] - 另一个用于 NOR 闪存的优秀嵌入式文件系统。作为一个具有完全静态磨损均衡的更传统的日志文件系统,SPIFFs 在小容量存储器(如微控制器上的内部闪存)上可能会优于 littlefs。 - [Dhara] - 一个有趣的小型 MCU NAND 闪存转换层。它提供静态磨损均衡和断电恢复能力,每个块和 RAM 中仅存储固定的 _O(|address|)_ 指针结构。 - [ChaN's FatFs] - 针对微控制器级设备的臭名昭著的 FAT 文件系统的轻量级重新实现。由于 FAT 的局限性,它无法提供断电恢复能力,但它确实允许与 PC 轻松互操作。
标签:Fail-safe, Flash存储, NOR Flash, RTOS, Zenmap, 低内存占用, 固件设计, 块设备, 存储管理, 客户端加密, 客户端加密, 嵌入式开发, 嵌入式系统, 开源库, 微控制器, 掉电保护, 搜索引擎爬虫, 数据完整性, 文件系统, 断电恢复, 物联网, 磨损均衡