本帖最后由 a976209770 于 2024-11-28 15:18 编辑
引言 FAT 文件系统(FileAllocation Table)是一种轻量级且广泛兼容的文件系统,广泛应用于嵌入式系统中,用于管理外部存储设备(如 SD 卡、U 盘等)。本篇文章将以APM32F407 芯片为例,详细讲解 FAT 文件系统的移植步骤、代码结构分析及其在实际工程中的使用方法,涵盖支持的格式、容量限制及每个代码模块的功能细节。 1. FAT 文件系统的支持特性 FAT 文件系统是由微软开发的早期文件系统标准,具有简单高效的特点,非常适合资源有限的嵌入式设备使用。 1.1 支持的文件系统类型
- FAT12:
- 适用于容量较小的设备(<32MB)。
- 每个文件的簇链表由 12 位表示。
- FAT16:
- 支持中等容量设备(2GB 以下)。
- 每个文件的簇链表由 16 位表示。
- FAT32:
- 适用于大容量设备(2GB 至 32GB)。
- 每个文件的簇链表由 32 位表示。
1.2 支持的存储设备
- SD 卡:支持 SPI 或 SDIO 接口通信。
- USB 存储设备:如 U 盘(需要 USB Host 支持)。
- NAND Flash 和 NOR Flash:需实现专用的硬件驱动。
1.3 支持的容量
- 最大文件系统容量:
- FAT32 的理论上限为 2TB,但大部分嵌入式平台受限于软件配置,支持最大 32GB。
- 文件大小限制:
2. FAT 文件系统的代码结构 FAT 文件系统的实现依赖多个核心模块和存储设备接口模块。以下是典型代码结构及各模块的作用。 2.1 核心文件
- ff.c 和 ff.h:
- ff.c 是 FAT 文件系统的核心实现,包含文件、目录操作的主要逻辑。
- ff.h 定义了系统的 API 接口和全局配置项。
- diskio.c 和 diskio.h:
- diskio.c 是存储设备抽象层的实现,定义了统一的存储读写接口。
- diskio.h 规定了底层驱动与文件系统之间的交互规范。
- integer.h:
- 提供跨平台的通用整数类型定义,如 BYTE、WORD 等。
2.2 存储设备驱动
- sdcard.c:
- 实现 SD 卡的硬件接口驱动,支持 SPI 和 SDIO 通信。
- usb_host.c:
- nand_flash.c:
3. 各模块详细解析 3.1 核心模块:ff.c 和 ff.h 作用
- ff.c 是文件系统的核心代码,实现以下功能:
- 文件操作:支持文件的打开、读取、写入、关闭。
- 目录操作:支持创建、删除、遍历目录。
- 文件系统管理:支持挂载、卸载、格式化文件系统。
关键接口 以下是常用的接口函数及其说明: FRESULT f_mount(FATFS *fs, const TCHAR*path, BYTE opt);
- f_open: 打开文件,如果文件不存在,可以创建文件。
FRESULT f_open(FIL *fp, const TCHAR *path,BYTE mode);
- f_read 和 f_write: 读取和写入文件数据。
FRESULT f_read(FIL *fp, void *buff, UINTbtr, UINT *br); FRESULT f_write(FIL *fp, const void *buff,UINT btw, UINT *bw); 文件读写示例
FIL file; FRESULT res; UINT bw;
// 挂载文件系统 f_mount(&FatFs, "", 0);
// 打开文件 res = f_open(&file,"hello.txt", FA_WRITE | FA_CREATE_ALWAYS); if (res == FR_OK) { // 写入数据 res = f_write(&file, "Hello, FAT File System!", 23,&bw); if (res == FR_OK && bw == 23) { printf("Data written successfully.\n"); } f_close(&file); } else { printf("Failed to open file.\n"); } 3.2 存储抽象模块:diskio.c和 diskio.h 作用 - diskio.c 是存储设备的抽象层,实现对底层存储驱动的封装。
- 定义了与硬件驱动的交互接口,包括初始化、读写和状态检测。
关键接口 - disk_initialize: 初始化存储设备。
- disk_read 和 disk_write: 提供数据块级读写接口。
- disk_ioctl: 实现设备控制命令,如获取设备容量。
3.3 存储设备驱动:sdcard.c 作用 - 实现 SD 卡的硬件通信,包括数据块读写、初始化和状态检测。
- 支持两种模式:SPI 和 SDIO。
关键函数 - SD_Init:初始化 SD 卡。
- SD_ReadBlock 和 SD_WriteBlock:单块数据读写操作。
- SD_GetStatus:检查卡是否准备好。
4. 初始化与挂载文件系统
4.1 初始化代码
以下代码展示如何初始化 SD 卡,并挂载 FAT 文件系统:
#include "ff.h" #include "diskio.h" #include "sdcard.h"
FATFS FatFs;
void fatfs_init(void) { FRESULT res;
// 初始化 SD 卡 if (SD_Init() == 0) { printf("SD card initialized successfully.\n");
// 挂载文件系统 res = f_mount(&FatFs, "", 0); if (res == FR_OK) { printf("File system mounted.\n"); } else { printf("Failed to mount file system.\n"); } } else { printf("Failed to initialize SD card.\n"); } } 4.2 数据读写代码
以下是一个完整的文件写入和读取示例:
FIL file; FRESULT res; UINT bw, br; char buffer[128];
// 写入数据 res = f_open(&file,"example.txt", FA_WRITE | FA_CREATE_ALWAYS); if (res == FR_OK) { f_write(&file, "FAT File System Test", 21, &bw); f_close(&file); }
// 读取数据 res = f_open(&file,"example.txt", FA_READ); if (res == FR_OK) { f_read(&file, buffer, sizeof(buffer), &br); buffer[br] = '\0'; // 添加字符串结束符 printf("Read data: %s\n", buffer); f_close(&file); } 5. 高级功能扩展
5.1 支持多分区
通过启用多分区支持,挂载不同分区到不同路径:
f_mount(&FatFs1, "0:", 0); f_mount(&FatFs2, "1:", 0);
5.2 遍历目录
DIR dir; FILINFO fno;
if (f_opendir(&dir, "/") ==FR_OK) { while (f_readdir(&dir, &fno) == FR_OK && fno.fname[0]) { printf("Found: %s\n", fno.fname); } f_closedir(&dir); } 6. 总结
通过本文所示代码,可以在 APM32F407 上完成 FAT 文件系统的移植与使用。以下是总结要点:
- 支持类型:支持 FAT12、FAT16 和 FAT32 文件系统。
- 容量限制:支持最大 32GB 的存储设备,单文件大小限制为 4GB。
- 关键模块:
- ff.c:文件系统核心。
- diskio.c:设备抽象层。
- sdcard.c:存储设备驱动。
FAT 文件系统提供了一种高效、兼容性强的嵌入式文件管理解决方案,适合多种存储设备的开发场景。通过合理配置和优化,可以在实际项目中快速实现文件存储功能。
附件为基于APM32F407库的fat_fs代码示例,供参考
|