LinuxGod

LinuxGod.net
Linux大神网——精选每一篇高品质的技术干货
  1. 首页
  2. 开源快讯
  3. 正文

FATFS文件系统负责管理和存储文件信息的特点及应用

2023年9月17日 114点热度

一、文件系统

负责管理和储存文件信息的软件机构称为文件管理系统,简称文件系统。即在c盘上组织文件的方式。

常用的文件系统:

FATFS文件系统

FATFS是一个完全免费开源的FAT文件系统模块linux运维博客,专门为大型的嵌入式系统而设计。完全用标准C语言编撰,所以具有良好的硬件平台独立性。可以移植到8051、PIC、AVR、SH、Z80、H8、ARM等系列单片机上而只需做简单的更改。它支持FATl2、FATl6和FAT32,支持多个储存媒介;有独立的缓冲区,可以对多个文件进行读/写,并非常对8位单片机和16位单片机做了优化。

FATFS文件系统特征

二、FATFS模块层次结构

①、底层插口,包括储存媒介读/写插口(diskI/O)和供给文件创建更改时间的实时时钟,须要我们依照平台和储存介质编撰移植代码。

②、中间层FATFS模块linux支持哪些文件系统,默认的文件系统是什么?,实现了FAT文件读/写合同。FATFS模块提供的是ff.c和ff.h。除非有必要,使用者通常不用更改,使用时将头文件直接包含进去即可。

③、最顶楼是应用层,使用者无需理会FATFS的内部结构和复杂的FAT合同,只须要调用FATFS模块提供给用户的一系列应用插口函数,如f_openlinux支持哪些文件系统,默认的文件系统是什么?,f_read,f_write和f_close等,就可以像在PC上读/写文件那样简单。

三、FATFS文件系统包

FATFS文件系统包下载地址

该网站富含FATFS文件包,也有相应函数的介绍和示范。

FATFS文件系统包结构

四、FATFS文件系统移植

1、ffconf.h:FATFS关键配置文件

五、FATFS移植步骤

1、数据类型:在integer.h上面去定义好数据的类型。这儿须要了解你用的编译器的数据类型,并依照编译器定义好数据类型。

2、配置:通过ffconf.h配置FATFS的相关功能linux 删除文件夹,以满足你的须要。

3、函数编撰:打开diskio.c,进行底层驱动编撰,通常须要编撰6个插口函数

①、disk_initialize函数

②、disk_status函数

③、disk_read函数

④、disk_write函数

⑤、disk_ioctl函数

⑥、get_fattime函数

六、FATFS开放函数

f_mount - 注册/注销一个工作区域(Work Area)
f_open - 打开/创建一个文件
f_close - 关闭一个文件
f_read - 读文件
f_write - 写文件
f_lseek - 移动文件读/写指针
f_truncate -截断文件
f_sync -  冲洗缓冲数据 Flush Cached Data
f_forward - 直接转移文件数据到一个数据流
f_stat - 获取文件状态
f_opendir - 打开一个目录 
f_closedir -关闭一个已经打开的目录
f_readdir - 读取目录条目
f_mkdir - 创建一个目录
f_unlink -删除一个文件或目录
f_chmod -  改变属性(Attribute)
f_utime -改变时间戳(Timestamp)
f_rename - 重命名/移动一个文件或文件夹
f_chdir - 改变当前目录
f_chdrive - 改变当前驱动器
f_getcwd -  获取当前工作目录 
f_getfree - 获取空闲簇 Get Free Clusters
f_getlabel - Get volume label
f_setlabel - Set volume label
f_mkfs - 在驱动器上创建一个文件系统
f_fdisk - Divide a physical drive
f_gets - 读一个字符串
f_putc - 写一个字符
f_puts - 写一个字符串
f_printf - 写一个格式化的字符串
f_tell - 获取当前读/写指针
f_eof - 测试文件结束
f_size - 获取文件大小
f_error - 测试文件上的错误

七、diskio.c代码展示

其中SD卡函数详情看上一讲

#include "diskio.h"		/* FatFs lower layer API */
#include "sdio_sdcard.h"
#include "w25qxx.h"
#include "malloc.h"		
						  
// 	 
#define SD_CARD	 0  //SD卡,卷标为0
#define EX_FLASH 1	//外部flash,卷标为1
#define FLASH_SECTOR_SIZE 	512			  
//对于W25Q128
//前12M字节给fatfs用,12M字节后,用于存放字库,字库占用3.09M.	剩余部分,给客户自己用	 			    
u16	    FLASH_SECTOR_COUNT=2048*12;	//W25Q1218,前12M字节给FATFS占用
#define FLASH_BLOCK_SIZE   	8     	//每个BLOCK有8个扇区
//初始化磁盘
DSTATUS disk_initialize (
	BYTE pdrv				/* Physical drive nmuber (0..) */
)
{
	u8 res=0;	    
	switch(pdrv)
	{
		case SD_CARD://SD卡
			res=SD_Init();//SD卡初始化 
  			break;
		case EX_FLASH://外部flash
			W25QXX_Init();
			FLASH_SECTOR_COUNT=2048*12;//W25Q1218,前12M字节给FATFS占用 
 			break;
		default:
			res=1; 
	}		 
	if(res)return  STA_NOINIT;
	else return 0; //初始化成功
}  
//获得磁盘状态
DSTATUS disk_status (
	BYTE pdrv		/* Physical drive nmuber (0..) */
)
{ 
	return 0;
} 
//读扇区
//drv:磁盘编号0~9
//*buff:数据接收缓冲首地址
//sector:扇区地址
//count:需要读取的扇区数
DRESULT disk_read (
	BYTE pdrv,		/* Physical drive nmuber (0..) */
	BYTE *buff,		/* Data buffer to store read data */
	DWORD sector,	/* Sector address (LBA) */
	UINT count		/* Number of sectors to read (1..128) */
)
{
	u8 res=0; 
    if (!count)return RES_PARERR;//count不能等于0,否则返回参数错误		 	 
	switch(pdrv)
	{
		case SD_CARD://SD卡
			res=SD_ReadDisk(buff,sector,count);	 
			while(res)//读出错
			{
				SD_Init();	//重新初始化SD卡
				res=SD_ReadDisk(buff,sector,count);	
				//printf("sd rd error:%drn",res);
			}
			break;
		case EX_FLASH://外部flash
			for(;count>0;count--)
			{
				W25QXX_Read(buff,sector*FLASH_SECTOR_SIZE,FLASH_SECTOR_SIZE);
				sector++;
				buff+=FLASH_SECTOR_SIZE;
			}
			res=0;
			break;
		default:
			res=1; 
	}
   //处理返回值,将SPI_SD_driver.c的返回值转成ff.c的返回值
    if(res==0x00)return RES_OK;	 
    else return RES_ERROR;	   
}
//写扇区
//drv:磁盘编号0~9
//*buff:发送数据首地址
//sector:扇区地址
//count:需要写入的扇区数
#if _USE_WRITE
DRESULT disk_write (
	BYTE pdrv,			/* Physical drive nmuber (0..) */
	const BYTE *buff,	/* Data to be written */
	DWORD sector,		/* Sector address (LBA) */
	UINT count			/* Number of sectors to write (1..128) */
)
{
	u8 res=0;  
    if (!count)return RES_PARERR;//count不能等于0,否则返回参数错误		 	 
	switch(pdrv)
	{
		case SD_CARD://SD卡
			res=SD_WriteDisk((u8*)buff,sector,count);
			while(res)//写出错
			{
				SD_Init();	//重新初始化SD卡
				res=SD_WriteDisk((u8*)buff,sector,count);	
				//printf("sd wr error:%drn",res);
			}
			break;
		case EX_FLASH://外部flash
			for(;count>0;count--)
			{										    
				W25QXX_Write((u8*)buff,sector*FLASH_SECTOR_SIZE,FLASH_SECTOR_SIZE);
				sector++;
				buff+=FLASH_SECTOR_SIZE;
			}
			res=0;
			break;
		default:
			res=1; 
	}
    //处理返回值,将SPI_SD_driver.c的返回值转成ff.c的返回值
    if(res == 0x00)return RES_OK;	 
    else return RES_ERROR;	
}
#endif
//其他表参数的获得
 //drv:磁盘编号0~9
 //ctrl:控制代码
 //*buff:发送/接收缓冲区指针
#if _USE_IOCTL
DRESULT disk_ioctl (
	BYTE pdrv,		/* Physical drive nmuber (0..) */
	BYTE cmd,		/* Control code */
	void *buff		/* Buffer to send/receive control data */
)
{
	DRESULT res;						  			     
	if(pdrv==SD_CARD)//SD卡
	{
	    switch(cmd)
	    {
		    case CTRL_SYNC:
				res = RES_OK; 
		        break;	 
		    case GET_SECTOR_SIZE:
				*(DWORD*)buff = 512; 
		        res = RES_OK;
		        break;	 
		    case GET_BLOCK_SIZE:
				*(WORD*)buff = SDCardInfo.CardBlockSize;
		        res = RES_OK;
		        break;	 
		    case GET_SECTOR_COUNT:
		        *(DWORD*)buff = SDCardInfo.CardCapacity/512;
		        res = RES_OK;
		        break;
		    default:
		        res = RES_PARERR;
		        break;
	    }
	}else if(pdrv==EX_FLASH)	//外部FLASH  
	{
	    switch(cmd)
	    {
		    case CTRL_SYNC:
				res = RES_OK; 
		        break;	 
		    case GET_SECTOR_SIZE:
		        *(WORD*)buff = FLASH_SECTOR_SIZE;
		        res = RES_OK;
		        break;	 
		    case GET_BLOCK_SIZE:
		        *(WORD*)buff = FLASH_BLOCK_SIZE;
		        res = RES_OK;
		        break;	 
		    case GET_SECTOR_COUNT:
		        *(DWORD*)buff = FLASH_SECTOR_COUNT;
		        res = RES_OK;
		        break;
		    default:
		        res = RES_PARERR;
		        break;
	    }
	}else res=RES_ERROR;//其他的不支持
    return res;
}
#endif
//获得时间
//User defined function to give a current time to fatfs module      */
//31-25: Year(0-127 org.1980), 24-21: Month(1-12), 20-16: Day(1-31) */                                                                                                                                                                                                                                          
//15-11: Hour(0-23), 10-5: Minute(0-59), 4-0: Second(0-29 *2) */                                                                                                                                                                                                                                                
DWORD get_fattime (void)
{				 
	return 0;
}			 
//动态分配内存
void *ff_memalloc (UINT size)			
{
	return (void*)mymalloc(SRAMIN,size);
}
//释放内存
void ff_memfree (void* mf)		 
{
	myfree(SRAMIN,mf);
}

FATFS文件系统解读就讲解到这儿啦!!!

本作品采用 知识共享署名 4.0 国际许可协议 进行许可
标签: 函数 应用 文件 移植 编写
最后更新:2023年9月17日

Linux大神网

每日更新,欢迎收藏♥ 不积跬步无以至千里,加油,共勉。

点赞
< 上一篇
下一篇 >

文章评论

您需要 登录 之后才可以评论

Linux大神网

每日更新,欢迎收藏♥
不积跬步无以至千里,加油,共勉。

最新 热点 随机
最新 热点 随机
如何在Linux系统中查看CPU信息使用lscpu命令行 linux服务器搭建ftp的6下安装vsftpd步骤及步骤 贵州工业职业技术学院求职意向期望工作地--诚聘英才 实验1Linux安装实验掌握虚拟机的使用 Linux系统tar命令的使用方法及使用命令教程 linux 开源nas系统 杰和科技NAS服务器媒体见面会在京召开 Android与Linux开发大不同 Linux系统软件安装包:自己动手,安装不用愁 车市新战局:汽车操作系统会复制智能手机的历史吗? Linux文件系统种类 如何卸载用源码包安装的软件?在线视频教程推荐 「职位」ASP.、PHP、Linux服务器集群开发 Torvalds:Linux内核开发的创新前景充满了热情 Linux文件系统的结构从终端窗口探索Linux目录树结构 卸载软件命令Linux.You linux软件开发如何入门?学习Linux步骤及学习方法介绍 14年Linux发行版的有趣历史观点 Linux中不像Windows可以直接在控制面板中卸载? 2018年波及众多Linux发行版的性能对比会更加深入 如何用源码包安装的软件?name的方法总结
嵌入式Linux操作系统学习规划+LINUX路线,主攻江苏电信天翼校园客户端故障指引及解决办法(101)英特尔GMAGMA950显卡驱动程序/WIN8/8.1电信校园网宽带用USB数据线共享给电脑无线上网国防科大开源操作系统:它只是一个吉祥的象征10个常用Linux文本查看命令及其详细说明和使用示例Linux嵌入式系统内核裁剪与定制方法的介绍情况淘宝教育热卖C语言编程开发C++程序设计零基础入门课程从CPU、内存、硬盘、显卡等这些方面安装Linux系统的最低配置Linux通过chkconfig设置开机启动服务创建的几种常见方式(技术分析)Linux多线程的使用与操作系统的区别通常rar命令由一个主命令加若干选项(可选)构成RedHatLinux中自动运行程序中的应用linux 读写文件 关于Linux内核的神秘面纱,你知道几个?使用wget实用程序的有用命令行工具的使用怎么设置linux开机项自启动?方式是怎样的?嵌入式Linux应用层与驱动层要想学习关于Linux内核的交叉编译步骤和方法:步骤、方法STM32嵌入式linux开发流程及应用程序分析-STMlinux下有哪些文件在介绍lsof命令实用用法介绍?
tarxf-3.13.2.tar-C/usr Unix或者类Unix文件系统中的每个文件(或者目录) 在多用户多任务中对每个用户运行环境的设置十分重要 《》Linux文件类型与文件权限权限与目录的区别 直接设置硬件时间和硬件时钟同步的解决方式有哪些 centos系统版本详细信息解决方案与操作系统版本兼容的重要性分析 Ubuntu上安装GCC速度较慢,有几种方法可以尝试加快安装过程 RedHatLinux软件安装包软件后缀为.rpm最初 linux设置开机服务自动启动/关闭自动命令@localhost 一个系统安装使用手册Alternate版Ubuntu系统U盘安装系统下载 系统架构师的考试分为,要开始战斗了!!(下) linux 用户空间内存申请 kmallockzallocmalloc和get_free_malloc_start这段地址 嵌入式Linux内核移植及根文件系统实验的实验步骤 文本文件的编辑命令:vim的三种状态模式、基本操作 搜狗输入法企业版:多设备输入新体验 Java拼接SLICE-F-MOVE的零拷贝方法是怎样的? 创建新用户账号,轻松管理Linux用户 mysql执行sql脚本文件的方法:SQLServerjava能写游戏吗 透过阅读Linux内核代码的方式看内核源码的分析并非“高不可攀” linux文件空间常用的命令有df、du和ls等
标签聚合
linux服务器 软件 内核 linux系统 应用 文件目录 虚拟机 命令 操作 文件
书籍
课程
技术群
技术干货大合集↓
  • 2023年9月 / 78篇
  • 2023年8月 / 93篇
  • 2023年7月 / 94篇
  • 2023年6月 / 90篇
  • 2023年5月 / 93篇
  • 2023年4月 / 90篇
  • 2023年3月 / 129篇
  • 2023年2月 / 84篇
  • 2023年1月 / 161篇
  • 2022年12月 / 187篇
  • 2022年11月 / 76篇
友情链接:

Linux书籍 | Linux命令 | Linux系统 | RHCE红帽认证 | Linux软件 | Linux教程 | CentOS系统 | Linux内核 | Linux服务器 | Linux大神 | IT资源

COPYRIGHT © 2023 linuxgod.net ALL RIGHTS RESERVED.