FATFS文件系统剖析(全)
更新时间:2023-03-13 07:19:02 阅读量: 教育文库 文档下载
- FATFS文件系统推荐度:
- 相关推荐
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,所以其每个分区最大容量为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 文件系统实现。当然要实现具体的应用移植,自己要根据diskio.h实现其diskio。c 底层驱动。 diskio.h : 底层驱动头文件
ff.h : 文件系统实现头文件,定义有文件系统所需的数据结构 ff.c : 文件系统的具体实现
如下开始逐个文件加以分析:
integer.h :仅实现数据类型重定义,增加系统的可移植性。
ffconf.h : 文件系统配置---逐个配置,先配置实现一个最小的fat文件系统,下面来分析各配置选项:
#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:Disable 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 - Simplified 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 */
#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 */ 只有一个分区
#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
#define _FS_SHARE 0 /* 0:Disable or >=1:Enable */ 共享选项 如上已经配置成了一个最小的fat文件系统。
Diskio.h:底层驱动头文件,就一些状态宏的定义和底层驱动函数的申明,看源码一目了然。 实现相应的 diskio.c 。
根据我的配置:只需要根据不同的存储介质实现相应的 disk_initialize ,disk_status,disk_read三个函数就够了,
我在这里实现上s3c2440上的SD卡驱动: DSTATUS disk_initialize (BYTE 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时系统没有被挂载
BYTE drv; // 物理磁盘驱动号
BYTE csize; // 每簇的扇区数目, 簇是文件数据分配的基本单位 BYTE n_fats; // 文件分配表的数目,一般为两个(一个备份fat表) //Fatfs文件系统应该是:引导扇区,文件分配表2个,根目录区,和数据区
BYTE wflag; // 文件活动窗体是否改动标志,为1要回写 BYTE fsi_flag; // 文件信息回写标志 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_RPATH
DWORD cdir; //使用相对路径,文件系统的当前起始路径 0(root 路径) #endif
DWORD n_fatent; //文件分配表占用的扇区 n_fatent=数据簇数目+2 DWORD fsize; //每FAT表有多少个扇区
DWORD fatbase; //文件分配表开始扇区
DWORD dirbase; // 如果是FAT32,根目录开始扇区需要首先得到 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 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
#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 dir) DWORD clust; // 目前处理的簇 DWORD sect; // 目前簇里对应的扇区
BYTE* dir; //指向当前在win[]中的短文件名入口项/* Pointer to the current SFN entry in the win[]
BYTE* fn; //指向短文件名 (in/out) {file[8],ext[3],status[1]} #if _USE_LFN
WCHAR* lfn; //指向长文件名缓冲 /* Pointer to the LFN working buffer */ WORD lfn_idx; /* Last matched LFN index number (0xFFFF: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 fname[13]; /* Short file name (8.3 format) */ #if _USE_LFN //长文件名支持
TCHAR* lfname; /* Pointer to the LFN buffer */ UINT lfsize; /* Size of LFN buffer in TCHAR */
#endif } FILINFO;
结构是搞清楚了,但其里面的具体联系怎么也还收理不清楚。只有看ff.c来疏通了! 里面东西还是蛮多的,咋一看,3000多行类(太多,在这里就根据我的配置,进行逐个分析吧),从头到尾,一个一个来。
首先是三个内存操作和以个字符查找处理函数,不说不解释。 然后是: 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 cluster# */ FATFS *fs, /* File system object */ DWORD clst /* Cluster# to be converted */ )
计算簇clst在对应文件系统fs里面的扇区号
DWORD get_fat ( /* 0xFFFFFFFF:Disk error, 1:Internal error, Else:Cluster status */ FATFS *fs, /* File system object */
DWORD clst /* Cluster# to get the link information */ )
获取簇clst在文件系统fs中FAT表里面fat入口
static
FRESULT dir_sdi (
DIR *dj, /* Pointer to directory object */ WORD idx /* Directory index number */ )
根据根目录索引号idx获取相应的目录信息存储到dj结构里面 static
FRESULT dir_next ( /* 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 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 */ )
创建一个文件名为 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 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 **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: Invalid */ FATFS *fs, /* Pointer to the file system object */
WORD id /* Member id of the target object to be checked */ )
检测文件系统是否可用
如下是现配置好的文件系统引出的四个接口函数:
FRESULT f_mount ( //挂在一个逻辑的文件系统
BYTE 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 */ )
文件打开, 包括(真正的文件系统初始化,系统检测)
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 */ ) 文件读
FRESULT f_close (
FIL *fp /* Pointer to the file object to be closed */ ) 文件关闭
转自博客,供大家相互交流!
正在阅读:
FATFS文件系统剖析(全)03-13
应收会计岗位职责02-25
会议平板操作说明手册07-03
四风问题自我剖析材料02-19
电大 2013秋 INTETNET网络系统与实践 平时作业一01-17
Linux基本网络配置09-25
农民工医疗保险现状及选择模式 - 图文09-12
互动式教学在初中语文阅读教学中的运用分析03-14
三升四优生训练题104-22
- exercise2
- 铅锌矿详查地质设计 - 图文
- 厨余垃圾、餐厨垃圾堆肥系统设计方案
- 陈明珠开题报告
- 化工原理精选例题
- 政府形象宣传册营销案例
- 小学一至三年级语文阅读专项练习题
- 2014.民诉 期末考试 复习题
- 巅峰智业 - 做好顶层设计对建设城市的重要意义
- (三起)冀教版三年级英语上册Unit4 Lesson24练习题及答案
- 2017年实心轮胎现状及发展趋势分析(目录)
- 基于GIS的农用地定级技术研究定稿
- 2017-2022年中国医疗保健市场调查与市场前景预测报告(目录) - 图文
- 作业
- OFDM技术仿真(MATLAB代码) - 图文
- Android工程师笔试题及答案
- 生命密码联合密码
- 空间地上权若干法律问题探究
- 江苏学业水平测试《机械基础》模拟试题
- 选课走班实施方案
- 剖析
- 文件
- 系统
- FATFS
- 质点动力学-非物理类试题(附解析)-中国科技大学-02
- 中职学校图书馆信息化建设方案探析
- 地震勘探原理
- 2015—2016英语人教新课标八下Unit1 Whats the matter同步检测题(一)及
- 劳保用品佩戴参考资料
- 交通安全事故毕业论文中英文资料外文翻译文献
- 名人故事:拉斐尔 - 名人故事
- PCT及CRP在肺部感染病原体鉴别诊断中的临床价值
- 1、江苏省学前教育学会“十三五”研究课题指南
- 反垄断与反不正当竞争执法专题网络培训班总复习
- 比较文学end
- 全国2009年01月高等教育自学考试婚姻家庭法原理与实务试题
- 中国石油大学计算机网络课程设计-第三次在线作业
- 2018-2019年小学语文北京版《一年级上》《汉语拼音》《8 j q x》综合测试试卷含答案
- 水暖分户验收学习资料
- 绩效考核制度1
- 高中英语(高升专)机考复习模拟题库2(3)
- 琅琊路小学苏教版语文读读背背拓展延伸积累
- 综合研判方案
- 《学习伴成长》教学设计