STM32——FATFS文件系统

news2024/11/20 14:41:18

 可裁剪意味着可以选择部分功能,减小占用的空间。

与Windows兼容意味着可以在电脑上直接读取文件。 

底层接口, 包括存储媒介读/写接口( disk I/O )和供给文件创建修改时间的实时时钟 需要我们 根据平台和存储介质 编写移植代码
中间层 FATFS 模块, 实现了 FAT 文件读/写协议。 FATFS 模块提供的是 ff.c ff.h 。除非有必要,使用者一般不用修改,使用时将头文件直接包含进去即可。
最顶层是应用层, 使用者无需理会 FATFS 的内部结构和复杂的 FAT 协议,只需要调用 FATFS 模块提供给用户的一系列应用接口函数,如 f_open f_read f_write f_close 等,就可以像在 PC 上读/写文件那样简单。

文件名

功能

说明

ffconf.h

FATFS模块配置文件

 需要根据需求来配置参数。

ff.h

FATFS和应用模块公用的包含文件

 不需要修改

ff.c

FATFS模块源码

 不需要修改

diskio.h

FATFSdisk I/O模块公用的包含文件

 不需要修改

diskio.c

FATFSdisk I/O模块接口层文件

与平台相关的代码,需要用户根据存储介质来编写函数。

interger.h

数据类型定义

与编译器有关。

option文件夹

可选的外部功能(比如支持中文等)

汉字实验把字库放到SPI FLASH需要修改

 diskio.c文件非常重要,我们需要根据存储介质来修改,是与硬件打交道的。

经验:

大部分的可移植的小系统或者应用,都是采用类似这种将与底层打交道的源码开发给用户编写,然后提供顶层配置文件供配置。不需要自己编写文件管理系统。

_FS_TINY 这个选项在 R0.07 版本中开始出现,之前的版本都是以独立的 C 文件出现( FATFS Tiny FATFS ),有了这个选项之后,两者整合在一起了,使用起来更方便。我们使用 FATFS ,所以把这个选项定义为 0 即可。
_FS_READONLY 这个用来配置是不是只读,本章我们需要读写都用,所以这里设置为 0 即可。
_USE_STRFUNC 。这个用来设置是否支持字符串类操作,比如 f_putc f_puts 等,本章我们需要用到,故设置这里为 1

_USE_MKFS这个用来定时是否使能格式化,本章需要用到,所以设     置这里为1

_USE_FASTSEEK这个用来使能快速定位,我们设置为1,使能快速定位。

_USE_LABEL这个用来设置是否支持磁盘盘符(磁盘名字)读取与设置。我们设置为1,使能,就可以通过相关函数来读取和设置磁盘的名字了。

_CODE_PAGE。这个用于设置语言类型,包括很多选项(见FATFS官网说明),我们这里设置为936,即简体中文(GBK码,需要c936.c文件支持,该文件在option文件夹)。

_USE_LFN该选项用于设置是否支持长文件名(还需要_CODE_PAGE支持),取值范围为0~30,表示不支持长文件名,1~3是支持长文件名,但是存储地方不一样,我们选择使用3,通过ff_memalloc函数来动态分配长文件名的存储区域。

_VOLUMES用于设置FATFS支持的逻辑设备数目,我们设置为3的话,即支持3个设备(磁盘)

_MAX_SS扇区缓冲的最大值,一般设置为512

diskio.c和diskio.h是硬件层。

ff.c和ff.h是FatFs的文件系统层和文件系统的API层


FATFS模块在移植的时候,我们一般只需要修改2个文件,即ffconf.hdiskio.cFATFS模块的所有配置项都是存放在ffconf.h里面,我们可以通过配置里面的一些选项,来满足自己的需求是diskio.c硬件层,负责与底层硬件接口适配。

①数据类型:在integer.h 里面去定义好数据的类型。这里需要了解你用的编译器的数据类型,并根据编译器定义好数据类型。
②配置:通过ffconf.h配置FATFS的相关功能,以满足你的需要。
③函数编写:打开diskio.c,进行底层驱动编写,一般需要编写6个接口函数

 

 下面以接口函数disk_read 为例子

//读扇区
//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);	 
		 	if(res)//STM32 SPI的bug,在sd卡操作失败的时候如果不执行下面的语句,可能导致SPI读写异常
			{
				SD_SPI_SpeedLow();
				SD_SPI_ReadWriteByte(0xff);//提供额外的8个时钟
				SD_SPI_SpeedHigh();
			}
			break;
		case EX_FLASH://外部flash
			for(;count>0;count--)
			{
				SPI_Flash_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;	   
}

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 -打开一个目录

正点原子自己写了一个exfuns.c的文件用来实现部分文件操作,如下图的f_typetell所示。同时写了fattester文件来封装FSTFS文件管理系统的开放函数,fattester.h文件如下。

//报告文件的类型
//fname:文件名
//返回值:0XFF,表示无法识别的文件类型编号.
//		 其他,高四位表示所属大类,低四位表示所属小类.
u8 f_typetell(u8 *fname)
{
	u8 tbuf[5];
	u8 *attr='\0';//后缀名
	u8 i=0,j;
	while(i<250)
	{
		i++;
		if(*fname=='\0')break;//偏移到了最后了.
		fname++;
	}
	if(i==250)return 0XFF;//错误的字符串.
 	for(i=0;i<5;i++)//得到后缀名
	{
		fname--;
		if(*fname=='.')
		{
			fname++;
			attr=fname;
			break;
		}
  	}
	strcpy((char *)tbuf,(const char*)attr);//copy
 	for(i=0;i<4;i++)tbuf[i]=char_upper(tbuf[i]);//全部变为大写 
	for(i=0;i<6;i++)
	{
		for(j=0;j<13;j++)
		{
			if(*FILE_TYPE_TBL[i][j]==0)break;//此组已经没有可对比的成员了.
			if(strcmp((const char *)FILE_TYPE_TBL[i][j],(const char *)tbuf)==0)//找到了
			{
				return (i<<4)|j;
			}
		}
	}
	return 0XFF;//没找到		 			   
}	 

mf_showfree 函数用来显示剩余SD卡的容量

//显示剩余容量
//drv:盘符
//返回值:剩余容量(字节)
u32 mf_showfree(u8 *drv)
{
	FATFS *fs1;
	u8 res;
    u32 fre_clust=0, fre_sect=0, tot_sect=0;
    //得到磁盘信息及空闲簇数量
    res = f_getfree((const TCHAR*)drv,(DWORD*)&fre_clust, &fs1);
    if(res==0)
	{											   
	    tot_sect = (fs1->n_fatent - 2) * fs1->csize;//得到总扇区数
	    fre_sect = fre_clust * fs1->csize;			//得到空闲扇区数	   
#if _MAX_SS!=512
		tot_sect*=fs1->ssize/512;
		fre_sect*=fs1->ssize/512;
#endif	  
		if(tot_sect<20480)//总容量小于10M
		{
		    /* Print free space in unit of KB (assuming 512 bytes/sector) */
		    printf("\r\n磁盘总容量:%d KB\r\n"
		           "可用空间:%d KB\r\n",
		           tot_sect>>1,fre_sect>>1);
		}else
		{
		    /* Print free space in unit of KB (assuming 512 bytes/sector) */
		    printf("\r\n磁盘总容量:%d MB\r\n"
		           "可用空间:%d MB\r\n",
		           tot_sect>>11,fre_sect>>11);
		}
	}
	return fre_sect;
}		    

 exfuns.c中的exf_getfree提供了类似的功能

//得到磁盘剩余容量
//drv:磁盘编号("0:"/"1:")
//total:总容量	 (单位KB)
//free:剩余容量	 (单位KB)
//返回值:0,正常.其他,错误代码
u8 exf_getfree(u8 *drv,u32 *total,u32 *free)
{
	FATFS *fs1;
	u8 res;
    u32 fre_clust=0, fre_sect=0, tot_sect=0;
    //得到磁盘信息及空闲簇数量
    res =(u32)f_getfree((const TCHAR*)drv, (DWORD*)&fre_clust, &fs1);
    if(res==0)
	{											   
	    tot_sect=(fs1->n_fatent-2)*fs1->csize;	//得到总扇区数
	    fre_sect=fre_clust*fs1->csize;			//得到空闲扇区数	   
#if _MAX_SS!=512				  				//扇区大小不是512字节,则转换为512字节
		tot_sect*=fs1->ssize/512;
		fre_sect*=fs1->ssize/512;
#endif	  
		*total=tot_sect>>1;	//单位为KB
		*free=fre_sect>>1;	//单位为KB 
 	}
	return res;
}		   

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/110453.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

深度学习笔记(1)| 导数、偏导数、梯度和方向导数的理解

1. 梯度&#xff08;Gradient&#xff09;的理解 深度学习尝试在权重空间中找到一个方向&#xff0c;沿着该方向能降低损失函数的损失值。其实不需要随机寻找方向&#xff0c;因为可以直接计算出最好的方向&#xff0c;这就是从数学上计算出最陡峭的方向。这个方向就是损失函数…

单页扒手-基于Node的实现

做网站的朋友经常遇见别人的好看的页面&#xff0c;想保存到本地自己用&#xff0c;可是用以前的老办法网页另存为&#xff0c;发现很不好&#xff0c;规则不好处理&#xff0c;路径也不好处理&#xff0c;用这个网页克隆&#xff08;单页模板扒手&#xff09;就很好处理了&…

阿里「杀手锏」级语音识别模型来了!推理效率较传统模型提升10倍,已开源

阿里达摩院&#xff0c;又搞事儿了。 这两天&#xff0c;它们发布了一个全新的语音识别模型&#xff1a; Paraformer。 开发人员直言不讳&#xff1a;这是我们“杀手锏”级的作品。 ——不仅识别准确率“屠榜”几大权威数据集&#xff0c;一路SOTA&#xff0c;推理效率上相比…

Zookeeper 4 Zookeeper JavaAPI 操作 4.7 Curator API 常用操作【Watch 事件监听】

Zookeeper 【黑马程序员Zookeeper视频教程&#xff0c;快速入门zookeeper技术】 文章目录Zookeeper4 Zookeeper JavaAPI 操作4.7 Curator API 常用操作4.7.1 Watch 事件监听4 Zookeeper JavaAPI 操作 4.7 Curator API 常用操作 4.7.1 Watch 事件监听 【基本概念】 ZooKeep…

异常见闻录-Java.lang.UnsupportedClassVersionError涨知识啦

今天有学生说自己的Eclipse的Java代码只能在新建的项目中运行&#xff0c;运行导入项目中类就报错 异常信息 java.lang.UnsupportedClassVersionError: com/demo1/Demo1Application has been compiled by a more recent version of the Java Runtime (class file version 5…

CMake入门

1. CMake的介绍&#xff1a; 当多人开发同一个项目时&#xff0c;最终要输出一个可执行文件或者共享库&#xff08;dll、so等&#xff09;&#xff0c;就可以使用cmake了 所有操作都是通过 CMakeLists.txt&#xff08;严格区分大小写&#xff09; 来完成的 ----> 简单 2. …

C51——超声波测距 函数封装和舵机代码结合

要注意舵机转动中 延时函数要放在哪里 #include "reg52.h" sbit D5 P3^7;// sbit D6 P3^6;// sbit Trig P1^5; sbit Echo P1^6; sbit sg90_con P1^1; int cnt; int jd; double time; void Delay10us() //11.0592MHz { unsigned ch…

操作系统管程-地址-重定位-内存管理与存储管理

管程的基本概念&#xff1a;为什么会出现管程&#xff1f;信号量机制的不足&#xff1a;程序编写困难、易出错解决&#xff1a;Brinch Hansen(1973)Boare(1974)方案&#xff1a;在程序设计语言中引入管程成分一种高级同步机制管程的定义&#xff1a;是一个特殊的模块有一个名字…

使用MAXScript脚本编写圣诞树建模插件教程

一、前言 2022年圣诞节到来啦&#xff0c;很高兴这次我们又能一起度过~ 今年的圣诞节为大家分享用MAXScript脚本编写圣诞树建模插件的技术创意&#xff0c;喜欢的同学别忘记在下面点个赞&#xff01; 二、创意名 一键圣诞树插件 三、效果展示 四、实现步骤 1.制作圣诞树的设计稿…

智能巡检系统:企业安全生产管理的智能助手

智能巡检是一种高效代替传统人工巡检的新方式&#xff0c;其依靠物联感知技术&#xff0c;通过物联网采集获取信息&#xff0c;自动记录巡检信息&#xff0c;及时发现问题&#xff0c;实现巡检科学化。 工业4.0带来的技术革新加速了企业的转型升级进程&#xff0c;传统企业的运…

F5张振伦:让应用安全、快速、可靠地交付到需要的地方丨2022首届全球数字生态大会

科技云报道原创。 日前&#xff0c;由杭州市人民政府和浙江省商务厅主办的“2022首届全球数字生态大会”在杭州国际博览中心成功举办。 本次大会以“新技术、新业态、新模式”为主题&#xff0c;邀请到国内外20余位演讲嘉宾和超300位专业观众线下参会。 与此同时&#xff0c;…

IB成绩换成GPA,美国大学是如何算的?

IB课程体系是全球公认的难度大、结构强的课程体系。 IB课程可以通过IB文凭课程&#xff08;也称为IBDP&#xff09;进行系统研究。IB课程体系是国际公认的基础文凭&#xff0c;世界上几乎所有大学都认可IB课程体系。这是否意味着IB在申请美国大学时会有优势&#xff1f; 事实上…

【vue系列-02】vue的核心属性,数据代理,事件

vue的核心属性一&#xff0c;vue的核心属性1&#xff0c;模板语法1.1&#xff0c;插值语法1.2&#xff0c;指令语法2&#xff0c;数据绑定2.1&#xff0c;单向绑定2.2&#xff0c;双向绑定3.mvvm模型4&#xff0c;数据代理4.1&#xff0c;数据代理的基本使用4.2&#xff0c;数据…

pytorch实现好莱坞明星识别

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f366; 参考文章地址&#xff1a; 365天深度学习训练营-第P6周&#xff1a;好莱坞明星识别&#x1f356; 作者&#xff1a;K同学啊一、前期准备 1.设置GPU import torch from torch import nn …

获取rdp保存的凭证

获取用户保存的rdp凭证 当获取到一台windows服务器&#xff0c;可以尝试获取本地远程连接的信息&#xff0c;如果用户在登入rdp时勾选了 允许为我保存凭证的选项&#xff0c;则在该用户本地会生成一个凭证文件&#xff0c;我们只需要破解该凭证文件即可获取其明文密码。 通过注…

[含文档+PPT+源码等]基于SSM框架图书借阅管理系统开发与设计

博主介绍&#xff1a;✌在职Java研发工程师、专注于程序设计、源码分享、技术交流、专注于Java技术领域和毕业设计✌ 项目名称 [含文档PPT源码等]基于SSM框架图书借阅管理系统开发与设计 系统介绍 《基于SSM框架图书管理系统开发与设计》 该项目含有源码、配套开发软件、软件安…

元数据相关的术语,你知道几个?

元数据被认为是数据治理的基石&#xff0c;但关于元数据相关的概念&#xff0c;很多人不是那么清楚&#xff0c;今天就和大家详解元数据相关的术语。当然&#xff0c;与元数据相关的概念非常多&#xff0c;以下仅罗列几个常见的。 01 元数据 1.名词解释 元数据最简单的定义…

【关于时间序列的ML】项目 7 :使用机器学习进行每日出生预测

&#x1f50e;大家好&#xff0c;我是Sonhhxg_柒&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流&#x1f50e; &#x1f4dd;个人主页&#xff0d;Sonhhxg_柒的博客_CSDN博客 &#x1f4c3; &#x1f381;欢迎各位→点赞…

u盘无法识别如何修复?恢复U盘,建议尝试下这些方法

我们基本都有使用过U盘&#xff0c;也都遇到过U盘损坏的问题。u盘无法识别如何修复&#xff1f;有没有什么实用的方法呢&#xff1f;来看看这篇文章&#xff0c;简单几步&#xff0c;就可以修复成功。如果在操作过程中&#xff0c;遇到数据丢失&#xff0c;也有方法帮你恢复&am…

ASP.NET开发的医疗健康咨询平台源码 养生知识咨询 寻根问药平台源码 C#源码

一、源码特点&#xff1a; 爱心医生健康知识门户网站是一个权威的医疗科普视频、语音、知识、医疗健康问答平台。 包含所有源代码和数据库&#xff0c;可以直接部署到IIS中使用。 二、菜单功能 网站页面&#xff1a; 1、首页&#xff1a;包含幻灯片。 2…