3、文件系统选型:FatFS、LittleFS、SPIFFS的优缺点及适用场景
做嵌入式UI,尤其是LVGL这种需要加载外部存储图片的场景,文件系统选型是个绕不开的坎。说白了,你得给Flash或者SD卡找个“管家”,让它知道文件存在哪、怎么读、怎么删。
市面上常见的嵌入式文件系统就那么几个:FatFS、LittleFS、SPIFFS。我这些年做项目,这三个都用过,踩过坑也填过坑。今天咱们就掰开揉碎了聊聊,它们各自适合什么场景,又有什么坑等着你。
核心观点:没有最好的文件系统,只有最适合你硬件和业务场景的文件系统。选型前,先搞清楚你的存储介质是NOR Flash、NAND Flash还是SD卡,以及你的系统是否允许掉电。
3.1 三巨头速览:一张表看懂差异
先给个总览,方便你快速建立认知。我习惯把这三个系统比作三种性格的人:
- FatFS —— 老大哥,兼容性好,但脾气大(依赖操作系统)
- LittleFS —— 技术宅,安全可靠,但有点挑食(针对Flash优化)
- SPIFFS —— 轻量级选手,简单直接,但上限低
| 特性 | FatFS | LittleFS | SPIFFS |
|---|---|---|---|
| 设计目标 | 兼容PC文件系统 | 掉电安全、磨损均衡 | 极小RAM占用 |
| 存储介质 | SD卡、NAND Flash | NOR Flash、SPI Flash | SPI Flash |
| 掉电保护 | 弱(需额外处理) | 强(内建CRC+回滚) | 中等(有日志机制) |
| 磨损均衡 | 无 | 有(动态均衡) | 有(简单均衡) |
| RAM占用 | 较大(~2KB+) | 中等(~1KB) | 极小(~200B) |
| 最大文件大小 | 4GB+(取决于配置) | 受限于Flash大小 | 受限于Flash大小 |
| 目录支持 | 完整支持 | 支持(扁平或层级) | 不支持(只有根目录) |
| PC直接读取 | 可以(插读卡器) | 不可以 | 不可以 |
3.2 FatFS:老牌劲旅,兼容性王者
FatFS是我最早接触的文件系统。那时候做MP3播放器,SD卡里存歌,用FatFS直接就能在电脑上拷文件,方便得很。
优点很明显:
- PC兼容性无敌:你从电脑上拷个图片到SD卡,插到板子上就能读。这对开发调试来说太爽了。
- 文档丰富:网上教程一抓一大把,遇到问题基本都能搜到答案。
- 功能完整:支持长文件名、目录嵌套、文件时间戳,甚至还能做简单的权限控制。
但缺点也致命:
- 掉电保护基本靠运气:写文件写到一半断电,文件大概率损坏。我曾经有个项目,用户频繁断电,结果SD卡里的配置文件三天两头坏掉,最后不得不加了个备份机制。
- 没有磨损均衡:用在Flash上,频繁写的区域会先挂掉。你想想看,LVGL的图片缓存如果反复擦写同一块区域,Flash寿命会急剧下降。
- 对RTOS依赖强:多任务环境下需要加锁,否则并发读写会出问题。
避坑指南:我曾经在一个工业平板项目里用FatFS + SD卡存储UI图片。结果发现,设备在振动环境下SD卡偶尔会接触不良,导致文件系统挂载失败。后来我换成了eMMC + FatFS,才解决了这个问题。如果你用SD卡,务必考虑物理连接的可靠性。
适用场景:
- SD卡、TF卡、U盘等可移动存储
- 需要与PC频繁交换数据的场景
- 对掉电保护要求不高的消费类产品
3.3 LittleFS:掉电安全的守护神
LittleFS是ARM公司专门为Flash设计的文件系统。我第一次用它是做IoT设备,设备可能随时断电,数据还不能丢。当时试了一圈,最后锁定了LittleFS。
它的核心优势:
- 掉电安全是基因里带的:每次写操作都有CRC校验和回滚机制。就算写到一半断电,下次上电也能恢复到上一个完整状态。我测试过连续断电100次,文件系统纹丝不动。
- 磨损均衡做得好:它会动态地把写操作分散到不同的Flash块上,延长Flash寿命。对于LVGL这种频繁更新图片缓存的场景,这个特性太重要了。
- RAM占用可控:通过配置lookahead buffer大小,可以控制在1KB以内,对资源紧张的MCU很友好。
但也不是没缺点:
- PC不能直接读:你没法把Flash拆下来插电脑上拷文件。调试时得通过串口或网络把文件传进去,稍微麻烦点。
- 大文件性能一般:它的设计目标是小文件频繁读写,如果你要存几百MB的视频文件,效率不如FatFS。
- 配置参数多:read_size、prog_size、block_size、cache_size……新手容易配错,导致性能拉胯。
我的习惯:在LVGL项目中,如果使用内部Flash或SPI Flash存储图片,我首选LittleFS。配合LVGL的文件系统接口,把图片文件直接放在LittleFS分区里,掉电不丢图,用户怎么折腾都不怕。
适用场景:
- 电池供电、可能频繁断电的IoT设备
- NOR Flash、SPI Flash等嵌入式存储
- 需要高可靠性的工业、医疗设备
3.4 SPIFFS:轻量级选手,小而美
SPIFFS是专门为SPI Flash设计的文件系统。它的特点就一个字:小。RAM占用可以低到200字节左右,非常适合那些资源紧张到极致的小MCU。
优点:
- 极致的轻量:代码量小,RAM占用小,几乎不挑MCU。
- 实现简单:API就那么几个,open、read、write、close,上手极快。
- 有基本的磨损均衡:虽然不如LittleFS那么智能,但比FatFS强。
缺点也很明显:
- 不支持目录:所有文件都在根目录下。如果你的图片文件多了(比如几百张),管理起来会非常痛苦。
- 文件数量有限:默认配置下,文件数上限通常只有几十到一百多个。超过这个数,文件系统就罢工了。
- 性能一般:大文件读写速度慢,而且碎片化问题比较严重。用久了,Flash里全是碎片,读写效率会明显下降。
- 社区维护不活跃:相比LittleFS,SPIFFS的更新频率低很多,有些bug可能没人修。
我曾经踩过的坑:在一个智能家居面板项目里,我用SPIFFS存UI图片。刚开始只有20张图,一切正常。后来UI升级到80张图,问题来了:文件系统报错,无法创建新文件。查了半天,发现是SPIFFS的文件数上限到了。最后不得不换成了LittleFS,才彻底解决。
适用场景:
- RAM和Flash都极度紧张的超低成本MCU
- 文件数量少(<50个)、文件体积小(<100KB)的场景
- 原型验证、快速开发阶段
3.5 选型决策流程图
说了这么多,到底怎么选?我画了张图,帮你快速决策:
3.6 我的最终建议
如果你问我个人习惯怎么选,我会这么干:
- SD卡存储图片:无脑上FatFS。调试方便,PC直接拷图,效率最高。但记得在应用层做掉电保护,比如写文件前先备份。
- SPI Flash存储图片:首选LittleFS。掉电安全、磨损均衡、性能稳定。虽然调试麻烦点,但产品可靠性是第一位的。
- RAM小于512B、文件少于30个:可以考虑SPIFFS。但要做好后期换文件系统的心理准备,别把路走窄了。