一:/* Object ID and allocation information (FFOBJID) */
cpp
typedef struct {
FATFS* fs; /* Pointer to the hosting volume of this object */
WORD id; /* Hosting volume's mount ID */
BYTE attr; /* Object attribute */
BYTE stat; /* Object chain status (b1-0: =0:not contiguous, =2:contiguous, =3:fragmented in this session, b2:sub-directory stretched) */
DWORD sclust; /* Object data start cluster (0:no cluster or root directory) */
FSIZE_t objsize; /* Object size (valid when sclust != 0) */
#if FF_FS_EXFAT
DWORD n_cont; /* Size of first fragment - 1 (valid when stat == 3) */
DWORD n_frag; /* Size of last fragment needs to be written to FAT (valid when not zero) */
DWORD c_scl; /* Containing directory start cluster (valid when sclust != 0) */
DWORD c_size; /* b31-b8:Size of containing directory, b7-b0: Chain status (valid when c_scl != 0) */
DWORD c_ofs; /* Offset in the containing directory (valid when file object and sclust != 0) */
#endif
#if FF_FS_LOCK
UINT lockid; /* File lock ID origin from 1 (index of file semaphore table Files[]) */
#endif
} FFOBJID;
FFOBJID 结构体分析总结
FFOBJID 是 FatFs 库中用于管理文件或目录对象的元数据结构体,记录对象在文件系统中的存储位置、状态、属性及并发控制信息。其成员变量根据配置选项(如 FF_FS_EXFAT
或 FF_FS_LOCK
)动态扩展,支持不同文件系统特性和功能。
核心成员变量解析
成员变量 | 类型 | 说明 |
---|---|---|
fs |
FATFS* |
所属卷指针:指向对象所在的文件系统卷(如 SD 卡、Flash 分区)。 |
id |
WORD |
卷挂载 ID:标识卷的挂载状态,用于检测卷是否被重新挂载(避免缓存失效)。 |
attr |
BYTE |
对象属性 :存储 FAT 文件属性(如只读 AM_RDO 、隐藏 AM_HID 等)。 |
stat |
BYTE |
对象链状态 : - b1-b0 : 簇链连续性(0=非连续,2=连续,3=当前会话碎片化)。 - b2: 子目录是否被扩展(如添加新条目导致目录簇链增长)。 |
sclust |
DWORD |
起始簇号:对象数据的第一个簇号(0 表示空文件或根目录)。 |
objsize |
FSIZE_t |
对象大小 :文件或目录的实际大小(单位:字节,仅当 sclust ≠ 0 时有效)。 |
条件编译扩展成员
-
FF_FS_EXFAT
(exFAT 文件系统支持)成员变量 类型 说明 n_cont
DWORD
首个片段大小 -1 :当 stat = 3
时有效,记录 exFAT 文件的碎片信息。n_frag
DWORD
待写入 FAT 的末片段大小:非零时需更新 FAT 表。 c_scl
DWORD
所属目录起始簇 :对象所在的父目录起始簇(仅当 sclust ≠ 0
时有效)。c_size
DWORD
目录大小与状态 : - b31-b8 : 父目录大小(字节)。 - b7-b0: 目录簇链状态。 c_ofs
DWORD
在父目录中的偏移 :文件对象在目录中的位置(仅当 sclust ≠ 0
时有效)。 -
FF_FS_LOCK
(文件锁支持)成员变量 类型 说明 lockid
UINT
文件锁 ID:从 1 开始,用于标识文件锁表中的条目,管理多线程/进程并发访问。
功能与应用场景
-
文件/目录操作跟踪
-
sclust
与objsize
:定位文件数据簇链的起始位置和大小,支持读写操作。 -
stat
:优化簇链遍历,连续簇(stat=2
)可快速寻址,碎片化簇(stat=3
)需动态处理。
-
-
exFAT 特性支持
-
n_cont
与n_frag
:管理 exFAT 文件的碎片,提升大文件存储效率。 -
c_scl
与c_ofs
:快速定位文件在父目录中的元数据,加速目录遍历。
-
-
并发控制
lockid
:通过信号量机制防止多线程同时修改同一文件,确保数据一致性。
-
卷状态管理
id
:检测卷是否被卸载后重新挂载,避免使用过时的缓存数据。
配置选项影响
配置宏 | 影响成员变量 | 功能扩展说明 |
---|---|---|
FF_FS_EXFAT |
n_cont , n_frag , c_scl 等 |
支持 exFAT 文件系统的碎片管理和目录操作。 |
FF_FS_LOCK |
lockid |
启用文件锁功能,防止并发冲突。 |
FF_FS_READONLY |
(间接影响) | 只读模式下无需更新 n_frag 或簇链状态。 |
典型使用流程
-
打开文件
cppFIL fil; f_open(&fil, "file.txt", FA_READ); // FFOBJID 被初始化,记录 fil 的 sclust、objsize 等
-
读取数据
cppUINT br; f_read(&fil, buffer, sizeof(buffer), &br); // 根据 sclust 和簇链定位数据扇区
-
写入数据(exFAT 碎片处理)
cppf_write(&fil, data, size, &bw); // 若文件扩展导致碎片,更新 n_cont 和 n_frag
-
文件锁控制
cpp// 多线程环境中,通过 lockid 加锁
-
关闭文件
cppf_close(&fil); // 释放 lockid,更新 stat 和 FAT 表(若数据修改)
总结
-
FFOBJID 是 FatFs 管理文件/目录的核心元数据容器,涵盖存储位置、状态、并发控制等。
-
条件编译成员 扩展了对 exFAT 和文件锁的支持,适应不同文件系统特性和应用场景。
-
状态位(
stat
) 优化簇链操作,区分连续与碎片化存储,提升读写效率。 -
多卷与并发 通过
id
和lockid
确保数据一致性和线程安全。
二:/* File object structure (FIL) */
cpp
typedef struct {
FFOBJID obj; /* Object identifier (must be the 1st member to detect invalid object pointer) */
BYTE flag; /* File status flags */
BYTE err; /* Abort flag (error code) */
FSIZE_t fptr; /* File read/write pointer (Zeroed on file open) */
DWORD clust; /* Current cluster of fpter (invalid when fptr is 0) */
LBA_t sect; /* Sector number appearing in buf[] (0:invalid) */
#if !FF_FS_READONLY
LBA_t dir_sect; /* Sector number containing the directory entry (not used at exFAT) */
BYTE* dir_ptr; /* Pointer to the directory entry in the win[] (not used at exFAT) */
#endif
#if FF_USE_FASTSEEK
DWORD* cltbl; /* Pointer to the cluster link map table (nulled on open, set by application) */
#endif
#if !FF_FS_TINY
BYTE buf[FF_MAX_SS]; /* File private data read/write window */
#endif
} FIL;
FIL 结构体分析总结
FIL 是 FatFs 文件系统库中用于管理 文件对象 的核心数据结构,记录文件操作过程中的状态、位置、缓存及错误信息。其成员根据配置选项(如 FF_FS_READONLY
、FF_USE_FASTSEEK
等)动态调整,支持不同场景下的文件读写需求。
核心成员变量解析
成员变量 | 类型 | 说明 |
---|---|---|
obj |
FFOBJID |
文件对象标识:包含文件所属卷、起始簇号等元数据。必须是第一个成员,用于检测无效指针。 |
flag |
BYTE |
文件状态标志 : - 记录文件打开模式(如 FA_READ 、FA_WRITE )。 - 标记文件是否已关闭或发生错误。 |
err |
BYTE |
错误代码 :记录最近一次文件操作的错误类型(如 FR_DISK_ERR 、FR_NOT_READY )。 |
fptr |
FSIZE_t |
文件读写指针:当前操作位置的字节偏移量(从文件开头计算)。 |
clust |
DWORD |
当前簇号 :与 fptr 对应的簇号,用于快速定位文件数据。 |
sect |
LBA_t |
当前扇区号 :buf 中缓存的扇区号(0 表示 buf 无效)。 |
条件编译扩展成员
-
!FF_FS_READONLY
(读写模式支持)成员变量 类型 说明 dir_sect
LBA_t
目录项所在扇区:记录文件目录项的物理扇区号(exFAT 中无效)。 dir_ptr
BYTE*
目录项指针 :指向 win[]
缓存中的目录项(exFAT 中无效)。 -
FF_USE_FASTSEEK
(快速寻址支持)成员变量 类型 说明 cltbl
DWORD*
簇链接表:用户提供的簇号映射表,加速大文件随机访问。 -
!FF_FS_TINY
(非微小配置)成员变量 类型 说明 buf
BYTE[]
文件数据缓存:存储当前扇区数据,减少磁盘访问次数。
功能与工作流程
-
文件打开
-
初始化
obj
:从目录项中获取文件起始簇号(sclust
)和大小(objsize
)。 -
设置
fptr
和clust
:初始化读写指针为 0,clust
为起始簇号。
-
-
文件读取
-
定位簇和扇区 :根据
fptr
计算目标簇号(通过clust
或 FAT 表遍历)和扇区号。 -
缓存数据 :若
sect
不匹配目标扇区,将数据读入buf
。 -
更新
fptr
和clust
:移动读写指针,记录当前簇号。
-
-
文件写入
-
簇分配 :若文件需要扩展,分配新簇并更新 FAT 表(依赖
dir_sect
和dir_ptr
)。 -
写缓存 :将数据写入
buf
,标记flag
为脏数据,适时写回磁盘。
-
-
错误处理
-
错误记录 :操作失败时,设置
err
为错误代码(如FR_DISK_FULL
)。 -
状态标记 :通过
flag
标记文件为错误状态,后续操作被禁止。
-
配置选项影响
配置宏 | 影响成员变量 | 功能扩展说明 |
---|---|---|
FF_FS_READONLY |
dir_sect , dir_ptr |
禁用目录项修改功能,减少内存占用。 |
FF_USE_FASTSEEK |
cltbl |
允许用户提供簇链接表,加速大文件寻址。 |
FF_FS_TINY |
buf |
禁用私有缓存,依赖外部缓冲区。 |
典型使用示例
cpp
FIL fil;
FRESULT res;
// 打开文件
res = f_open(&fil, "data.txt", FA_READ);
if (res != FR_OK) {
printf("Error: %d\n", fil.err);
return;
}
// 读取文件内容
BYTE buffer[128];
UINT br;
res = f_read(&fil, buffer, sizeof(buffer), &br);
if (res != FR_OK) {
printf("Read error: %d\n", fil.err);
}
// 关闭文件
f_close(&fil);
关键设计思想
-
缓存优化
-
buf
成员:通过缓存当前扇区数据,减少磁盘 I/O 操作。 -
sect
标记:避免重复读取同一扇区,提升性能。
-
-
快速寻址
cltbl
支持:用户可预先生成簇号映射表,将文件偏移直接映射到簇号,减少 FAT 表遍历开销。
-
错误隔离
err
和flag
:明确记录错误原因和文件状态,防止错误传播。
总结
-
FIL 结构体是 FatFs 文件操作的核心,涵盖文件位置、状态、缓存及错误管理。
-
条件编译成员支持灵活配置,适应只读、快速寻址等不同场景。
-
读写流程 通过
fptr
、clust
和sect
协同工作,优化性能和数据一致性。 -
错误处理机制确保操作可追溯,提升系统健壮性。
三:/* Directory object structure (DIR) */
cpp
typedef struct {
FFOBJID obj; /* Object identifier */
DWORD dptr; /* Current read/write offset */
DWORD clust; /* Current cluster */
LBA_t sect; /* Current sector (0:Read operation has terminated) */
BYTE* dir; /* Pointer to the directory item in the win[] */
BYTE fn[12]; /* SFN (in/out) {body[8],ext[3],status[1]} */
#if FF_USE_LFN
DWORD blk_ofs; /* Offset of current entry block being processed (0xFFFFFFFF:Invalid) */
#endif
#if FF_USE_FIND
const TCHAR* pat; /* Pointer to the name matching pattern */
#endif
} DIR;
DIR 结构体分析总结
DIR 是 FatFs 文件系统库中用于管理 目录对象 的核心数据结构,记录目录遍历过程中的状态、位置、缓存及匹配信息。其成员根据配置选项(如 FF_USE_LFN
、FF_USE_FIND
等)动态调整,支持目录项的读取、搜索和长文件名处理。
核心成员变量解析
成员变量 | 类型 | 说明 |
---|---|---|
obj |
FFOBJID |
目录对象标识 :包含目录所属卷、起始簇号等元数据(继承自 FFOBJID )。 |
dptr |
DWORD |
目录项偏移量:当前读取/写入的目录项在目录扇区中的偏移(单位:字节)。 |
clust |
DWORD |
当前簇号:目录遍历过程中当前所在的簇号(用于 FAT32/exFAT 的子目录)。 |
sect |
LBA_t |
当前扇区号:目录数据所在的扇区号(0 表示遍历结束)。 |
dir |
BYTE* |
目录项指针 :指向缓存(win[] )中当前处理的目录项。 |
fn |
BYTE[12] |
短文件名缓冲区 :存储 8.3 格式文件名(如 FILENAME.TXT )。 |
条件编译扩展成员
-
FF_USE_LFN
(长文件名支持)成员变量 类型 说明 blk_ofs
DWORD
长文件名块偏移 :当前长文件名目录项块的偏移( 0xFFFFFFFF
表示无效)。 -
FF_USE_FIND
(目录搜索支持)成员变量 类型 说明 pat
const TCHAR*
匹配模式 :指向文件名匹配模式(如 *.txt
),用于f_findnext()
。
功能与工作流程
1. 目录遍历
-
初始化 :
调用
f_opendir()
打开目录时,FatFs 初始化obj
,记录目录起始簇号(根目录或子目录)。 -
遍历过程:
-
dptr
递增以遍历目录项,sect
和clust
定位物理扇区。 -
dir
指向当前目录项,解析文件名、属性、大小等信息。 -
sect == 0
表示遍历结束。
-
2. 长文件名处理
-
多目录项拼接 :
长文件名(如
"LongFileName.txt"
)由多个目录项组成,blk_ofs
记录当前处理的长名块偏移。 -
编码转换 :
长文件名使用 Unicode 编码(UTF-16 或 UTF-8),需配置
FF_LFN_UNICODE
。
3. 目录搜索
-
模式匹配 :
若启用
FF_USE_FIND
,pat
存储匹配模式(如"*.txt"
),f_findnext()
根据此模式过滤目录项。
配置选项影响
配置宏 | 影响成员变量 | 功能扩展说明 |
---|---|---|
FF_USE_LFN |
blk_ofs |
支持长文件名解析,需额外内存存储长名块。 |
FF_USE_FIND |
pat |
支持目录搜索功能(如 f_findfirst() )。 |
FF_FS_EXFAT |
(隐式影响) | exFAT 目录项结构与 FAT32 不同,需特殊处理。 |
典型使用示例
cpp
DIR dir;
FILINFO fno;
// 打开目录
FRESULT res = f_opendir(&dir, "/");
if (res != FR_OK) return;
// 遍历目录项
while (1) {
res = f_readdir(&dir, &fno);
if (res != FR_OK || fno.fname[0] == 0) break; // 错误或遍历完成
printf("File: %s\n", fno.fname);
}
// 关闭目录
f_closedir(&dir);
关键设计思想
-
高效遍历
-
dptr
和sect
:通过偏移和扇区号快速定位目录项,减少磁盘访问。 -
dir
指针:直接操作缓存数据,避免频繁读取物理扇区。
-
-
兼容性设计
-
短文件名兼容 :
fn
缓冲区存储 8.3 格式文件名,兼容传统 FAT 系统。 -
长文件名扩展 :通过
blk_ofs
支持多目录项拼接,适应现代文件系统需求。
-
-
搜索优化
- 模式匹配 :
pat
成员与f_findnext()
结合,实现高效文件名过滤。
- 模式匹配 :
总结
-
DIR 结构体是 FatFs 目录操作的核心,涵盖目录遍历、长文件名处理和搜索功能。
-
短文件名 与长文件名兼容设计,适应不同文件系统需求。
-
条件编译成员支持灵活配置,平衡功能与资源占用。
-
通过
dptr
、sect
和clust
协同工作,实现高效的目录项遍历。