c语言sscanf函数的用法是什么
502
2022-11-16
详细了解并学习FatFS文件系统的基本原理
/* File system object structure (FATFS) */
typedef struct {
BYTE drv; /* 物理驱动号,一般为0*/
BYTE n_fats; /* 文件分配表的数目(1,2) */
/*FAT文件系统依次为:引导扇区、两个文件分配表、根目录区和数据区*/
BYTE fsi_flag; /* 标记文件系统信息是否被改动过,为1时要回写*/
WORD id; /* 文件系统挂载ID */
WORD n_rootdir; /* 根目录区入口(目录项)的个数(用于FAT12/16)*/
WORD ssize; /* 每扇区的字节数(用于扇区大于512Byte的flash) */
#endif
#if _FS_REENTRANT
#endif
#if !_FS_READONLY
DWORD last_clust; /* 最后一个被分配的簇*/
DWORD free_clust; /* 空闲簇的个数*/
DWORD fsi_sector; /* 存放fsinfo的扇区(用于FAT32) */
#endif
#if _FS_RPATH
DWORD cdir; /* 允许相对路径时用,存储当前目录起始簇(0:root)*/
#endif
DWORD n_fatent; /* FAT入口数(簇的数目 + 2)*/
DWORD fsize; /* 每个FAT所占扇区*/
DWORD fatbase; /* FAT起始扇区*/
DWORD dirbase; /* 根目录起始扇区(FAT32:Cluster#) */
DWORD database; /* 数据目录起始扇区*/
DWORD winsect; /* 当前缓冲区中存储的扇区号*/
BYTE win[_MAX_SS]; /* 单个扇区缓存*/
} FATFS;
然后是与之相关的文件和文件夹结构体,附上具体注释:
view plaincopy to clipboardprint?
/* File object structure (FIL) */
typedef struct {
FATFS* fs; /* 所在的fs指针*/
WORD id; /* 所在的fs挂载编号*/
BYTE flag; /* 文件状态*/
DWORD fptr; /* 文件读写指针*/
DWORD fsize; /* 大小*/
DWORD sclust; /* 文件起始簇(fsize=0时为0) */
DWORD clust; /* 当前簇*/
DWORD dsect; /* 当前数据扇区*/
#if !_FS_READONLY
DWORD dir_sect; /* 包含目录项的扇区 */
BYTE* dir_ptr; /* Ponter to the directory entry in the window */
#endif
#if _USE_FASTSEEK
DWORD* cltbl; /*指向簇链接映射表的指针*/
#endif
#if _FS_SHARE
UINT lockid; /* File lock ID (index of file semaphore table) */
#endif
#if !_FS_TINY
BYTE buf[_MAX_SS]; /* File data read/write buffer */
#endif
} FIL;
/* File object structure (FIL) */typedef struct {FATFS*fs;/* 所在的fs指针*/WORDid;/* 所在的fs挂载编号*/BYTEflag;/* 文件状态*/BYTEpad1; /* 不知道含义,也未见程序使用*/DWORDfptr;/* 文件读写指针*/DWORDfsize;/* 大小*/DWORDsclust;/* 文件起始簇(fsize=0时为0) */DWORDclust;/* 当前簇*/DWORDdsect;/* 当前数据扇区*/#if !_FS_READONLYDWORDdir_sect;/* 包含目录项的扇区 */BYTE*dir_ptr;/* Ponter to the directory entry in the window */#endif#if _USE_FASTSEEKDWORD*cltbl;/*指向簇链接映射表的指针*/#endif#if _FS_SHAREUINTlockid;/* File lock ID (index of file semaphore table) */#endif#if !_FS_TINYBYTEbuf[_MAX_SS];/* File data read/write buffer */#endif} FIL;
下面是目录的:
view plaincopy to clipboardprint?
/* Directory object structure (DIR) */
typedef struct {
FATFS* fs; /* 同上*/
WORD id;
WORD index; /* 当前读写索引号 */
DWORD sclust; /* 文件数据区开始簇*/
DWORD clust; /* 当前簇*/
DWORD sect; /* 当前扇区*/
BYTE* dir; /* 扇区缓存中当前SFN入口指针,SFN含义未知,猜测和LFN类似,与文件名相关*/
BYTE* fn; /* Pointer to the SFN (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;
/* Directory object structure (DIR) */typedef struct {FATFS*fs;/* 同上*/WORDid;WORDindex;/* 当前读写索引号 */DWORDsclust;/* 文件数据区开始簇*/DWORDclust;/* 当前簇*/DWORDsect;/* 当前扇区*/BYTE*dir;/* 扇区缓存中当前SFN入口指针,SFN含义未知,猜测和LFN类似,与文件名相关*/BYTE*fn;/* Pointer to the SFN (in/out) {file[8],ext[3],status[1]} */#if _USE_LFNWCHAR*lfn;/* Pointer to the LFN working buffer */WORDlfn_idx;/* Last matched LFN index number (0xFFFF:No LFN) */#endif} DIR;
熟悉了代码结构后,现在开始作修改了,首先修改ffconf.h文件配置与硬件相关的文件系统特性,然后自己添加一套底层操作即可。先看ffconf.h,里面定义了很多宏,可以根据自己需要一一配置:
先看功能配置:
_FS_TINY:文件系统为标准的还是微型的,默认为标准的(0);
_FS_READONLY:文件系统是否为只读,默认为可读写(0),若只读则f_write、f_sync、 f_unlink、f_mkdir、f_chmod、f_rename、f_truncate和f_getfree不可用;
_USE_MKFS:是否允许使用f_mkfs函数,默认为0,用于创建文件夹,建议开启;
_USE_FASTSEEK:是否开启快速索引,默认为0,开启后,会使用FIL结构体中的cltbl元素来加快搜索;
_CODE_PAGE:指定目标系统使用的OEM代码页,默认为日语(932),改为936简体中文;OEM是什么意思呢?在OS编码中,unicode是一种双字节字符编码,无论中文还是英文,或者其他语言统一到2个字节,它与现有的任何编码(ASCII,GB等)都不兼容。WindowsNT(2000)的内核即使用该编码,所有数据进入内核前转换成UNICODE,退出内核后在转换成版本相关的编码(通常称为OEM,在简体中文版下即为GB);
_USE_LEN、_MAX_LEN、_LFN_UNICODE:这三个的意思不是很清楚,但是确定是与长文件名有关的,不建议开启,否则又要多加函数,麻烦;
_FS_RPATH:是否允许相对路径,让我选择就不开启,否则逻辑变得复杂不说,代码量也变多了一些;
再看硬件相关配置:
_VOLUMES:磁盘(flash)逻辑卷数,默认为1,不建议修改;
_MAX_SS:扇区大小,默认512Byte,最大可设置4096Byte;
_MULTI_PARTITION:分区选项,默认为0,即一个分区,若想要多分区可自行设置;
_USE_ERASE:是否允许扇区擦除,默认为0,若开启则要在disk_ioctl函数中添加擦除命令代码;
最后是文件系统配置:
_WORD_ACCESS:数据递进格式,默认为0,即以字节为单位递进,兼容性更强,若你的系统最新单位为字(2Byte),则可设为1;
_FS_SHARE:和上面的类似,表示文件系统最大允许同时打开多少文件,默认为0,即只能打开一个。
在配置这些选项的时候,可以根据定义阅读ff.c文件中的相关代码,基本上能对整体的结果有了了解,完成了ffconf.h后,再就是编写底层接口了,在新一点的FatFs中,并未提供函数接口模版,可以下老版的拷过来,也可以打开doc文件夹下的帮助文档00index_e.htm文件,里面有底层函数接口的格式及各个参数的描述。至于底层驱动,我只做过spi flash的,这个可以参考我上一篇文章。需要注意的是,底层读写函数中的参数sector指的是扇区的序号,需要自己换算成驱动接口中的字节位置。
到这里,移植基本完成了,如果你的文件系统出现LD_WORD(ptr) (WORD)(*(WORD*)(BYTE*)(ptr))有问题(数据异常终止DATA ABORT exception之类的)的情况,请百度搜索“转一篇比较详细介绍FatFS文件系统移植的文章”就可以搞定了,那里有详细的解决办法。
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~