019 - STM32学习笔记 - Fatfs文件系统(一) - FatFs文件系统初识
019 - STM32学习笔记 - Fatfs文件系统(一) - FatFs文件系统初识
最近工作比较忙,没时间摸鱼学习,抽空学点就整理一点笔记。
1、文件系统
在之前学习Flash的时候,可以调用SPI_FLASH_BufferWrite
函数,将数据内容写入到Flash芯片中,需要使用的时候,可以再从Flash中读取出来,但是我们每次写入数据的时候,有以下三点比较麻烦:
- 有效数据的位置不方便记录;
- 存储数据量大小可能随时变动,对于Flash的容量剩余大小难以确定;
- 存储数据类型多变,读取时不确定该以何种格式解读数据。
目前我们接触到的Windows/Linux系统就是比较常见的文件系统,我们在Windows/Linux中查找文件只需要根据文件的存储路径就可以方便的找到需要的文件,文件内容读取可以通过文件类型(例如txt、exe等)方式去通过特定的打开方式去使用。
数据文件在硬盘(以机械硬盘为例)中的存储,是将硬盘分为盘片-扇区-磁道的方式分布存储在磁道中,文件存储时,磁盘会记录文件存储的地址,当使用文件的时候,会根据地址寻址进行读取写入磁盘。
为了存储和管理数据方便,在存储介质中会建立组织结构,包含操作系统的引导区、目录和文件。常见的Windows系统下文件系统格式包括FAT32、NTFS、exFAT,我们拿到新的磁盘时,需要将磁盘格式化为上述的一种文件格式,格式化时,会在磁盘中建立一个文件分配表和目录,后续文件系统可以在文件分配表和目录中记录数据存放的地址以及剩余空间了。
如上图,Windows中将磁盘通过逻辑划分,将整块硬盘划分为几块,包含主引导记录分区(MBR),基本分区1-3,逻辑分区等,其中主引导分区中记录着后续几个分区的物理地址,可以通过这些物理地址找到后续分区,这里会装系统的基本都懂,就不过多阐述了,感兴趣的可以百度一下学习学习。
当使用文件系统时,数据都是以文件的方式进行存储。写入新文件时,首先要在目录中创建一个文件索引,用来指示文件存放的物理位置,然后再将文件存储到该地址中;当需要读取数据时,首先到目录中查找读取数据的文件索引,再到相应的地址中区读取数据。这期间还牵扯到逻辑地址、簇大小、不连续存储等一系列过程。
文件存储时,不仅仅是简单的向某个物理地址直接读写,需要以一定的既定格式进行读写。
例如在火哥的教程中举的例子,假设现在有0-99共100簇的存储空间(簇可以理解为扇区),其中第0簇是文件分配表,第1簇为目录,后续几个文件分别占用不同数量的扇区存储文件,这些文件的存储信息都在记录在第1簇的目录中。
当需要读取文件时,根据目录相中,读取到开始簇为2,找到文件分配表中,第2簇上读取到数据为3,表示下一部分数据指向存储在第3簇上,再到第3簇记录上读到下一簇得数据指向为4,一次向后,直到最后一簇11时,发现下一个指向为FF,表示到文件末尾了,到此文件就读取完了。到这里的时候,起始发现这种指向方式很像链表,链表头指向的时数据存放的位置,链表尾,指向的是下一个数据起始位置。
上面这个表中,数据是连续存储的,假如我们对文件进行修改了,可能原来的存储单元存不下更多的数据,那么后续增加的内容可能会放到其他簇中,这样在原来的第11簇位置指向的FF就变更为后续文件存储的起始位置了。如下图
2、FatFs系统
FatFs是面向小型嵌入式系统的一种通用的FAT文件系统,由AISI C语言编写,并且完全独立于底层的I/O介质。因此它可以很容易的不加修改一直到其他处理器中。
上节中我们已经写好用SPI读写Flash,这节开始就可以将FatFs文件系统代码移植进去,就可以使用文件系统的各种函数,对Flash采用文件的方式进行读写了。
学习中使用到的FatFs文件系统官网地址:
FatFs文件系统官网
目前官网最新的FatFs版本为ff15,野火教程中使用的为ff11a,这里也就根据野火教程先进行学习,等到后面抽空再学习最新的版本。
在下载好的FatFs源码文件中,在documents目录下,有关于此源码的说明,关于接口函数的说明可以看一下说明文档,这里不做过多赘述。
在src文件夹中,有个read.txt,里面对源码中的各个文件都做了说明,感兴趣的可以看一下。
文件名 | 功能 |
---|---|
integer.h | 文件中包含了一些数值类型的定义。 |
diskio.c | 包含底层存储介质的操作函数,这些函数需要用户自己实现,主要添加底层驱动函数。 |
ff.c | FatFs核心文件,文件管理的实现方法。该文件独立于底层介质操作文件的函数,利用这些函数实现文件的读写。 |
cc936.c | 本文件在option目录下,是简体中文支持所需要添加的文件,包含了简体中文的GBK和Unicode互相转换功能函数 |
ffconf.h | 这个头文件包含了对FatFs功能配置的宏定义,通过修改这些宏定义就可以裁剪FatFs的功能,如果需要支持简体中文,需要把ffconf.h中的_CODE_PAGE的宏改成936,并把上面的ccp36.c文件加入到工程中。 |
在以上几个文件中,我们需要修改的主要是diskio.c、ff.c以及ffconf.h,这里针对性的讲一下关于FatFs文件系统移植需要注意的地方。
先看一下FatFs在程序中的关系网络图:
这里先分析一下ff.c、diskio.c这几个文件:
diskio.c中,我们主要了解一下DRESULT disk_read (BYTE pdrv,BYTE *buff,DWORD sector,UINT count)
函数
#define ATA 0 /* 硬盘设备标号为0 */
#define MMC 1 /* MMC/SD设备标号为1 */
#define USB 2 /* USB设备标号为2 */
DRESULT disk_read (BYTE pdrv,BYTE *buff,DWORD sector,UINT count)
{DRESULT res;int result;switch (pdrv) {case ATA :// translate the arguments hereresult = ATA_disk_read(buff, sector, count);// translate the reslut code herereturn res;case MMC :// translate the arguments hereresult = MMC_disk_read(buff, sector, count);// translate the reslut code herereturn res;case USB :// translate the arguments hereresult = USB_disk_read(buff, sector, count);// translate the reslut code herereturn res;}return RES_PARERR;
}
disk_read
函数是Fatfs与底层程序对接的接口,在这里可以实现对硬盘、SD卡、USB等设备的读写,在程序中,实际上预留了给用户改写自己实现的底层程序,例如这里,我们可以将我们在之前学习I2C读写EEPROM或者SPI读写Flash的函数放在这里实现,例如改写后:
#define FLASH 3 /* FLASH设备标号为3 */
//以上省略case FLASH ://这里采用我们之前实现的额SPI读取Flash的函数,使用前需要在文件前#include "bsp_spi_flash.h"result = SPI_Flash_ReadDate(buff, sector, count);return res;
//以下省略
在diskio.c中还有disk_write
,同样我们也可以采用跟读方式相同的办法用我们自己实现的写函数进行改写。
这里改写完成后,再到ff.c中看一下,这里我们就可以使用学习C语言是学到的文件操作函数了,例如f_open()、f_read()、f_write()等。
FRESULT f_read (FIL* fp, /* Pointer to the file object */void* buff, /* Pointer to data buffer */UINT btr, /* Number of bytes to read */UINT* br /* Pointer to number of bytes read */
)
{
//---------------------------篇幅原因省略----------------------------------------//if (csect + cc > fp->fs->csize) /* Clip at cluster boundary */cc = fp->fs->csize - csect;if (disk_read(fp->fs->drv, rbuff, sect, cc) != RES_OK)ABORT(fp->fs, FR_DISK_ERR);
//---------------------------篇幅原因省略----------------------------------------//
}
在以上程序中,f_read
函数又调用了disk_read
函数,从而实现文件的读取。
因此在使用FatFs文件系统时,我们只需要去修改diskio.c文件基本就可以完成对设备的读写等操作了。ff.c、ff.h、integer.h以及diskio.h这四个文件基本不需要改动。
另外在说一下ffconf.h文件,关于FatFs文件系统所具备的功能,基本上跟我们在PC系统上操作硬盘、文件夹、文件等操作一致,因此我们使用FatFs文件系统时,可以根据实际需要对其功能进行裁剪,野火的教程中对内容进行了总结,这里就直接附到下面各位可以根据实际需求进行裁剪。
关于FatFs文件系统的相关内容,可以在官网或者帮助文档中看看相关的介绍。
相关文章:

019 - STM32学习笔记 - Fatfs文件系统(一) - FatFs文件系统初识
019 - STM32学习笔记 - Fatfs文件系统(一) - FatFs文件系统初识 最近工作比较忙,没时间摸鱼学习,抽空学点就整理一点笔记。 1、文件系统 在之前学习Flash的时候,可以调用SPI_FLASH_BufferWrite函数,将数…...

Selenium开发环境搭建
1.下载Python https://www.python.org/downloads/ 下载下来选择自己创建的路径进行安装,然后配置环境变量 cmd命令框查看 2.安装selenium cmd命令框输入: pip install selenium3.下载pycharm https://www.jetbrains.com/pycharm/download/#sec…...
解决 The ‘more_itertools‘ package is required
在使用爬虫获取维基百科数据时看到了一个很好的项目: 博客:https://blog.51cto.com/u_15919249/5962100 项目地址:https://github.com/wjn1996/scrapy_for_zh_wiki 但在使用过程中遇到若干问题,记录一下: The more_it…...

手把手教你在云环境炼丹(部署Stable Diffusion WebUI)
前几天写了一篇《手把手教你在本机安装Stable Diffusion秋叶整合包》的文章,有些同学反映对硬件的要求太高,显卡太TM贵了。今天我再分享一个云服务器炼丹的方法,方便大家快速入门上手,这个云服务不需要特殊网络设置,能…...

pytorch-gpu 极简安装
1、进入pytoch官网:PyTorch 找到pytorch-gpu版本,看到CUDA11.8、11.7、CPU,这里我选择安装CUDA11.8 2、下载CUDA Toolkit:CUDA Toolkit 11.8 Downloads | NVIDIA Developer 3、下载CUDANN:cuDNN Download | NVIDIA D…...

有道云笔记迁移到自建服务器Joplin
当前有道云笔记各项业务开始逐渐向会员靠拢,如一开始不受限的多端同步现在非会员限制成了两个终端,估计以后会有越来越多的免费内容会逐渐的向会员转移,因此博主开始考虑自建服务器来搞一个云笔记服务端。 因博主已有黑群晖,并且有…...

qt源码--事件系统之QAbstractEventDispatcher
1、QAbstractEventDispatcher内容较少,其主要是定义了一些注册接口,如定时器事件、socket事件、注册本地事件、自定义事件等等。其源码如下: 其主要定义了大量的纯虚函数,具体的实现会根据不同的系统平台,实现对应的方…...
深入了解Python中的os.path.join函数
深入了解Python中的os.path.join函数 1. 引言 在Python中,处理文件和目录路径是常见的任务。为了简化路径的拼接和操作,Python提供了os.path模块,其中的join函数是一个非常重要且常用的函数。本文将深入介绍os.path.join函数的用法和注意事…...
Node.js:execSync执行一个shell命令
默认输出是Buffer对象 const { execSync } require(child_process)let out execSync("echo hi") console.log(out); // <Buffer 68 69 0a>需要转为字符串 const { execSync } require(child_process)let out execSync("echo hi") console.log(…...

《入门级-Cocos2d 4.0塔防游戏开发》---第二课:游戏加载界面开发
目录 一、开发环境介绍 二、开发内容 2.1 修改窗口的大小。 2.2 添加加载场景相关代码 2.3 添加资源 三、显示效果 四、知识点 4.1 Sprite 4.2 定时器 一、开发环境介绍 操作系统:UOS1060专业版本。 cocos2dx:版本 环境搭建教程: 统信UOS下配…...
打卡力扣题目十二
#左耳听风 ARST 打卡活动重启# 目录 一、问题 二、解题方法一 三、解题方法二 关于 ARTS 的释义 —— 每周完成一个 ARTS: ● Algorithm: 每周至少做一个 LeetCode 的算法题 ● Review: 阅读并点评至少一篇英文技术文章 ● Tips: 学习至少一个技术技巧 ● Share: …...

QT服务器练习
#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);//给服务器指针实例化空间server new QTcpServer(this); }Widget::~Widget() {delete ui; }//启动服务器按钮对…...

Vcenter 创建 虚拟机配置 Thin Provision 模式 disk
介绍 在vCenter中选择虚拟磁盘格式通常也取决于您的需求和使用情况。 vSphere支持多种虚拟磁盘格式,以下是一些常见的格式: Thick Provision Lazy Zeroed:这是vSphere中的默认格式。它会预分配虚拟磁盘所需的存储空间,但只有在虚…...

初识mysql数据库之事务的概念及操作
目录 一、数据库多客户端访问问题 1. 数据库的CURD无限制带来的问题 2. 如何解决CURD导致的问题 二、事务的概念 1. 什么是事务 2. 事务的四个属性 3. mysql对事务的管理 4. 为什么会有事务 5. 事务的版本支持 三、事务的操作 1. 事务提交方式 2. 事务操作的准备工…...
MPL-2.0(Mozilla Public License 2.0)
MPL-2.0(Mozilla Public License 2.0)是一种开源软件许可证,由 Mozilla 组织于2012年发布,用于授权开源项目。MPL-2.0 是 MPL-1.1 许可证的继任版本,旨在更好地适应现代开源软件的发展和使用。 MPL-2.0 许可证的主要特…...
Qt+OpenCV+VTK在VS2017中配置路径
QtOpenCVVTK在VS2017中配置路径 《Qt环境配置》《OpenCV环境配置》《VTK环境配置》 《Qt环境配置》 包含目录: D:\Qt\Qt5.12.11\5.12.11\msvc2017_64\include D:\Qt\Qt5.12.11\5.12.11\msvc2017_64\include\QtWidgets D:\Qt\Qt5.12.11\5.12.11\msvc2017_64\include…...

线性代数(应用篇):第五章:特征值与特征向量、第六章:二次型
文章目录 第5章 特征值与特征向量、相似矩阵(一) 特征值与特征向量1.定义2.性质3.求解(1)具体型矩阵试根法、多项式带余除法:三阶多项式分解因式 (2)抽象型矩阵 (二) 相似1.矩阵相似(1)定义(2)性质 2.相似对角化(1)定义(2)相似对角化的条件(n阶矩阵A可相…...

Java8实战-总结9
Java8实战-总结9 Lambda表达式把Lambda付诸实践:环绕执行模式第1步:记得行为参数化第2步:使用函数式接口来传递行为第3步:执行一个行为第4步:传递Lambda 使用函数式接口PredicateConsumerFunction原始类型特化 Lambda表…...

大数据开发面试必问:Hive调优技巧系列一
Hive必问调优 Hive 调优拆解:Hive SQL 几乎是每一位互联网分析师的必备技能,相信很多小伙伴都有被面试官问到 Hive 优化问题的经历。所以掌握扎实的 HQL 基础尤为重要,hive优化也是小伙伴应该掌握的一项技能,本篇文章具体从hive建表优化、HQ…...

Jupyter Notebook 7重磅发布,新增多个特性!
本文分享Jupyter Notebook大版本v7.0.0更新亮点,及简单测试! 近日,Jupyter Notebook大版本v7.0.0更新,Jupyter Notebook 7基于JupyterLab,因此它包含了过去几年JupyterLab中添加的许多新功能和改进,部分亮…...
【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密
在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...
条件运算符
C中的三目运算符(也称条件运算符,英文:ternary operator)是一种简洁的条件选择语句,语法如下: 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true,则整个表达式的结果为“表达式1”…...
使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装
以下是基于 vant-ui(适配 Vue2 版本 )实现截图中照片上传预览、删除功能,并封装成可复用组件的完整代码,包含样式和逻辑实现,可直接在 Vue2 项目中使用: 1. 封装的图片上传组件 ImageUploader.vue <te…...

2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面
代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口(适配服务端返回 Token) export const login async (code, avatar) > {const res await http…...

Map相关知识
数据结构 二叉树 二叉树,顾名思义,每个节点最多有两个“叉”,也就是两个子节点,分别是左子 节点和右子节点。不过,二叉树并不要求每个节点都有两个子节点,有的节点只 有左子节点,有的节点只有…...
.Net Framework 4/C# 关键字(非常用,持续更新...)
一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...

听写流程自动化实践,轻量级教育辅助
随着智能教育工具的发展,越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式,也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建,…...

【C++进阶篇】智能指针
C内存管理终极指南:智能指针从入门到源码剖析 一. 智能指针1.1 auto_ptr1.2 unique_ptr1.3 shared_ptr1.4 make_shared 二. 原理三. shared_ptr循环引用问题三. 线程安全问题四. 内存泄漏4.1 什么是内存泄漏4.2 危害4.3 避免内存泄漏 五. 最后 一. 智能指针 智能指…...
NPOI操作EXCEL文件 ——CAD C# 二次开发
缺点:dll.版本容易加载错误。CAD加载插件时,没有加载所有类库。插件运行过程中用到某个类库,会从CAD的安装目录找,找不到就报错了。 【方案2】让CAD在加载过程中把类库加载到内存 【方案3】是发现缺少了哪个库,就用插件程序加载进…...

ubuntu22.04有线网络无法连接,图标也没了
今天突然无法有线网络无法连接任何设备,并且图标都没了 错误案例 往上一顿搜索,试了很多博客都不行,比如 Ubuntu22.04右上角网络图标消失 最后解决的办法 下载网卡驱动,重新安装 操作步骤 查看自己网卡的型号 lspci | gre…...