3. 外部存储设备选型:SPI Flash、SD 卡、NAND Flash 对比,文件系统选择 (FATFS, LittleFS)

做 LVGL 外部存储加载图片,第一个绕不开的问题就是:图片放哪儿?

我见过不少新手,在 PC 上把 LVGL 跑得飞起,一上硬件就卡成幻灯片。为什么?因为图片数据还在内部 Flash 里挤着,或者用了个慢得要命的存储方案。

说白了,LVGL 的图片解码和渲染,本质上是「数据搬运工」。存储设备的读取速度、文件系统的开销,直接决定了你的 UI 能不能跑满 60fps。

这一章,咱们就把市面上主流的三种外部存储设备掰开揉碎,再聊聊文件系统怎么选。

3.1 三大存储设备:核心参数对比

先看一张表,把它们的底裤扒干净。

参数项 SPI Flash (如 W25Q64) SD 卡 (SPI/SDIO 模式) NAND Flash (如 MT29F)
典型容量 1MB ~ 256MB 128MB ~ 32GB+ 128MB ~ 8GB+
读取速度 (SPI 40MHz) ~5 MB/s (连续读) ~2 MB/s (SPI 模式)
~20 MB/s (SDIO 4bit)
~15 MB/s (连续读)
写入速度 ~0.5 MB/s (页编程) ~1 MB/s (SPI 模式) ~3 MB/s (页编程)
擦除方式 扇区擦除 (4KB) 无显式擦除 (FTL 管理) 块擦除 (128KB+)
随机读取 快 (按地址直接读) 慢 (文件系统+FTL 开销) 较慢 (需地址映射)
寿命 (擦写次数) 10万次 (典型) 取决于 SD 卡主控 1万~10万次 (MLC/SLC)
引脚数 8 脚 (SOIC-8) 9 脚 (SD 卡座) 48 脚 (TSOP-48)
硬件复杂度 低 (SPI 总线) 中 (SPI/SDIO + 卡座) 高 (需 ECC + 坏块管理)

关键结论:对于 LVGL 图片加载场景,连续读取速度和随机读取延迟是核心指标。写入速度反而不重要——图片通常是预烧录的。

3.2 SPI Flash:小容量场景的「甜点」

我个人最喜欢 SPI Flash。为什么?因为它简单、可靠、便宜。

如果你做的产品是智能家居面板、小尺寸彩屏设备,图片总量不超过 64MB,SPI Flash 几乎是唯一正确的选择。

  • 优势:硬件接口极其简单,4 根线(CS、SCK、MOSI、MISO)搞定。MCU 几乎都有 SPI 外设,驱动代码网上大把。
  • 劣势:容量天花板低。市面上最大也就 256MB,再大就得用 NAND 了。
  • 读取速度:40MHz SPI 时钟下,连续读能跑到 5MB/s 左右。对于 320x240 的 RGB565 图片(150KB),加载时间约 30ms,够用。

我的经验:用 SPI Flash 时,记得开启 Quad SPI (QSPI) 模式。同样是 40MHz 时钟,QSPI 能跑到 20MB/s,速度翻 4 倍。很多 MCU 都支持,别浪费这个功能。

3.3 SD 卡:大容量场景的「万金油」

如果你的产品需要存几百张高清图片,或者要支持用户通过 USB 拷贝图片,SD 卡是首选。

但 SD 卡有个坑——随机读取性能很差。

LVGL 加载图片时,经常需要跳转到文件的不同位置读取数据(比如解码 JPEG 时需要读取 Huffman 表)。SD 卡的 FTL(Flash Translation Layer)在处理随机小数据块时,延迟可能高达几十毫秒。

  • SPI 模式 vs SDIO 模式:SPI 模式速度慢(~2MB/s),但几乎所有 MCU 都支持。SDIO 4bit 模式速度快(~20MB/s),但需要 MCU 有 SDIO 外设,且布线要小心。
  • 文件系统:SD 卡出厂通常是 FAT32 格式。FAT32 在读取大文件时效率不错,但目录项多时,查找文件会变慢。

避坑指南:我曾经在一个项目里用 SD 卡存 200 张 800x480 的图片,结果 UI 切换时卡顿明显。后来发现是 SD 卡在读取每个文件时,FAT 表查找花了大量时间。解决方案:把图片打包成一个 .bin 文件,用偏移量直接读取,跳过文件系统开销。

3.4 NAND Flash:高性能场景的「重武器」

NAND Flash 通常用在高端产品上,比如工业平板、车载仪表。它的容量大、连续读取速度快,但代价是硬件复杂度高。

  • 坏块管理:NAND Flash 出厂就有坏块,使用过程中还会产生新坏块。你必须实现坏块管理算法,或者用现成的软件包(如 UFFS、YAFFS)。
  • ECC 纠错:NAND Flash 的存储单元会随着擦写次数增加而出现位翻转。你需要硬件 ECC 或软件 ECC 来保证数据正确性。
  • 读取速度:连续读取能到 15MB/s 以上,对于大尺寸图片(如 1024x600 的 JPEG)加载非常有利。

我的建议:除非你的产品图片总量超过 256MB,或者对读取速度有极致要求,否则别碰 NAND Flash。它的开发成本太高,不值得在小项目上折腾。

3.5 文件系统选择:FATFS vs LittleFS

存储设备选好了,接下来就是文件系统。文件系统决定了你怎么组织、读取图片文件。

对比项 FATFS LittleFS
设计目标 兼容 Windows/Linux 文件系统 嵌入式小容量、掉电安全
掉电保护 弱 (需额外日志/事务) 强 (内建掉电安全)
磨损均衡 无 有 (动态磨损均衡)
RAM 占用 ~2KB (最小配置) ~4KB (典型配置)
ROM 占用 ~10KB ~8KB
最大文件大小 4GB (FAT32) 取决于配置 (通常 < 4GB)
适用场景 SD 卡、大容量存储 SPI Flash、小容量 NOR Flash

3.6 我的推荐组合

做了这么多项目,我总结了一套「懒人选择法」:

  1. 图片总量 < 64MB,用 SPI Flash + LittleFS。 LittleFS 的掉电安全和磨损均衡,让 SPI Flash 的寿命大大延长。而且 LittleFS 在读取小文件时速度很快。
  2. 图片总量 > 64MB,用 SD 卡 + FATFS。 SD 卡容量大,FATFS 兼容性好。但记得把图片打包成 .bin 文件,或者用 LVGL 的 lv_fs 接口做缓存。
  3. 工业级产品,用 NAND Flash + 专用文件系统。 比如 UFFS 或 YAFFS。别用 FATFS 直接怼 NAND,会出大问题。

小技巧:不管你用哪种组合,都建议在 LVGL 初始化时,用 lv_fs_set_ready_cb() 注册一个回调,检测存储设备是否就绪。如果 SD 卡没插,或者 SPI Flash 初始化失败,LVGL 可以优雅地降级显示默认图片。

3.7 知识结构图:存储选型决策流程

下面这张图,帮你快速定位自己的需求。

外部存储选型决策流程图 外部存储选型决策流程 图片总量评估 总量 < 64MB ? 是 SPI Flash 否 SD 卡 / NAND LittleFS 掉电安全 + 磨损均衡 FATFS 大容量 + 兼容性 LVGL 图片加载优化 提示:SPI Flash + LittleFS 适合小容量、高可靠性场景;SD 卡 + FATFS 适合大容量、快速开发场景

3.8 小结

存储选型没有银弹。你得根据图片总量、读取速度要求、硬件成本、开发周期来权衡。

我个人最常用的组合是 SPI Flash + LittleFS,因为 90% 的嵌入式 UI 产品,图片总量都在 64MB 以内。这个组合开发快、成本低、可靠性高。

如果你非要用 SD 卡,记得做好文件系统缓存和图片打包,不然 LVGL 的刷新率会很难看。