《2022年FATFS文件系统剖析 .pdf》由会员分享,可在线阅读,更多相关《2022年FATFS文件系统剖析 .pdf(12页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、FATFS 文件系统剖析1:FAT16 :数据按照其不同的特点和作用大致可分为5 部分: MBR 区、 DBR 区、 FAT 区、 DIR 区和DATA 区,相比 fat12 多了 DBR 区 Main boot record: MBR( 0-1bdh )磁盘参数存放DPT ( 1beh-1fdh )磁盘分区表55, aa 分区结束标志 DBR (Dos Boot Record)是操作系统引导记录区的意思FAT 区(有两个,一个备份):对于fat16 ,每一个 fat 项 16 位,所以可寻址的簇项数为 65535( 2 的 16 次方)。 而其每簇大小不超过 32k, 所以其每个分区最大容量
2、为2G 。 fat32 ,每一个 fat 项 32 位,可寻址簇数目为2 的 32 次方。DIR 区(根目录区):紧接着第二FAT 表(即备份的FAT 表)之后,记录着根目录下每个文件(目录)的起始单元,文件的属性等。定位文件位置时,操作系统根据DIR 中的起始单元,结合FAT 表就可以知道文件在硬盘中的具体位置和大小了。DATA 区:实际文件内容存放区。FAT32 :暂时放在这里,不讨论!Fatfs :嵌入式 fat 文件系统,支持fat16 , fat32 。包含有 ff.h,diskio.h,integer.h,ffconf.h 四个头文件以及ff.c 文件系统实现。 当然要实现具体的应
3、用移植,自己要根据diskio.h 实现其 diskio 。c 底层驱动。diskio.h : 底层驱动头文件ff.h : 文件系统实现头文件,定义有文件系统所需的数据结构ff.c : 文件系统的具体实现名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 1 页,共 12 页 - - - - - - - - - 如下开始逐个文件加以分析:integer.h :仅实现数据类型重定义,增加系统的可移植性。ffconf.h : 文件系统配置 -逐个配置,先配置实现一个最小的fat 文件系统 ,
4、下面来分析各配置选项:#define _FFCONF 8255 /版本号#define _FS_TINY 0 /* 0:Normal or 1:Tiny */ /在这里与先前版本有些许变化,是通过配置头配置两种不同大小的文件系统,这里配置为0。#define _FS_READONLY 1/定义文件系统只读,也就不能写修改,在此定义为 1,这样文件系统会大大缩小,简化学习理解过程。#define _FS_MINIMIZE 3 /* 0 to 3 */ 这个选项是用于过滤掉一些文件系统功能,为 0 时是全功能, 3 是功能实现最小#define _USE_STRFUNC 0 /* 0:Disabl
5、e or 1/2:Enable */ 是否使用字符串文件接口,为0,不使用#define _USE_MKFS 0 /* 0:Disable or 1:Enable */ 制作文件系统,这个功能实现是还要 _FS_READONLY=0 #define _USE_FORWARD 0 /* 0:Disable or 1:Enable */ f_forward function 实现还需 _FS_TINY =1#define _USE_FASTSEEK 0 /* 0:Disable or 1:Enable */ 快速查找功能 #define _CODE_PAGE 936 / 936 - Simplif
6、ied Chinese GBK (DBCS, OEM, Windows)#define _USE_LFN 0/* 0 to 3 */ 0:不使用长文件名#define _MAX_LFN 255/* Maximum LFN length to handle (12 to 255) */ #define _LFN_UNICODE 0 /* 0:ANSI/OEM or 1:Unicode */ 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 2 页,共 12 页 - - - - - - -
7、 - - #define _FS_RPATH 0 /* 0 to 2 */ 不使用相对路径/*-/ / Physical Drive Configurations /-*/ #define _VOLUMES 1 /* Number of volumes (logical drives) to be used. */ #define _MAX_SS 512 /* 512, 1024, 2048 or 4096 */ 512 字节每扇区 #define _MULTI_PARTITION 0 /* 0:Single partition or 1:Multiple partition */ 只有一个分
8、区#define _USE_ERASE 0 /* 0:Disable or 1:Enable */ /* To enable sector erase feature, set _USE_ERASE to 1. */ /*-/ / System Configurations /-*/ #define _WORD_ACCESS 0 /* 0 or 1 */ 0: Byte-by-byte access. /* Include a header file here to define sync object types on the O/S */ /* #include , , or ohters
9、. */ #define _FS_REENTRANT 0 /* 0:Disable or 1:Enable */ 同步选项#define _FS_TIMEOUT 1000 /* Timeout period in unit of time ticks */ #define _SYNC_t HANDLE /* O/S dependent type of sync object. e.g. HANDLE, OS_EVENT*, ID and etc. */ #define _FS_SHARE 0 /* 0:Disable or =1:Enable */ 共享选项如上已经配置成了一个最小的fat 文
10、件系统。Diskio.h: 底层驱动头文件, 就一些状态宏的定义和底层驱动函数的申明,看源码一目了然。实现相应的diskio.c 。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 3 页,共 12 页 - - - - - - - - - 根据我的配置:只需要根据不同的存储介质实现相应的disk_initialize ,disk_status ,disk_read三个函数就够了,我在这里实现上s3c2440 上的 SD 卡驱动:DSTATUS disk_initialize (BYTE
11、 nDisk) return 1; DSTATUS disk_status (BYTE nDisk) return 1; DRESULT disk_read (BYTE nDisk, BYTE* b, DWORD c, BYTE d) return 0; 编译报错get_fattime 没实现:DWORD get_fattime (void) return 0; 转自博客,供大家相互交流!FATFS 文件系统剖析2:分析下 ff.h 和 ff.c 两个文件。先来分析 ff.h 中定义的几个结构体:typedef struct BYTE fs_type; / 系统类型,为0 时系统没有被挂载名师
12、资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 4 页,共 12 页 - - - - - - - - - BYTE drv; / 物理磁盘驱动号 BYTE csize; / 每簇的扇区数目,簇是文件数据分配的基本单位 BYTE n_fats; / 文件分配表的数目,一般为两个(一个备份fat 表) /Fatfs 文件系统应该是:引导扇区,文件分配表2 个,根目录区,和数据区 BYTE wflag; / 文件活动窗体是否改动标志,为1 要回写 BYTE fsi_flag; / 文件信息回写
13、标志 WORD id; / 文件系统加载id 号 WORD n_rootdir; / 根目录区目录项数目(针对FAT12/16 ,FAT32 不使用)#if _MAX_SS != 512 WORD ssize; / 每扇区多少字节#endif #if _FS_REENTRANT _SYNC_t sobj; / 允许重入,则定义同步对象#endif #if !_FS_READONLY DWORD last_clust; / 最新分配的簇 DWORD free_clust; / 空闲簇 DWORD fsi_sector; / 文件信息扇区(仅用于FAT32 )#endif #if _FS_RPAT
14、H DWORD cdir; /使用相对路径,文件系统的当前起始路径0(root 路径)#endif DWORD n_fatent; /文件分配表占用的扇区 n_fatent= 数据簇数目 +2 DWORD fsize; /每 FAT 表有多少个扇区名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 5 页,共 12 页 - - - - - - - - - DWORD fatbase; /文件分配表开始扇区 DWORD dirbase; / 如果是 FAT32 ,根目录开始扇区需要首先得到
15、 DWORD database; / 数据起始扇区 DWORD winsect; / win 中当前指定的扇区 BYTE win_MAX_SS; /扇区操作缓存 FATFS; typedef struct FATFS* fs; / 指向的文件系统 WORD id; / 自身文件系统挂载id 号即 fs-id BYTE flag; / 文件状态 BYTE pad1; /文件在簇里面扇区偏移( 0-fs-csize ) DWORD fptr; /文件当前读写指针位置,当文件打开时为0 DWORD fsize; /文件大小(按字节计算) DWORD org_clust; / 文件起始簇(0 when
16、 fsize=0) DWORD curr_clust; / 文件当前操作簇 DWORD dsect; / 文件当前操作扇区#if !_FS_READONLY DWORD dir_sect; / 包含路径入口的扇区号 BYTE* dir_ptr; / 目录入口指针#endif #if _USE_FASTSEEK DWORD* cltbl; /指向查找映射表的簇(null on file open) #endif #if _FS_SHARE UINT lockid; / 文件锁ID 号 (index of file semaphore table) #endif 名师资料总结 - - -精品资料欢
17、迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 6 页,共 12 页 - - - - - - - - - #if !_FS_TINY BYTE buf_MAX_SS; / 文件读写缓存#endif FIL; typedef struct FATFS* fs; / 对应的文件系统 WORD id; / 自身文件系统挂载id 号即 fs-id WORD index; / 目前读写索引号 /* Current read/write index number */ DWORD sclust; / 目录表起始簇(0:Root
18、dir) DWORD clust; / 目前处理的簇 DWORD sect; / 目前簇里对应的扇区 BYTE* dir; / 指向当前在win 中的短文件名入口项/* Pointer to the current SFN entry in the win BYTE* fn; /指向短文件名 (in/out) file8,ext3,status1 #if _USE_LFN WCHAR* lfn; /指向长文件名缓冲 /* Pointer to the LFN working buffer */ WORD lfn_idx; /* Last matched LFN index number (0
19、xFFFF:No LFN) */ #endif DIR; typedef struct /文件目录表项大小 =4+2+2+1+13 DWORD fsize; /* File size */ WORD fdate; /* Last modified date */ WORD ftime; /* Last modified time */ BYTE fattrib; /* Attribute */ / 文件属性 TCHAR fname13; /* Short file name (8.3 format) */ #if _USE_LFN /长文件名支持 TCHAR* lfname; /* Point
20、er to the LFN buffer */ UINT lfsize; /* Size of LFN buffer in TCHAR */ 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 7 页,共 12 页 - - - - - - - - - #endif FILINFO; 结构是搞清楚了,但其里面的具体联系怎么也还收理不清楚。只有看ff.c 来疏通了!里面东西还是蛮多的,咋一看,3000 多行类(太多,在这里就根据我的配置,进行逐个分析吧),从头到尾,一个一个来。首先是三个内存
21、操作和以个字符查找处理函数,不说不解释。然后是:static FRESULT move_window ( FATFS *fs, /* File system object */ DWORD sector /* Sector number to make appearance in the fs-win */ ) /* Move to zero only writes back dirty window */ 该函数就是把指定扇区sector 中的数据读到fs-win 里面DWORD clust2sect ( /* !=0: Sector number, 0: Failed - invalid
22、cluster# */ FATFS *fs, /* File system object */ DWORD clst /* Cluster# to be converted */ ) 计算簇 clst 在对应文件系统fs 里面的扇区号DWORD get_fat ( /* 0 xFFFFFFFF:Disk error, 1:Internal error, Else:Cluster status */ FATFS *fs, /* File system object */ DWORD clst /* Cluster# to get the link information */ ) 获取簇 cls
23、t 在文件系统fs 中 FAT 表里面 fat 入口名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 8 页,共 12 页 - - - - - - - - - static FRESULT dir_sdi ( DIR *dj, /* Pointer to directory object */ WORD idx /* Directory index number */ ) 根据根目录索引号idx 获取相应的目录信息存储到dj 结构里面static FRESULT dir_next (
24、/* FR_OK:Succeeded, FR_NO_FILE:End of table, FR_DENIED:EOT and could not stretch */ DIR *dj, /* Pointer to directory object */ int stretch /* 0: Do not stretch table, 1: Stretch table if needed */ ) 获取当前目录项的索引值+1 ,对应的目录项信息static FRESULT dir_find ( DIR *dj /* Pointer to the directory object linked to
25、 the file name */ ) 在目录表中查找与dj-fn 相同文件名的目录项static FRESULT create_name ( DIR *dj, /* Pointer to the directory object */ const TCHAR *path /* Pointer to pointer to the segment in the path string */ )名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 9 页,共 12 页 - - - - - -
26、- - - 创建一个文件名为path 指向的dj 目录项static FRESULT follow_path ( /* FR_OK(0): successful, !=0: error code */ DIR *dj, /* Directory object to return last directory and found object */ const TCHAR *path /* Full-path string to find a file or directory */ )获取文件路径path 对应的目录项填入dj 里面static BYTE check_fs ( /* 0:The
27、 FAT BR, 1:Valid BR but not an FAT, 2:Not a BR, 3:Disk error */ FATFS *fs, /* File system object */ DWORD sect /* Sector# (lba) to check if it is an FAT boot record or not */ )读取文件系统fs 的一号扇区,进行MBR 检查,文件系统类型区分static FRESULT chk_mounted ( /* FR_OK(0): successful, !=0: any error occurred */ const TCHAR
28、 *path, /* Pointer to pointer to the path name (drive number) */ FATFS *rfs, /* Pointer to pointer to the found file system object */ BYTE chk_wp /* !=0: Check media write protection for write access */ )测试文件系统是否已挂在,如没有,就进行挂载,文件系统结构初始化static FRESULT validate ( /* FR_OK(0): The object is valid, !=0:
29、Invalid */ FATFS *fs, /* Pointer to the file system object */ 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 10 页,共 12 页 - - - - - - - - - WORD id /* Member id of the target object to be checked */ )检测文件系统是否可用如下是现配置好的文件系统引出的四个接口函数:FRESULT f_mount ( /挂在一个逻辑的文件系统 BYTE
30、vol, /* Logical drive number to be mounted/unmounted */ FATFS *fs /* Pointer to new file system object (NULL for unmount)*/ )系统挂载FRESULT f_open ( FIL *fp, /* Pointer to the blank file object */ const TCHAR *path, /* Pointer to the file name */ BYTE mode /* Access mode and file open mode flags */ )文件
31、打开,包括(真正的文件系统初始化,系统检测)FRESULT f_read ( FIL *fp, /* Pointer to the file object */ void *buff, /* Pointer to data buffer */ UINT btr, /* Number of bytes to read */ UINT *br /* Pointer to number of bytes read */ )文件读名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 11 页,共 12 页 - - - - - - - - - FRESULT f_close ( FIL *fp /* Pointer to the file object to be closed */ )文件关闭转自博客,供大家相互交流!名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 12 页,共 12 页 - - - - - - - - -