019 - STM32学习笔记 - Fatfs文件系统(一) - FatFs文件系统初识

019 - STM32学习笔记 - Fatfs文件系统(一) - FatFs文件系统初识

最近工作比较忙,没时间摸鱼学习,抽空学点就整理一点笔记。

1、文件系统

在之前学习Flash的时候,可以调用SPI_FLASH_BufferWrite函数,将数据内容写入到Flash芯片中,需要使用的时候,可以再从Flash中读取出来,但是我们每次写入数据的时候,有以下三点比较麻烦:

  1. 有效数据的位置不方便记录;
  2. 存储数据量大小可能随时变动,对于Flash的容量剩余大小难以确定;
  3. 存储数据类型多变,读取时不确定该以何种格式解读数据。

目前我们接触到的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.cFatFs核心文件,文件管理的实现方法。该文件独立于底层介质操作文件的函数,利用这些函数实现文件的读写。
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文件系统的相关内容,可以在官网或者帮助文档中看看相关的介绍。

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

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

相关文章

Windows 11 上使用 Docker 安装 SQL Server 2022 数据库

Windows 11 上使用 Docker 安装 SQL Server 2022 数据库,你可以按照以下步骤进行操作: 安装 Docker Desktop for Windows: 访问 Docker 官方网站(https://www.docker.com/get-started)下载并安装适用于 Windows 的 Do…

“RWEQ+”集成技术在土壤风蚀模拟与风蚀模数估算、变化归因分析中的实践应用及SCI论文撰写

土壤风蚀是一个全球性的环境问题。中国是世界上受土壤风蚀危害最严重的国家之一,土壤风蚀是中国干旱、半干旱及部分湿润地区土地荒漠化的首要过程。中国风蚀荒漠化面积达160.74104km2,占国土总面积的16.7%,严重影响这些地区的资源开发和社会经…

SpringBoot原理分析 | 安全框架:Shiro

💗wei_shuo的个人主页 💫wei_shuo的学习社区 🌐Hello World ! Shiro Shiro是一个安全框架,用于认证、授权和管理应用程序的安全性。它提供了一组易于使用的API和工具,可以帮助您轻松地添加安全性到您的应用…

2.10 Android ebpf帮助函数解读(九)

161.struct task_struct *bpf_get_current_task_btf(void) 描述:返回一个指向"current"的BTF指针。这个指针可以用来在帮助函数中接收一个task_struct类型的ARG_PTR_TO_BTF_ID。 返回值:返回指向当前task的指针。 162.long bpf_bprm_opts_set(struct linux_binpr…

iOS开发-hook之Method Swizzle更改原有方法实现流程

iOS开发-hook之Method Swizzle更改原有方法实现流程 一 Hook是什么? Hook 简介 Hook,中文译为“挂钩”或“钩子”。通过hook可以让别人的程序执行自己所写的代码。 一段程序的执行流程是 A -> B -> C,现在我们在 A 和 B 之间插入一…

一款基于过滤器的线程共享变量的清理机制

项目中常常用到线程共享变量。如多个函数或对象之间传递参数。循环读取缓存或数据库时时用共享变量减少读取次数。某类特殊对象的持有等。一般用finally去强制释放共享变量。但释放时机有时并不能准确的把握。为此,基于过滤器写了个个释放机制。 过滤器如下&#x…

ubuntu22.04 DNSSEC(加密DNS服务) configuration

/etx/systemd/resolved.conf是ubuntu下DNS解析服务配置文件,systemd为ubuntu下system and service配置目录 step 1——修改resolved.conf参数 管理员权限打开 /systemd/resolved.conf sudo nano /etc/systemd/resolved.conf修改如下: # This file i…

vr禁毒毒驾模拟体验从源头拒绝毒品,预防毒品

俗话说,一念天堂,一念地狱。吸毒一口,掉入虎口。吸毒对人体的危害非常大,普通人吸毒会导致家破人亡,明星吸毒会毁掉自己的大好星途。没有感同身受,何来悲喜相通,毒品危害认知VR模拟情景体验是VR…

利用频谱仪进行简单的2.4G 频率测试

一、概述 1. 信号源 我们开发2.4G 无线产品的时候,经常需要对产品的无线信号进行测试,以确定精确的频率。在进行频率测试之前,我们的2.4G 射频芯片需要进入单载波模式。 2. 频谱仪 这里选择的是普源的频谱仪。测试范围是 9kHz - 3.2GHz。…

Jtti:Linux内存管理中的slab缓存怎么实现

在Linux内存管理中,slab缓存是一种高效的内存分配机制,用于管理小型对象的内存分配。slab缓存的实现是通过SLAB分配器来完成的,它在Linux内核中对内存分配进行优化。 SLAB分配器将内存分为三个区域:slab、partial、和empty。 Slab…

hive 全量表、增量表、快照表、切片表和拉链表

全量表:记录每天的所有的最新状态的数据,增量表:记录每天的新增数据,增量数据是上次导出之后的新数据。快照表:按日分区,记录截止数据日期的全量数据切片表:切片表根据基础表,往往只…

Java-day03(程序流程控制)

程序流程控制 1.顺序结构 程序从上至下逐行执行,无判断与跳转 public class Test1{ public static void main(String[] args){int i 1;int j i 1; System.out.println(j);} }2.分支结构 依据条件,选择性执行某段语句 主要有以下两种 2.1 i…

知识图谱实战应用22-数据导入技巧与基于py2neo的金融领域风险评估的应用

大家好,我是微学AI,今天给大家介绍一下知识图谱实战应用22-数据导入技巧与基于py2neo的金融领域风险评估的应用。本文的金融领域风险评估的应用旨在利用知识图谱技术对金融风险进行评估和管理。该项目利用py2neo库与Neo4j图数据库进行交互,构建一个金融领域的知识图谱,并根…

vue 封装一个鼠标拖动选择时间段功能

<template><div class"timeRange"><div class"calendar"><table><thead><tr><th rowspan"6" class"weekRow"><b>周/时间</b></th><th colspan"24"><…

【机器学习】西瓜书习题3.3Python编程实现对数几率回归

参考代码 结合自己的理解&#xff0c;添加注释。 代码 导入相关的库 import numpy as np import pandas as pd import matplotlib from matplotlib import pyplot as plt from sklearn import linear_model导入数据&#xff0c;进行数据处理和特征工程 # 1.数据处理&#x…

Linux 学习记录60(ARM篇)

Linux 学习记录60(ARM篇) 本文目录 Linux 学习记录60(ARM篇)一、SPI总线1. 概念2. 硬件连接 二、SPI总线协议三、SPI总线通信模式四、对比IIC总线和SPI总线1. 相同点2. 不同点 思维导图 一、SPI总线 1. 概念 1、SPI总结是Motorola首先提出的全双工三线/四线同步串行总线 2、采…

Rust- 模块

&#xff08;1&#xff09;在项目根目录下创建mylib&#xff08;里面实现自定义的外部模块&#xff09; cargo new --lib mylib &#xff08;2&#xff09;在 项目名\mylib\src\lib.rs文件中实现新模块 pub mod add_salary {pub fn study(name: String) {println!("Rust…

WEB浏览器轻松读写NDEF智能海报、地图坐标、文本标签信息

本示例使用的发卡器&#xff1a;Android Linux RFID读写器NFC发卡器WEB可编程NDEF文本/智能海报/-淘宝网 (taobao.com) <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&…

Python状态模式介绍、使用

一、Python状态模式介绍 Python状态模式&#xff08;State Pattern&#xff09;是一种行为型设计模式&#xff0c;它允许对象在不同的状态下表现不同的行为&#xff0c;从而避免在代码中使用多重条件语句。该模式将状态封装在独立的对象中&#xff0c;并根据当前状态选择不同的…

flutter开发实战-图片保存到相册

flutter开发实战-图片保存到相册。保存相册使用的是image_gallery_saver插件 一、引入image_gallery_saver插件 在pubspec.yaml中引入插件 # 保存图片到相册image_gallery_saver: ^1.7.1# 权限permission_handler: ^10.0.0二、保存到相册的代码 使用image_gallery_saver将图…