fatfs学习 2Word格式.docx
- 文档编号:22087694
- 上传时间:2023-02-02
- 格式:DOCX
- 页数:18
- 大小:39.67KB
fatfs学习 2Word格式.docx
《fatfs学习 2Word格式.docx》由会员分享,可在线阅读,更多相关《fatfs学习 2Word格式.docx(18页珍藏版)》请在冰豆网上搜索。
/*FAT文件系统依次为:
引导扇区、两个文件分配表、根目录区和数据区*/
BYTEwflag;
/*标记文件是否被改动过,为1时要回写*/
BYTEfsi_flag;
/*标记文件系统信息是否被改动过,为1时要回写*/
WORDid;
/*文件系统挂载ID*/
WORDn_rootdir;
/*根目录区入口(目录项)的个数(用于FAT12/16)*/
#if_MAX_SS!
=512
WORDssize;
/*每扇区的字节数(用于扇区大于512Byte的flash)*/
#endif
#if_FS_REENTRANT
_SYNC_tsobj;
/*允许重入,即定义同步对象,用在tiny中*/
#if!
_FS_READONLY
DWORDlast_clust;
/*最后一个被分配的簇*/
DWORDfree_clust;
/*空闲簇的个数*/
DWORDfsi_sector;
/*存放fsinfo的扇区(用于FAT32)*/
#if_FS_RPATH
DWORDcdir;
/*允许相对路径时用,存储当前目录起始簇(0:
root)*/
DWORDn_fatent;
/*FAT入口数(簇的数目+2)*/
DWORDfsize;
/*每个FAT所占扇区*/
DWORDfatbase;
/*FAT起始扇区*/
DWORDdirbase;
/*根目录起始扇区(FAT32:
Cluster#)*/
DWORDdatabase;
/*数据目录起始扇区*/
DWORDwinsect;
/*当前缓冲区中存储的扇区号*/
BYTEwin[_MAX_SS];
/*单个扇区缓存*/
}FATFS;
文件结构体
/*Fileobjectstructure(FIL)*/
FATFS*fs;
/*所在的fs指针*/
/*所在的fs挂载编号*/
BYTEflag;
/*文件状态*/
BYTEpad1;
/*不知道含义,也未见程序使用*/
DWORDfptr;
/*文件读写指针*/
/*大小*/
DWORDsclust;
/*文件起始簇(fsize=0时为0)*/
DWORDclust;
/*当前簇*/
DWORDdsect;
/*当前数据扇区*/
DWORDdir_sect;
/*包含目录项的扇区*/
BYTE*dir_ptr;
/*Pontertothedirectoryentryinthewindow*/
#if_USE_FASTSEEK
DWORD*cltbl;
/*指向簇链接映射表的指针*/
#if_FS_SHARE
UINTlockid;
/*FilelockID(indexoffilesemaphoretable)*/
_FS_TINY
BYTEbuf[_MAX_SS];
/*Filedataread/writebuffer*/
}FIL;
目录结构体
/*Directoryobjectstructure(DIR)*/
/*同上*/
WORDindex;
/*当前读写索引号*/
/*文件数据区开始簇*/
DWORDsect;
/*当前扇区*/
BYTE*dir;
/*扇区缓存中当前SFN入口指针,SFN含义未知,猜测和LFN类似,与文件名相关*/
BYTE*fn;
/*PointertotheSFN(in/out){file[8],ext[3],status[1]}*/
#if_USE_LFN
WCHAR*lfn;
/*PointertotheLFNworkingbuffer*/
WORDlfn_idx;
/*LastmatchedLFNindexnumber(0xFFFF:
NoLFN)*/
}DIR;
程序移植
移植FATFS主要分3步
1..数据类型:
在integer.h里定义数据类型
2.配置:
ffconf.h里进行配置
ffconf.h里进行配置:
_MCU_ENDIAN,选择你的CPU是大端存储(bigendding)还是小端存储(littleendding),一般的都用的小端存储,1是小端,2是大端。
_FS_TINY:
文件系统为标准的还是微型的,默认为标准的(0);
_FS_READONLY:
文件系统是否为只读,默认为可读写(0),若只读则f_write、f_sync、f_unlink、f_mkdir、f_chmod、f_rename、f_truncate和f_getfree不可用;
_FS_MINIMIZE:
裁剪文件系统的功能,默认为全部功能(0),若为1、2则会移除大部分链接、目录等功能;
_USE_STRFUNC:
是否允许字符串操作,默认为不允许(0),这个看个人需求,一般情况下设置为1即可,如果工作在windows下,为保证文件兼容性(如换行符’\n’和回车符’\r’)建议将此项设置为2;
_USE_MKFS:
是否允许使用f_mkfs函数,默认为0,用于创建文件夹,建议开启;
_USE_FORWARD:
用于允许f_forward函数,只有开启tiny文件系统时才用到,该函数用于将读写的数据立即转存到数据流中,以节省RAM空间;
_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_REENTRANT、_FS_TIMEOUT、_SYNC_t:
这三个选项与文件系统是否允许重入有关,所直白点,就是能否被多线程同时访问,像RTOS中,一般建议开启,_SYNC_t可定义为对应OS中的操作对象,windows下为HANDLE,uCos中为OS_EVENT,vxWorks中为SEMAPHORE。
另外,开启后还需要添加ff_req_grant、ff_rel_grant和ff_del_syncobj三个函数,实际上实现的功能就是申请互斥量、释放互斥量和删除互斥量的意思,可以定义OS封装即可;
_FS_SHARE:
和上面的类似,表示文件系统最大允许同时打开多少文件,默认为0,即只能打开一个。
函数编写:
diskio.c,进行底层驱动编写,6个函数:
disk_initialize,disk_status,disk_read,disk_write,disk_ioctl,get_fattime
disk_initialize
初始化磁盘驱动器
DSTATUSdisk_initialize(BYTEDrive/*物理驱动器号*/);
参数
Drive指定待初始化的物理驱动器号。
返回值
disk_initialize函数返回一个磁盘状态作为结果。
磁盘状态的详情,参考disk_status函数。
描述
disk_initialize函数初始化一个物理驱动器。
函数成功后,返回值中的STA_NOINIT标志被清除。
disk_initialize函数被FatFs模块在卷挂载过程中调用,去管理存储介质的改变。
当FatFs模块起作用时,或卷上的FAT结构可以被瓦解时,应用程序不能调用该函数。
可以使用f_mount函数去重新初始化文件系统。
DSTATUSdisk_initialize(BYTEdrv)
{
u8state;
switch(drv){
case0:
//SD卡
if(!
SD_Detect()){
returnSTA_NODISK;
//没有检测到SD卡,报NOTREADY错误
}
if(uDbgFlg&
SDDEBUGIO)
printf("
SD_Init!
\r\n"
);
state=SD_Init();
if(state==SD_RESPONSE_NO_ERROR){
if(uDbgFlg&
SDERRORIO)
printf("
SDInitError!
%d\r\n"
state);
SD_GetCapacity();
SD_Status=0;
return0;
//初始化成功
}else{
returnSTA_NOINIT;
//其他错误:
初始化失败
case1:
//U盘
UDDEBUGIO)
UDiskInit!
if(DiskInitalCH375()==0)
else
returnSTA_NOINIT;
default:
returnSTA_NOINIT;
//仅支持磁盘0的操作
}
获取当前磁盘的状态
DSTATUSdisk_status(BYTEDrive/*物理驱动器号*/);
Drive指定待确认的物理驱动器号。
磁盘状态,是下列标志的组合:
STA_NOINIT
指示磁盘驱动器还没有被初始化。
当系统复位、磁盘移除和disk_initialize函数失败时,该标志被设置;
当disk_initialize函数成功时,该标志被清除。
STA_NODISK
指示驱动器中没有存储介质。
当安装了磁盘驱动器后,该标志始终被清除。
STA_PROTECTED
指示存储介质被写保护。
在不支持写保护缺口的驱动器上,该标志始终被清除。
当STA_NODISK被设置时,该标志无效。
DSTATUSdisk_status(BYTEdrv)
u8utemp;
//检查SD卡是否插入
SD_Status=1;
returnSTA_NODISK;
}else{
if(SD_Status!
=0){
returnSTA_NOINIT;
}else{
return0;
}
}
utemp=GetStatusCH375();
if(utemp==USB_INT_USB_READY)
elseif(utemp==USB_INT_DISCONNECT)
//仅支持磁盘0操作
}
从磁盘驱动器中读取扇区
DRESULTdisk_read(
BYTEDrive,/*物理驱动器号*/
BYTE*Buffer,/*读取数据缓冲区的指针*/
DWORDSectorNumber,/*起始扇区号*/
BYTESectorCount/*要读取的扇区数*/
Drive指定物理驱动器号。
Buffer存储读取数据的缓冲区的指针。
该缓冲区大小需要满足要读取的字节数(扇区大小*扇区总数。
由上层指定的存储器地址可能会也可能不会以字边界对齐。
SectorNumber
指定在逻辑块地址(LBA)中的起始扇区号。
SectorCount指定要读取的扇区数(1-255)。
RES_OK(0)函数成功
RES_ERROR在读操作过程中发生了不能恢复的硬错误。
RES_PARERR无效的参数。
RES_NOTRDY磁盘驱动器还没被初始化。
DRESULTdisk_read(BYTEdrv,BYTE*buff,DWORDsector,BYTEcount)
u8res=0;
if(uDbgFlg&
SDDEBUGIO)
printf("
diskreadsector:
%u,count:
%u"
sector,count);
case0:
//SPI_SD
if(!
count){
returnRES_PARERR;
//仅支持单磁盘操作,count不能等于0,否则返回参数错误
if(!
NoInst!
returnRES_NOTRDY;
if(count==1){//1个sector的读操作
res=SD_ReadBlock(sector,buff);
}else{//多个sector的读操作
res=SD_ReadMultiBlocks(sector,buff,count);
}
//处理返回值,将SPI_SD_driver.c的返回值转成ff.c的返回值
if(uDbgFlg&
Result:
res);
if(res==SD_RESPONSE_NO_ERROR){
returnRES_OK;
}else{
SDERRORIO)
%u,result:
%u\r\n"
sector,count,res);
SD_Status=2;
returnRES_ERROR;
case1:
//CH375
if(Read_Sector_CH375(sector,count,buff)==0)
returnRES_OK;
else
returnRES_ERROR;
default:
returnRES_PARERR;
向磁盘驱动器中写入扇区
DRESULTdisk_write(
constBYTE*Buffer,/*写入数据缓冲区的指针(可能未对齐)*/
BYTESectorCount/*要写入的扇区数*/
Buffer存储写入数据的缓冲区的指针。
SectorNumber指定在逻辑块地址(LBA)中的起始扇区号。
SectorCount指定要写入的扇区数(1-255)。
RES_WRPRT存储介质被写保护。
在只读配置中,不需要此函数。
DRESULTdisk_write(BYTEdrv,constBYTE*buff,DWORDsector,BYTEcount)
u8res;
diskwritesector:
%ucount:
%u"
printf("
//读写操作
if(count==1){
res=SD_WriteBlock(sector,(uint8_t*)buff);
res=SD_WriteMultiBlocks(sector,(uint8_t*)buff,count);
if(res==SD_RESPONSE_NO_ERROR){//返回值转换
}else{
SD_Status=3;
if(Write_Sector_CH375(sector,count,(u8*)buff)==0)
returnRES_ERROR;
控制设备特定的功能以及磁盘读写以外的其它功能。
DRESULTdisk_ioctl(
BYTEDrive,/*驱动器号*/
BYTECommand,/*控制命令代码*/
void*Buffer/*数据传输缓冲区*/
Drive指定驱动器号(1-9)。
Command指定命令代码。
Buffer取决于命令代码的参数缓冲区的指针。
当不使用时,指定一个NULL指针。
RES_OK(0)函数成功。
RES_ERROR发生错误。
RES_PARERR无效的命令代码。
FatFs模块只使用下述与设备无关的命令,没有使用任何设备相关功能。
命令
CTRL_SYNC
确保磁盘驱动器已经完成等待写过程。
当磁盘I/O模块有一个写回高速缓存时,立即刷新扇区。
在只读配置中,不需要该命令。
GET_SECTOR_SIZE
返回驱动器的扇区大小赋给Buffer指向的WORD变量。
在单个扇区大小配置中(_MAX_SS为512),不需要该命令。
GET_SECTOR_COUNT
返回总扇区数赋给Buffer指向的DWORD变量。
只在f_mkfs函数中,使用了该命令。
GET_BLOCK_SIZE
返回以扇区为单位的存储阵列的擦除块大小赋给Buffer指向的DWORD变量。
当擦除块大小未知或是磁盘设备时,返回1。
DRESULTdisk_ioctl(BYTEdrv,BYTEctrl,void*buff)
DRESULTres;
DISK_INFO_CH375disk_info;
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- fatfs学习 fatfs 学习