话说嵌入式设备里用闪存做文件系统,一直是个微妙活儿:RAM 少、块擦除大、写入只能把 1 变 0,想反过来得整个块擦除才能重置。SPIFFS(SPI Flash File System))就诞生在这种痛点里。它是一套专门跑在 SPI NOR Flash(理论上任何 NOR Flash),占用极小 RAM、提供类 POSIX 接口(open/close/read/write/seek/stat……),还自带静态磨损均衡(wear leveling)和一致性检查。简单来说,就是给小内存 MCU 一条简单好用的闪存“读写通道”。
核心设计亮点
-
• 极简 RAM:所有缓冲区都是静态大小,不会随着文件数量炸堆,常见配置下一次只要几十到几百字节就够。
-
• 静态磨损均衡:SPIFFS 会把写擦操作分散到不同区块,延长闪存寿命。
-
• 一致性自检:格式化、挂载、写入都有内建 FS check,避免掉电瞬间丢数据。
-
• 多实例共存:同一片 Flash 上能跑几个 SPIFFS 实例,甚至不同分区。
-
• 高度可配置:chunk 大小、页大小、Cache 方式……config 宏统统自己调。
SPIFFS 的优势
-
1. 超低资源占用
在只有几十 KB RAM 的环境下也能愉快工作,刷写一个小固件客户再也不用担心文件系统把 RAM 吃光。 -
2. POSIX 式接口
不用自己瞎写 read/write 底层驱动,调用方式和 Linux 文件系统几乎一致,上手极快。 -
3. 无惧断电
突然断电、掉电,SPIFFS 的一致性检查能帮你快速恢复,绝大多数情形下数据不会损坏。 -
4. 多平台友好
虽然叫 SPI Flash FS,但也能跑在片上嵌入式 Flash,上游 C 代码,多数编译器都能纳入。 -
5. 社区打磨
1.6k⭐、400+ forks,稳定版维护到 v0.3.7,大家实战检验了好几年。
SPIFFS 的局限与挑战
-
• 扁平命名空间
不支持目录,所有文件其实都在同一个平面。想“tmp/1.txt”会被当作完整文件名。 -
• 非实时写入
有时单次写耗时差距较大,不适合对延时敏感的关键路径。 -
• 可扩展性有限
设计初衷是小闪存(几 MB 级别),当容量逼近上百 MB 后,RAM/索引开销会变得尴尬。 -
• 坏块管理空缺
目前不主动检测或隔离坏块,若遇工艺问题,得靠底层驱动层面保障。 -
• 单配置单二进制
编译时选好参数就一路走到底,无法“一镜多用”。
如何快速上手 SPIFFS
-
1. 克隆仓库并编译
git clone https://github.com/pellepl/spiffs.git
cd spiffs
mkdir build && cd build
make -
2. 配置你的 Flash 驱动
按照spiffs_config.h,填入 flash 大小、页/块尺寸、缓冲区需求等宏。 -
3. 挂载并使用
SPIFFS fs;
spiffs_config cfg = { /* 填你的读写函数、Flash 参数等 */ };
SPIFFS_mount(&fs, &cfg, work_buf, fds, fd_count, cache_buf, cache_size, null);
int fd = SPIFFS_open(&fs, "hello.txt", SPIFFS_RDWR | SPIFFS_CREAT, 0);
SPIFFS_write(&fs, fd, data, len);
SPIFFS_close(&fs, fd); -
4. 断电测试
反复暴力掉电,验证文件一致性。建议结合 Travis CI 或 AFL 等工具做自动化跑分。
总结
SPIFFS 不完美,但它在“小而全、用资源少”的赛道上表现抢眼。对那些仅需扁平文件存储、容忍偶尔非实时写延迟、闪存容量适中(几 MB 到几十 MB)的小型嵌入式项目,SPIFFS 几乎是「零痛点」的首选。想榨干每一块 NOR Flash 的潜力,它能帮你省下大把设计精力。不过要是你需要超级目录层级、超大容量、坏块自动管理,就得另谋高枝。总之,闪存小伙伴们,不妨试试这款被 1.6k 人点⭐的神器。
项目地址:https://github.com/pellepl/spiffs