4、嵌入式FAT文件系统:与Windows/Linux交换数据的桥梁,SD卡与U盘的最佳拍档

说到FAT文件系统,很多做嵌入式开发的朋友第一反应是:「这玩意儿太老了,都什么年代了还用FAT?」

嗯,我刚开始做QNX项目时也是这么想的。直到有一次,客户要求设备能直接插U盘导出日志,Windows电脑一插就能读。我试了试ext2、试了试QNX自家的PPS,结果Windows根本不认。最后老老实实换回FAT32,问题瞬间解决。

说白了,FAT文件系统在嵌入式世界里最大的价值,就是兼容性。它是Windows、Linux、macOS、QNX都能读写的「通用语言」。你想想看,SD卡、U盘、数码相机、行车记录仪……这些设备几乎清一色用FAT。为什么?因为没人想装驱动才能读卡。

4.1 FAT家族:FAT12、FAT16、FAT32 怎么选?

FAT家族有三个主要成员:FAT12、FAT16、FAT32。它们的核心区别在于簇地址用多少位来表示。位数越多,能管理的分区就越大。

类型 最大分区 最大文件 典型用途
FAT12 32 MB 32 MB 软盘、小容量MCU存储
FAT16 2 GB (4 KB簇) 2 GB 老式数码相机、MP3播放器
FAT32 2 TB (实际建议32 GB) 4 GB - 1字节 U盘、SD卡、行车记录仪

我个人习惯是:SD卡和U盘一律用FAT32。为什么?因为FAT16最大只支持2GB分区,现在随便一张卡都32GB起步。FAT12更是只能用在古董级设备上。

但有个坑要注意——FAT32单个文件不能超过4GB。我在项目中遇到过客户拷了一个4.2GB的监控视频到U盘,结果设备死活读不出来。排查了半天才发现是文件大小超限了。所以如果你要存大文件,比如高清视频、数据库镜像,那FAT32就不合适了,得考虑exFAT或者别的方案。

4.2 QNX下挂载FAT设备:三步搞定

在QNX里操作FAT文件系统,核心工具是io-blk.sofs-dos.so。前者负责跟硬件打交道(读扇区),后者负责解析FAT表结构。

挂载一个U盘,典型流程是这样的:

# 1. 启动块设备驱动(假设U盘是第一个USB存储设备)
io-blk.so -d usb &

# 2. 检查设备节点
ls /dev/hd0*

# 3. 挂载FAT32分区到/mnt/usb
mount -t dos /dev/hd0t177 /mnt/usb

这里t177是分区类型编号,对应FAT32。如果是FAT16,用t06;FAT12用t01。记不住没关系,用fdisk /dev/hd0看一眼分区表就清楚了。

小技巧: 如果你不确定分区类型,可以用 mount -t dos /dev/hd0 /mnt/usb 让系统自动检测。QNX的fs-dos驱动会扫描分区表,自动匹配正确的FAT变体。

4.3 性能调优:别让FAT成为瓶颈

FAT文件系统本身设计简单,但性能上限不高。尤其是在嵌入式设备上,CPU主频低、内存小,如果读写频繁,很容易卡顿。

我总结了几条实战经验:

  • 增大簇大小:默认簇大小是4KB,如果你存的文件普遍较大(比如照片、视频),可以格式化成32KB甚至64KB簇。这样能减少FAT表项数量,提升大文件读写速度。代价是浪费一点空间。
  • 开启写缓存:QNX的fs-dos驱动支持写缓存。在挂载时加-o cache=1M参数,分配1MB内存做缓存。我测试过,连续写入速度能提升30%~50%。
  • 避免频繁小文件写入:FAT的目录项是线性链表结构,每创建/删除一个文件都要遍历目录。如果你要写日志,建议先攒一批再批量写入,或者用内存文件系统做缓冲。
注意: 开启写缓存后,如果突然断电,缓存里的数据会丢失。我曾经在一个车载项目里吃过这个亏——设备记录行驶数据,结果司机拔钥匙太猛,缓存没刷完,最后一条日志丢了。后来我加了个电容,断电时强制刷缓存,才解决问题。

4.4 避坑指南:FAT在嵌入式中的常见问题

做嵌入式FAT开发,有几个坑我几乎每次都会遇到:

  1. 文件名编码问题:FAT32支持长文件名(LFN),但用的是UTF-16LE编码。如果你在QNX里用UTF-8字符串创建文件,需要做编码转换。否则Windows上看到的文件名可能是乱码。
  2. 8.3短文件名冲突:老设备只支持8.3格式(文件名8字符+扩展名3字符)。如果你创建了ABCDEFGH.TXTABCDEFGH.DOC,它们的短文件名可能冲突。我建议尽量用短文件名,或者确保前6个字符唯一。
  3. 卸载前一定要sync:拔U盘前,先执行sync命令,再umount。直接拔盘轻则丢数据,重则损坏FAT表。我在实验室里至少修过十几次坏掉的U盘。

核心要点:

  • FAT32是嵌入式设备与PC交换数据的首选,兼容性最好
  • 单个文件不能超过4GB,大文件场景请用exFAT或别的方案
  • 挂载命令:mount -t dos /dev/hd0t177 /mnt/usb
  • 性能优化:增大簇大小、开启写缓存、批量写入
  • 安全操作:先sync再umount,防止数据丢失

好了,FAT文件系统就聊到这儿。下一章我会讲exFAT——它是FAT32的升级版,解决了4GB文件限制,而且同样被Windows和macOS原生支持。如果你在做高清视频录制或者大容量数据采集,exFAT可能是更好的选择。