Fatfs二进制数据分析

本文详细介绍了FATFS文件系统的工作原理,通过分析关键数据结构如FATFS和FIL,解释了如何在SD卡中定位和读取文件。以实际案例result.txt为例,展示了如何使用f_open和f_write函数,并解读了文件系统参数和文件对象的状态。
摘要由CSDN通过智能技术生成

fatfs开源文件系统,不再赘述,笔者主要做嵌入式方向,最近对文件管理感兴趣,说白了对于CPU来说无论是磁盘,ram等输入输出都是0101的数据,sd中也是存储的010的数据,只是最后经过文件系统的解析到我们用户手中便变成了我们可以看到的字符串,汉字,图片等等。于是打算深入学习下fatfs,这种东西就是一通百通的东西,下面进行实际的分析。
ok先看文件系统的数据结构,比较重要的我们需要分析的已经被汉语标注,其他的看英文就懂了,这里的还需要读者去看下Fat的基本原理,也附上链接源码的分析

http://www.cnblogs.com/amanlikethis/p/3793077.html

typedef struct {
	BYTE	fs_type;		/* Filesystem type (0:not mounted) */
	BYTE	pdrv;			/* Associated physical drive */
	BYTE	n_fats;			/* Number of FATs (1 or 2) */
	BYTE	wflag;			/* win[] flag (b0:dirty) */
	BYTE	fsi_flag;		/* FSINFO flags (b7:disabled, b0:dirty) */
	WORD	id;				/* Volume mount ID */
	WORD	n_rootdir;		/* Number of root directory entries (FAT12/16) */
	WORD	csize;			/* Cluster size [sectors] 每个簇的扇区个数,所以簇的地址就是数据开始地址 + 簇的num * 扇区个数 * 512*/

#if FF_USE_LFN
	WCHAR*	lfnbuf;			/* LFN working buffer */
#endif

#if FF_FS_REENTRANT
	FF_SYNC_t	sobj;		/* Identifier of sync object */
#endif
#if !FF_FS_READONLY
	DWORD	last_clst;		/* Last allocated cluster */
	DWORD	free_clst;		/* Number of free clusters */
#endif
#if FF_FS_RPATH
	DWORD	cdir;			/* Current directory start cluster (0:root) */
#endif
	DWORD	n_fatent;		/* Number of FAT entries (number of clusters + 2) */
	DWORD	fsize;			/* Size of an FAT [sectors] fat表的大小 每个数据用32字节*/
	DWORD	volbase;		/* Volume base sector */
	DWORD	fatbase;		/* FAT base sector  FAT表,当数据大于一个簇的大小时需要制定下一个簇在哪里*/
	DWORD	dirbase;		/* Root directory base sector/cluster 根目录扇区在哪里 计算实际地址时需要 dirbase * 512 //因为一个扇区固定大小512byte*/
	DWORD	database;		/* Data base sector 数据扇区在哪里*/

	DWORD	winsect;		/* Current sector appearing in the win[] */
	BYTE	win[FF_MAX_SS];	/* Disk access window for Directory, FAT (and file data at tiny cfg) */
} FATFS;

其次我们需要分析的数据结构是存储文件信息的,这样我们根据这个以及上面的数据结构就能在sd的二进制文件中找到我们存储的数据了

/* File object structure (FIL) */

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) 当前操作的簇 */
	DWORD	sect;			/* Sector number appearing in buf[] (0:invalid) 开始扇区*/
#if !FF_FS_READONLY
	DWORD	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;

我们以我们存在根目录下的result.txt为例分析。
在这里插入图片描述
存放的数据为
在这里插入图片描述
只关心前面正常的数据就行了,测试代码也是网上下载的,嘻嘻嘻。。。。
ok我们在sdk下进行f_open, f_write,然后debug看这两个数据结构的数据如下:
在这里插入图片描述
在这里插入图片描述
ok,此时我们可以看到(注意每个sd卡可能不一样,每个这样分析就可以了)
n_fat:文件系统fat表个数为2个
csize:每个簇里面一个扇区,512字节
dirbase:目录开始扇区为2,转化为地址就是2512=0x400
fatbase:fat表的开始扇区为0x307e,转换为地址就是0x307e
512=0x60Fc00
database:数据开始扇区为0x4000,也就是说从这里开始簇开始计数0,1,2,3,这里的实际地址是0x4000512=0x800000
在来看fil:
看文件的目录地址:dirbase = 0x4000
512 = 0x800000
在这里插入图片描述
sec:开始时0x4005,地址是0x4005*512 = 0x800a00如下
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值