FatFs学习笔记

合集下载

FATFS深入理解

FATFS深入理解

一、通过格式化命令-看磁盘文件系统的建立过程1、添加format命令,单步调试所有的底层驱动函数都已经准备好。

添加格式化命令format后,编译下载。

Format命令的执行主要是调用f_mkfs()函数,下面进行单步调试。

以下主要列出函数的主要执行步骤:res=f_mkfs( 0, 1, 4096 ); //1表示不需要引导扇区。

4096是8个扇区。

进入f_mkfs()函数,这里只列出主要执行步骤:if (disk_ioctl(drv, GET_SECTOR_COUNT, &n_part) != RES_OK || n_part < MIN_SECTOR)return FR_MKFS_ABORTED;这个函数调用后,n_part=0x000F,3400 = 996 352,这是SD的总块数。

allocsize /= SS(fs); 等于8/*Number of sectors per cluster */n_clst = n_part / allocsize; //等于0x1E680 = 124 544 簇。

if (n_clst >= 0xFFF5) fmt = FS_FAT32; 所以文件系统确定为FAT32类型。

n_fat = ((n_clst * 4) + 8 + SS(fs) - 1) / SS(fs); 等于0x3CE = 974,表示FAT要占据974个扇区。

n_rsv = 33 - partition; 保留扇区32个。

n_dir = 0;b_fat = b_part + n_rsv; /* FATs start sector 32扇区*/b_dir = b_fat + n_fat * N_FATS; /* Directory start sector 0x3EE =1006,由于FAT表个数设为1个,所以目录区=FAT起始+FAT占用扇区数*/b_data = b_dir + n_dir; /* Data start sector */以上三项确定FAT区域、根目录区、数据区的起始扇区。

详细了解并学习FatFS文件系统的基本原理

详细了解并学习FatFS文件系统的基本原理

详细了解并学习FatFS文件系统的基本原理最近做的spi flash,本打算弄个文件系统,由于之前用过了JFFS、YAFFS和TrueFFS,代码量都相当的大,这次想找款代码量不那么吓人的,学习一下,听说配置会相对复杂一些。

选来选去,最终选定了FatFS,代码量足够的小,最新的R0.09版本只有1个.c文件(当然,还有一个底层的要自己写,option文件夹里的无视),老点版本就更小了。

而且更新很频繁,用户量也够大,就选定它了。

尽管最后由于硬件和项目原因未能实际的移植它到vxWorks,但学过的还是要记录下。

在这里http://elm-chan/fsw/ff/00index_el下载源码,只有800多K,小的可怜,还可以下载示例程序,有A VR、Win32、lpc等多平台已实现的方案。

打开看src文件夹,一个opTIon 文件夹、00readme.txt、diskio.h、ff.c、ff.h、ffconf.h和interger.h。

移植时需要修改的文件主要包括ffconf.h和interger.h,后者是在它的定义与目标平台上的有冲突,或者用的不习惯时修改的。

在做具体修改之前,先大概阅读下FatFS的源代码,可以先读integer.h,了解所用的数据类型,然后是ff.h,了解文件系统所用的数据结构和各种函数声明,再就是diskio.h,了解与介质相关的数据结构和操作函数。

ff.c这个文件相对较大,可以在最后将所实现的函数大致扫描一遍,之后根据用户应用层程序调用函数的次序仔细阅读相关代码。

各个文件都可以直接用记事本打开查阅,非常方便。

ff.h中的几个结构体十分重要,列举如下,首先是最基础的文件系统结构体:view plaincopy to clipboardprint?/* File system object structure (FATFS) */typedef struct {BYTE fs_type; /* FAT子类型,一般在mount时用,置0表示未挂载*/BYTE drv; /* 物理驱动号,一般为0*/BYTE csize; /* 每个簇的扇区数目(1,2,4...128) */BYTE n_fats; /* 文件分配表的数目(1,2) */。

fatfs文件系统函数

fatfs文件系统函数

fatfs文件系统函数FatFs 文件系统函数详解导语:FatFs 是一个跨平台、开源的文件系统实现,广泛应用于嵌入式设备。

本文将详细介绍 FatFs 文件系统函数的使用方法和实现原理。

第一节:FatFs 是什么?1.1 背景介绍嵌入式设备通常需要一个文件系统来管理储存和访问数据,而 FatFs 就是一个能够在 flash、SD 卡等储存介质上运行的文件系统实现。

1.2 FatFs 的功能FatFs 提供了一系列的文件系统函数,包括文件的创建、删除、读取、写入,目录的创建、删除、改名等。

同时,FatFs 还提供了簇管理、簇链、簇链索引的功能,以及对文件系统的格式化、检查、优化等操作。

第二节:FatFs 的使用方法2.1 环境配置在开始使用 FatFs 之前,首先要配置开发环境。

基本的配置包括硬件平台的选择和文件系统的选择。

FatFs 支持多种平台,如ARM、AVR、PIC、STM32等,并且支持多种文件系统类型,如FAT12、FAT16、FAT32等。

2.2 创建文件系统对象在使用 FatFs 的文件系统函数之前,需要先创建一个文件系统对象,并为其指定一个驱动器号。

驱动器号可以认为是一个逻辑卷,可以是实体存储介质上的一个分区或一个逻辑卷。

2.3 挂载文件系统在文件系统对象创建之后,需要通过调用 f_mount 函数来将文件系统对象挂载到系统中。

挂载文件系统的过程中,需要指定文件系统类型、逻辑卷号等参数。

2.4 文件的创建、打开和关闭通过使用文件系统函数可以创建、打开和关闭文件。

使用 f_open 函数可以创建一个新文件或打开一个已有的文件,指定打开的方式(读、写、追加等)和文件名。

使用 f_close 函数可以关闭一个已打开的文件。

2.5 文件的读取和写入文件系统函数提供了对文件的读取和写入操作。

通过 f_read 函数可以从文件中读取数据,指定读取的缓冲区和读取的大小。

通过 f_write 函数可以向文件中写入数据,指定写入的缓冲区和写入的大小。

FATFS深入理解

FATFS深入理解

FATFS深⼊理解⼀、通过格式化命令-看磁盘⽂件系统的建⽴过程1、添加format命令,单步调试所有的底层驱动函数都已经准备好。

添加格式化命令format后,编译下载。

Format命令的执⾏主要是调⽤f_mkfs()函数,下⾯进⾏单步调试。

以下主要列出函数的主要执⾏步骤:res=f_mkfs( 0, 1, 4096 ); //1表⽰不需要引导扇区。

4096是8个扇区。

进⼊f_mkfs()函数,这⾥只列出主要执⾏步骤:if (disk_ioctl(drv, GET_SECTOR_COUNT, &n_part) != RES_OK || n_part < MIN_SECTOR)return FR_MKFS_ABORTED;这个函数调⽤后,n_part=0x000F,3400 = 996 352,这是SD的总块数。

allocsize /= SS(fs); 等于8/*Number of sectors per cluster */n_clst = n_part / allocsize; //等于0x1E680 = 124 544 簇。

if (n_clst >= 0xFFF5) fmt = FS_FAT32; 所以⽂件系统确定为FAT32类型。

n_fat = ((n_clst * 4) + 8 + SS(fs) - 1) / SS(fs); 等于0x3CE = 974,表⽰FAT要占据974个扇区。

n_rsv = 33 - partition; 保留扇区32个。

n_dir = 0;b_fat = b_part + n_rsv; /* FATs start sector 32扇区*/b_dir = b_fat + n_fat * N_FATS; /* Directory start sector 0x3EE =1006,由于FAT表个数设为1个,所以⽬录区=FAT起始+FAT 占⽤扇区数*/b_data = b_dir + n_dir; /* Data start sector */以上三项确定FAT区域、根⽬录区、数据区的起始扇区。

STM32笔记(六)SD卡的读写和FatFS文件系统

STM32笔记(六)SD卡的读写和FatFS文件系统

STM32笔记(六)SD卡的读写和FatFS文件系统因为要用,学习了一下SPI操作SD卡,同时移植了一个免费开源的FAT文件系统:FatFS。

感觉挺好,在单片机上实现了读写文件的操作,接下来就可以解释我的G代码咯!我的SD卡底层操作参考了网上几种常见的代码,但又对其结构做了一定的优化,至少看起来用起来比较方便。

既可以作为文件系统的diskio使用,也可以直接使用底层函数,把SD卡作为一块flash读写。

FatFs文件系统体积蛮小,6-7K足矣,对于128Kflash的STM32来说很合适,代价不大。

同时可移植性很高,最少只需要4个函数修改既可以实现文件系统的移植。

相关文件系统的介绍请看这里。

这里给一套比较完整的参考资料,包括fatfs文件系统的原版资料、几个重要的手册和网上下载的代码。

/bbs/bbs_content.jsp?bbs_sn=3210864&bbs_page_no=1&bbs_id=3020 下面是我的代码:其中底层的SPI总线对SD卡的操作在SPI_SD_driver.c/h中,而FATFS的移植文件diskio.c中对磁盘的操作函数中将调用底层的操作函数。

下面是一些底层操作函数:u8 SPI_ReadWriteByte(u8 TxData); //SPI总线读写一个字节u8 SD_WaitReady(void); //等待SD卡就绪u8 SD_SendCommand(u8 cmd, u32 arg, u8 crc); //SD卡发送一个命令u8 SD_SendCommand_NoDeassert(u8 cmd, u32 arg, u8 crc); //SD卡发送一个命令,不断线u8 SD_Init(void); //SD卡初始化u8 SD_ReceiveData(u8 *data, u16 len, u8 release); //SD卡读数据u8 SD_GetCID(u8 *cid_data); //读SD卡CIDu8 SD_GetCSD(u8 *csd_data); //读SD卡CSDu32 SD_GetCapacity(void); //取SD卡容量u8 SD_ReadSingleBlock(u32 sector, u8 *buffer); //读一个sectoru8 SD_WriteSingleBlock(u32 sector, const u8 *buffer); //写一个sectoru8 SD_ReadMultiBlock(u32 sector, u8 *buffer, u8 count); //读多个sectoru8 SD_WriteMultiBlock(u32 sector, const u8 *data, u8 count); //写多个sector这是diskio.c中的一段代码,在disk初始化中,我们调用了SPI_SD_driver.c中的SD卡初始化函数。

FAT文件系统部分摘记

FAT文件系统部分摘记

FAT文件系统部分摘记FAT文件系统部分摘记1、磁道当磁盘在旋转时,磁头若保持在一个位置上,则每个磁头都会在磁盘表面划出一个圆形轨迹,这些圆形轨迹就叫做磁道。

每张盘片上的磁道由外向内依次从“0”开始进行编号。

虽然磁道的编号是“由外向内依次从“0”开始进行编号”,但这并不意味着“0”磁道是位于磁盘片的最外沿的。

固件区的物理位置有的位于比“0”磁道更靠近磁盘片的外缘的磁道上。

有的位于磁盘片的中部。

2、扇区磁盘上的每个磁道被等分为若干个弧段,这些弧段便是磁盘的扇区。

每个扇区大小为512字节。

扇区从“1”开始编号。

3、DOC分区虽然我们的存储介质没有分区(你的u盘,sd卡等小容量存储介质肯定没有分区的吧)。

但是在文件系统初始化的开始我们必须通过MBR获取分区表项的数据,以获得CHS、LBA参数以及分区大小扇区数,否则就无法知道你文件系统的起始物理扇区号Microsoft将使用DOC分区体系的磁盘称为“主引导记录(Mas ter Boot recorder,MBR)”磁盘,这是对于使用“全局ID分区表(GUID Partition T able, GPT)磁盘”而言的。

4、主引导记录扇区使用“DOC分区”体系时,磁盘的第一个——也就是0号扇区被称为主引导记录扇区,也称为主引导记录MBR(Master Boot record er,MBR)。

MBR由446个字节的引导代码、64字节的主分区(4个)表及两个字节的签名值“55 AA”组成。

5、FAT文件系统简介文件系统会在你把文件存放到某个目录下时记录下你文件的信息(文件存放的起始簇号,文件大小,文件创建、修改、访问、保存的时间等等),当你下次要打开那个文件时,文件系统就根据已知的文件信息去寻找它,找到后,你就又可以读,写,修改,移动你的文件了,并且文件系统会同时更新。

文件系统会在你把文件存放到某个目录下时记录下你文件的信息(文件存放的起始簇号,文件大小,文件创建、修改、访问、保存的时间等等),当你下次要打开那个文件时,文件系统就根据已知的文件信息去寻找它,找到后,你就又可以读,写,修改,移动你的文件了,并且文件系统会同时更新。

FATFS文件系统剖析(全)要点

FATFS文件系统剖析(全)要点

FATFS文件系统剖析1:FAT16:数据按照其不同的特点和作用大致可分为5部分:MBR区、DBR区、FAT区、DIR区和DATA区,相比fat12多了DBR区Main boot record: MBR(0--1bdh)磁盘参数存放DPT(1beh--1fdh)磁盘分区表55,aa 分区结束标志DBR(Dos Boot Record)是操作系统引导记录区的意思FAT区(有两个,一个备份):对于fat16,每一个fat项16位,所以可寻址的簇项数为65535(2的16次方)。

而其每簇大小不超过32k,所以其每个分区最大容量为2G。

fat32,每一个fat项32位,可寻址簇数目为2的32次方。

DIR区(根目录区):紧接着第二FAT表(即备份的FAT表)之后,记录着根目录下每个文件(目录)的起始单元,文件的属性等。

定位文件位置时,操作系统根据DIR中的起始单元,结合FAT表就可以知道文件在硬盘中的具体位置和大小了。

DATA区:实际文件内容存放区。

FAT32:暂时放在这里,不讨论!Fatfs:嵌入式fat文件系统,支持fat16,fat32。

包含有ff.h,diskio.h,integer.h,ffconf.h 四个头文件以及ff.c 文件系统实现。

当然要实现具体的应用移植,自己要根据diskio.h实现其diskio。

c 底层驱动。

diskio.h : 底层驱动头文件ff.h : 文件系统实现头文件,定义有文件系统所需的数据结构ff.c : 文件系统的具体实现如下开始逐个文件加以分析:integer.h :仅实现数据类型重定义,增加系统的可移植性。

ffconf.h : 文件系统配置---逐个配置,先配置实现一个最小的fat文件系统,下面来分析各配置选项:#define _FFCONF 8255 //版本号#define _FS_TINY 0 /* 0:Normal or 1:Tiny */ //在这里与先前版本有些许变化,是通过配置头配置两种不同大小的文件系统,这里配置为0。

STM32之FATFS文件系统(SPI方式)笔记

STM32之FATFS文件系统(SPI方式)笔记

STM32之FATFS文件系统(SPI方式)笔记BY:T7Date:20171202At:YSU_B307开发环境:uVision: V5.12.0.0STM32F103V8T6库版本: STM32F10x_StdPeriph_Lib_V3.5.0FATSF : ff13a工程版本:FATFS_V1日期:20171130硬件连接:SPI1_CS -> PA4 SPI1_CLK -> PA5 SPI1_MISO -> PA6 SPI1_MOSI -> PA7工程功能:建立在SPI_SD的基础上,完成文件系统的初步接触。

一、FATFS文件系统1.使用开源的FAT文件系统模块,其源代码的获取从官网:目前最新版本是:ff13a2.解压后得到两个文件:其中,documents相当于STM32的固件库使用手册,介绍FATFS系统的函数使用方法,source 中则是需要用到的源代码。

因为FATFS使用SD卡,所以FATFS的基础是SD卡的正常读写,这里采用SPI模式。

二、STM32之SD卡_SPI模式1.硬件连接:SPI1_CS -> PA4 SPI1_CLK -> PA5 SPI1_MISO -> PA6 SPI1_MOSI -> PA72.SPI模式下STM32读写SD卡的工程结构在确定STM32使用SPI模式读写SD卡没有问题后,进入FATSF文件系统的实验,另源代码在文档最后。

三、FATSF文件系统移植1.配置工程环境1)STM32读写SD卡-SPI模式成功2)将解压后的ff13a整个文件夹赋值到工程目录下,如图:3)返回到MDK界面下,添加ff13a项目组,并把ff13a\source\目录下ff.c,diskio.c,ffunicode.c,ffsystem.c添加到项目组中,如下列图:4)在Target Options的C++编译器选项中添加文件包含路径,如下列图四、为FATSF文件系统添加底层驱动〔一〕在diskio.c中添加函数代码1.DSTATUS disk_status (BYTE pdrv); 添加完成后如下列图2.DSTATUS disk_initialize (BYTE pdrv); 添加完成后如下列图3.DRESULT disk_read (BYTE pdrv, BYTE* buff, DWORD sector, UINT count);4.DRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count);5.DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff);6.DWORD get_fattime (void);注意:在diskio.c中DEV_MMC的宏定义要为0,如下列图(二)打开Ffconf.h函数1.改变FF_CODE_PAGE的值如下2.改变FF_USE_LFN的值如下五、Main主函数Main.c函数如下代码:#include "main.h"#define ONE_BLOCK 512#define TWO_BLOCK 1024uint8_t sd_RxBuf[TWO_BLOCK];//SD卡数据j接收缓存区uint8_t sd_TxBuf[TWO_BLOCK] = {0};//SD卡数据j接收缓存区FRESULT res;//读写文件的返回值FIL FileSyatemSrc,FileSystemDst;//文件系统结构体,包含文件指针等成员UINT br,bw;//Fil R/W countBYTE FileRxBuffer[ONE_BLOCK];//FILE COPY BUFFER//BYTE TxFileBuffer[] = "This is the FATFS System!\r\n";BYTE TxFileBuffer[] = "中文文件系统实验!\r\n";static const char * FR_Table[]={"FR_OK:成功", /* (0) Succeeded */"FR_DISK_ERR:底层硬件错误", /* (1) A hard error occurred in the low level disk I/O layer */"FR_INT_ERR:断言失败", /* (2) Assertion failed */"FR_NOT_READY:物理驱动没有工作", /* (3) The physicaldrive cannot work */"FR_NO_FILE:文件不存在", /* (4) Could not find the file */"FR_NO_PATH:路径不存在", /* (5) Could not find the path */"FR_INVALID_NAME:无效文件名", /* (6) The path name format is invalid */"FR_DENIED:由于禁止访问或者目录已满访问被拒绝", /* (7) Access denied due to prohibited access or directory full */"FR_EXIST:由于访问被禁止访问被拒绝", /* (8) Access denied due to prohibited access */"FR_INVALID_OBJECT:文件或者目录对象无效", /* (9) The file/directory object is invalid */"FR_WRITE_PROTECTED:物理驱动被写保护", /* (10) The physical drive is write protected */"FR_INVALID_DRIVE:逻辑驱动号无效", /* (11) The logical drive number is invalid */"FR_NOT_ENABLED:卷中无工作区", /* (12) The volume has no work area */"FR_NO_FILESYSTEM:没有有效的FAT卷", /* (13) There is no valid FAT volume */"FR_MKFS_ABORTED:由于参数错误f_mkfs()被终止", /* (14) The f_mkfs() aborted due to any parameter error */"FR_TIMEOUT:在规定的时间内无法获得访问卷的许可", /* (15) Could not get a grant to access the volume within defined period */"FR_LOCKED:由于文件共享策略操作被拒绝", /* (16) The operation is rejected according to the file sharing policy */"FR_NOT_ENOUGH_CORE:无法分配长文件名工作区", /* (17) LFN working buffer could not be allocated */"FR_TOO_MANY_OPEN_FILES:当前打开的文件数大于_FS_SHARE", /* (18) Number of open files > _FS_SHARE */"FR_INVALID_PARAMETER:参数无效" /* (19) Given parameter is invalid */};int main(void){int i = 0;FATFS fs;//记录文件系统盘符信息的结构体LED_Init();USARTx_Init();/* 调用f_mount()创建一个工作区,另一个功能是调用了底层的disk_initialize()函数,进行SDIO借口的初始化*/res = f_mount(&fs, "0:", 1 );if (res != FR_OK){printf("挂载文件系统失败(%s)\r\n", FR_Table[res]);}else{printf("挂载文件系统成功(%s)\r\n", FR_Table[res]);}/* 调用f_open()函数在刚刚开辟的工作区的盘符0下打开一个名为Demo.TXT的文件,以创建新文件或写入的方式打开(参数"FA_CREATE_NEW | FA_WRITE"),如果不存在的话则创建这个文件。

fatfs 读写模式解析

fatfs 读写模式解析

fatfs 读写模式解析摘要:1.FATFS 文件系统概述2.FATFS 文件系统的读写模式3.FATFS 文件系统的优缺点正文:【FATFS 文件系统概述】FATFS(File Allocation Table File System) 是一种常见的文件系统,常用于存储设备中,例如硬盘、U 盘、SD 卡等。

FATFS 文件系统采用表格方式来存储文件的分配表,从而实现对文件的读写管理。

FATFS 文件系统支持多种设备,并且具有较好的兼容性,因此被广泛使用。

【FATFS 文件系统的读写模式】FATFS 文件系统的读写模式分为三种:只读模式、读写模式和写保护模式。

1.只读模式:在只读模式下,用户只能读取文件,不能修改文件。

该模式通常用于只读设备,例如CD-ROM、DVD-ROM 等。

2.读写模式:在读写模式下,用户既可以读取文件,也可以修改文件。

该模式通常用于可读写设备,例如硬盘、U 盘、SD 卡等。

3.写保护模式:在写保护模式下,用户只能读取文件,不能修改文件。

该模式通常用于防止数据被误删除或修改的场景,例如某些设备的启动盘等。

【FATFS 文件系统的优缺点】FATFS 文件系统的优点包括:1.兼容性好:FATFS 文件系统可以支持多种设备,并且具有较好的兼容性,可以实现不同设备之间的数据共享。

2.稳定性好:FATFS 文件系统采用表格方式来存储文件的分配表,从而实现对文件的读写管理,具有较好的稳定性。

3.支持大容量存储:FATFS 文件系统支持大容量存储,可以满足不同设备的存储需求。

FATFS 文件系统的缺点包括:1.存储效率低:FATFS 文件系统采用表格方式来存储文件的分配表,导致存储效率较低。

2.安全性差:FATFS 文件系统采用明文方式来存储文件名和数据,容易导致数据泄露和安全问题。

3.不支持高级功能:FATFS 文件系统不支持高级功能,例如文件加密、压缩等。

【结论】FATFS 文件系统是一种常见的文件系统,采用表格方式来存储文件的分配表,实现对文件的读写管理。

fatfs避免文件碎片的方法

fatfs避免文件碎片的方法

fatfs避免文件碎片的方法(原创版4篇)《fatfs避免文件碎片的方法》篇1在FATFS文件系统下,要避免文件碎片,可以使用以下两种方法:1. 合理使用文件删除和写入操作:在进行文件删除和写入操作时,要尽量避免同时进行,尽量保证每个文件操作的连续性和完整性。

例如,在删除一个文件后,应立即创建一个新文件,而不是等待一段时间后再创建。

这样可以减少文件的碎片数量。

2. 定期整理磁盘空间:定期对磁盘空间进行整理,可以清除磁盘上的冗余数据和垃圾文件,减少磁盘碎片的产生。

可以使用磁盘清理工具或手动删除不需要的文件和文件夹。

《fatfs避免文件碎片的方法》篇2FATFS(File Allocation Table File System)是一种用于嵌入式系统的文件系统,它支持FAT12、FAT16和FAT32文件格式。

在FATFS中,文件碎片通常是由于频繁地删除和创建文件而导致的。

为了避免文件碎片,可以采取以下方法:1. 减少文件删除和创建操作:尽量减少频繁的文件删除和创建操作,尤其是对大文件的删除和创建。

这样可以减少文件系统中的簇变化,从而减少文件碎片的产生。

2. 定期整理磁盘空间:定期使用磁盘清理工具清理磁盘空间,释放无用的簇。

这样可以减少磁盘空间的碎片,从而提高了文件系统的性能。

3. 使用大型文件:尽量使用大型文件,而不是小文件。

这样可以减少簇的使用次数,从而减少了文件碎片的产生。

4. 使用缓存:使用缓存可以减少磁盘访问次数,从而减少了文件碎片的产生。

5. 定期备份:定期备份数据可以避免数据丢失,同时也可以减少数据碎片的产生。

《fatfs避免文件碎片的方法》篇3FATFS(File Allocation Table File System)是一种用于嵌入式系统的文件系统,它支持FAT12、FAT16和FAT32文件格式。

为了避免文件碎片,可以采取以下方法:1. 定期清理文件:定期删除不再需要的文件或文件夹,可以减少文件碎片的产生。

18-STM32CubeMX系列教程18文件系统FATFS

18-STM32CubeMX系列教程18文件系统FATFS

在main.c文件前面添加错误处理函数声明。
5/7
/* USER CODE BEGIN PFP */ /* Private function prototypes -----------------------------------------------*/ static void Error_Handler(void); /* USER CODE END PFP */
在FATFS配置中选择简体中文字GBK编码支持 中文,使能长文件名,缓存存储在堆 (STACK)中。
1/7
点击菜单栏中Project->Setting修改堆的大小,堆设置为0x1000。(注意:由于刚才设置长文件名 动态缓存存储在堆中,故需要增大堆大小,如果不修改则程序运行时堆会生成溢出,程序进入硬件错误 中断(HardFault),死循环)。
编译程序并下载到开发板。将Micro SD卡插入Micro SD Storage Board中,再插到Open746I-C开发的 SDMMC接口中。打开串口调试助手,设置波特率为115200,按下复位串口助手上面会显示如下信息。
下载简介一下FATFS的几个操作函数。 1.f_mount 在FatFs模块上注册、注销一个工作区(文件系统对象)。
在main函数中添加应用程序。程序中首先注 册一个文件系统对象,然后新 建STM32cube.txt文件,将数据写文件中再读 出来,判断文件系统是否工作正常。
4/7
/* USER CODE BEGIN 2 */ printf("\r\n ****** FatFs Example ******\r\n\r\n"); /*##-1- Register the file system object to the FatFs module ##############*/ retSD = f_mount(&fs, "", 0); if(retSD) { printf(" mount error : %d \r\n",retSD); Error_Handler(); } else printf(" mount sucess!!! \r\n"); /*##-2- Create and Open new text file objects with write access ######*/ retSD = f_open(&fil, filename, FA_CREATE_ALWAYS | FA_WRITE); if(retSD) printf(" open file error : %d\r\n",retSD); else printf(" open file sucess!!! \r\n"); /*##-3- Write data to the text files ###############################*/ retSD = f_write(&fil, wtext, sizeof(wtext), (void *)&byteswritten); if(retSD) printf(" write file error : %d\r\n",retSD); else { printf(" write file sucess!!! \r\n"); printf(" write Data : %s\r\n",wtext); } /*##-4- Close the open text files ################################*/ retSD = f_close(&fil); if(retSD) printf(" close error : %d\r\n",retSD); else printf(" close sucess!!! \r\n"); /*##-5- Open the text files object with read access ##############*/ retSD = f_open(&fil, filename, FA_READ); if(retSD) printf(" open file error : %d\r\n",retSD); else printf(" open file sucess!!! \r\n"); /*##-6- Read data from the text files ##########################*/ retSD = f_read(&fil, rtext, sizeof(rtext), (UINT*)&bytesread); if(retSD) printf(" read error!!! %d\r\n",retSD); else { printf(" read sucess!!! \r\n"); printf(" read Data : %s\r\n",rtext); } /*##-7- Close the open text files ############################*/ retSD = f_close(&fil); if(retSD) printf(" close error!!! %d\r\n",retSD); else printf(" close sucess!!! \r\n"); /*##-8- Compare read data with the expected data ############*/ if(bytesread == byteswritten) { printf(" FatFs is working well!!!\r\n"); } /* USER CODE END 2 */

FatFs详解

FatFs详解

最近做的spi flash,本打算弄个文件系统,由于之前用过了JFFS、YAFFS和TrueFFS,代码量都相当的大,这次想找款代码量不那么吓人的,学习一下,听说配置会相对复杂一些。

选来选去,最终选定了FatFS,代码量足够的小,最新的R0.09版本只有1个.c文件(当然,还有一个底层的要自己写,option文件夹里的无视),老点版本就更小了。

而且更新很频繁,用户量也够大,就选定它了。

尽管最后由于硬件和项目原因未能实际的移植它到vxWorks,但学过的还是要记录下。

在这里/fsw/ff/00index_e.html下载源码,只有800多K,小的可怜,还可以下载示例程序,有AVR、Win32、lpc等多平台已实现的方案。

打开看src文件夹,一个option文件夹、00readme.txt、diskio.h、ff.c、ff.h、ffconf.h和interger.h。

移植时需要修改的文件主要包括ffconf.h和interger.h,后者是在它的定义与目标平台上的有冲突,或者用的不习惯时修改的。

在做具体修改之前,先大概阅读下FatFS的源代码,可以先读integer.h,了解所用的数据类型,然后是ff.h,了解文件系统所用的数据结构和各种函数声明,再就是diskio.h,了解与介质相关的数据结构和操作函数。

ff.c这个文件相对较大,可以在最后将所实现的函数大致扫描一遍,之后根据用户应用层程序调用函数的次序仔细阅读相关代码。

各个文件都可以直接用记事本打开查阅,非常方便。

ff.h中的几个结构体十分重要,列举如下,首先是最基础的文件系统结构体:1. /* File system object structure (FATFS) */2. typedef struct {3. BYTE fs_type; /* FAT子类型,一般在mount时用,置0表示未挂载*/4. BYTE drv; /* 物理驱动号,一般为0*/5. BYTE csize; /* 每个簇的扇区数目(1,2,4...128) */6. BYTE n_fats; /* 文件分配表的数目(1,2) */7. /*FAT文件系统依次为:引导扇区、两个文件分配表、根目录区和数据区*/8. BYTE wflag; /* 标记文件是否被改动过,为1时要回写*/9. BYTE fsi_flag; /* 标记文件系统信息是否被改动过,为1时要回写*/10. WORD id; /* 文件系统挂载ID */11. WORD n_rootdir; /* 根目录区入口(目录项)的个数(用于FAT12/16)*/12. #if _MAX_SS != 51213. WORD ssize; /* 每扇区的字节数(用于扇区大于512Byte的flash) */14. #endif15. #if _FS_REENTRANT16. _SYNC_t sobj; /* 允许重入,即定义同步对象,用在tiny中*/17. #endif18. #if !_FS_READONLY19. DWORD last_clust; /* 最后一个被分配的簇*/20. DWORD free_clust; /* 空闲簇的个数*/21. DWORD fsi_sector; /* 存放fsinfo的扇区(用于FAT32) */22. #endif23. #if _FS_RPATH24. DWORD cdir; /* 允许相对路径时用,存储当前目录起始簇(0:root)*/25. #endif26. DWORD n_fatent; /* FAT入口数(簇的数目 + 2)*/27. DWORD fsize; /* 每个FAT所占扇区*/28. DWORD fatbase; /* FAT起始扇区*/29. DWORD dirbase; /* 根目录起始扇区(FAT32:Cluster#) */30. DWORD database; /* 数据目录起始扇区*/31. DWORD winsect; /* 当前缓冲区中存储的扇区号*/32. BYTE win[_MAX_SS]; /* 单个扇区缓存*/33. } FATFS;然后是与之相关的文件和文件夹结构体,附上具体注释:1. /* File object structure (FIL) */2. typedef struct {3. FATFS* fs; /* 所在的fs指针*/4. WORD id; /* 所在的fs挂载编号*/5. BYTE flag; /* 文件状态*/6. BYTE pad1; /* 不知道含义,也未见程序使用*/7. DWORD fptr; /* 文件读写指针*/8. DWORD fsize; /* 大小*/9. DWORD sclust; /* 文件起始簇(fsize=0时为0) */10. DWORD clust; /* 当前簇*/11. DWORD dsect; /* 当前数据扇区*/12. #if !_FS_READONLY13. DWORD dir_sect; /* 包含目录项的扇区 */14. BYTE* dir_ptr; /* Ponter to the directory entry in the window */15. #endif16. #if _USE_FASTSEEK17. DWORD* cltbl; /*指向簇链接映射表的指针*/18. #endif19. #if _FS_SHARE20. UINT lockid; /* File lock ID (index of file semaphore table) */21. #endif22. #if !_FS_TINY23. BYTE buf[_MAX_SS]; /* File data read/write buffer */24. #endif25. } FIL;下面是目录的:1. /* Directory object structure (DIR) */2. typedef struct {3. FATFS* fs; /* 同上*/4. WORD id;5. WORD index; /* 当前读写索引号 */6. DWORD sclust; /* 文件数据区开始簇*/7. DWORD clust; /* 当前簇*/8. DWORD sect; /* 当前扇区*/9. BYTE* dir; /* 扇区缓存中当前SFN入口指针,SFN含义未知,猜测和LFN类似,与文件名相关*/10. BYTE* fn; /* Pointer to the SFN (in/out) {file[8],ext[3],status[1]} */11. #if _USE_LFN12. WCHAR* lfn; /* Pointer to the LFN working buffer */13. WORD lfn_idx; /* Last matched LFN index number (0xFFFF:No LFN) */14. #endif15. } DIR;其他类似f_mount、f_open等接口API就不细说了,在挂载的时候其实真正起作用的是chk_mounted函数,在这里才会将挂载分区的相关信息分配到FatFS结构体中;还有一个get_fat函数,也比较重要,在f_open和许多目录操作的函数中都有用到,而且FAT入口这个表达也十分晦涩,而它又调用了一个move_window的函数,也是十分晦涩难懂,可能是我英语太烂的缘故吧。

FATFS浅谈(Tao3236)

FATFS浅谈(Tao3236)

更多资料见
更多资料见
酷学玩首页:
一.注册工作区域
FRESULT f_mount ( BYTE Drive, FATFS* FileSystemObject ); /* Logical drive number */ /* Pointer to the work area */
函数说明: 1. 此函数用来向文件中写入数据,前提是以写文件的方式打开文件 2. 参数说明: a) *FileObject : 指向文件对象结构体的指针 b) *Buffer : 指向数据缓冲的指针 c) ByteToWrite : 准备写入的字节数 d) *ByteWritten : 记录已写入的字节数,用来检测是否写完 3. 后两个参数的长度都是两个字节,计数值最大为 65536,所以一次写入字节数最大为 64K。一般情况下一次不会写这么长的数据,因为就算 RAM 足够用,也不会在里面开一 个几十 K 的数据缓冲区。 例程: 结合前面的 f_open 函数, 在下面例程中以写的方式新建一个 txt 文档, 然后写入 100 个字节。 已定义: unsighed char buffer[100] = "This is a new file, the data is just written in! 文件,数据也是新的!"; 这是一个新
函数说明: 1. 此函数可以打开,或新建一个文件 2. 参数说明 a) *FileObject : 指向一个用来存储文件对象的空结构体的指针 b) *FileName : 指向文件名的指针
c) ModeFlags : 打 开 方 式 , 可 以 是 以 下 一 种 或 几 种 的 组 合 ( 默 认 方 式 是 FA_OPEN_EXISTING) Value FA_READ FA_WRITE Description 读模式,(读写模式可同时生效) 写模式,(读写模式可同时生效) 打开文件,如果文件不存在,则创建一个新文件; 用此种方式,可以用 f_lseek 在文件后追加数据 新建文件,如果文件已存在,则新建失败

STM32的FATFS文件系统移植笔记 - 黑-月 - 博客园

STM32的FATFS文件系统移植笔记 - 黑-月 - 博客园

黑­月人在江湖!STM32的FATFS文件系统移植笔记一、序言经常在网上、群里看到很多人问关于STM32的FATFS文件系统移植的问题,刚好自己最近也在调试这个程序,为了让大家少走弯路,我把我的调试过程和方法也贡献给大家。

二、FATFS简介FatFs Module是一种完全免费开源的FAT文件系统模块,专门为小型的嵌入式系统而设计。

它完全用标准C语言编写,所以具有良好的硬件平台独立性,可以移植到8051、PIC、AVR、SH、Z80、H8、ARM等系列单片机上而只需做简单的修改。

它支持FATl2、FATl6和FAT32,支持多个存储媒介;有独立的缓冲区,可以对多个文件进行读/写,并特别对8位单片机和16位单片机做了优化。

三、移植准备1、FATFS源代码的获取,可以到官网下载:http://elm­/fsw/ff/00index_e.html 最新版本是R0.09版本,我们就移植这个版本的。

2、解压文件会得到两个文件夹,一个是doc文件夹,这里是FATFS的一些使用文档和说明,以后在文件编程的时候可以查看该文档。

另一个是src文件夹,里面就是我们所要的源文件。

3、建立一个STM32的工程,为方便调试,我们应重载printf()底层函数实现串口打印输出。

可以参考已经建立好的printf()打印输出工程:/bbs/foru ... d=77&extra=page%3D1四、开始移植1、在已经建立好的工程目录User文件夹下新建两个文件夹,FATFS_V0.09和SPI_SD_Card,FATFS_V0.09用于存放FATFS源文件,SPI_SD_Card用于存放SPI的驱动文件。

2、如图1将ff.c添加到工程文件夹中,并新建diskio.c文件,在diskio.c文件中实现五个函数:1. DSTATUS disk_initialize (BYTE);//SD卡的初始化2. DSTATUS disk_status (BYTE);//获取SD卡的状态,这里可以不用管3. DRESULT disk_read (BYTE, BYTE*, DWORD, BYTE);//从SD卡读取数据4. DRESULT disk_write (BYTE, const BYTE*, DWORD, BYTE);//将数据写入SD卡,若该文件系统为只读文件系统则不用实现该函数5. DRESULT disk_ioctl (BYTE, BYTE, void*);//获取SD卡文件系统相关信息图1导航管理我的标签keil(335)C51(308)工作之外(204)行业了解(189)USB(184)NFC(178)硬件设计(142)PCB(123)RFID(122)JAVA CARD(96)更多Powered by:博客园Copyright © 黑­月3、初步实现以上五个函数FATFS初始化函数:DSTATUS disk_initialize (BYTE drv /* Physical drive nmuber (0..) */){switch (drv){case 0 :return RES_OK;case 1 :return RES_OK;case 2 :return RES_OK;case 3 :return RES_OK;default:return STA_NOINIT;}}FATFS状态获取函数:DSTATUS disk_status (BYTE drv /* Physical drive nmuber (0..) */){switch (drv){case 0 :return RES_OK;case 1 :return RES_OK;case 2 :return RES_OK;default:return STA_NOINIT;}}FATFS底层读数据函数:DRESULT disk_read (BYTE drv, /* Physical drive nmuber (0..) */BYTE *buff, /* Data buffer to store read data */DWORD sector, /* Sector address (LBA) */BYTE count /* Number of sectors to read (1..255) */){if( !count ){return RES_PARERR; /* count不能等于0,否则返回参数错误 */}switch (drv){case 0:if(count==1) /* 1个sector的读操作 */{return RES_OK;} else /* 多个sector的读操作 */{return RES_OK;} case 1:if(count==1) /* 1个sector的读操作 */{return RES_OK;} else /* 多个sector的读操作 */{return RES_OK;}default:return RES_ERROR;}}FATFS底层写数据函数:DRESULT disk_write (BYTE drv, /* Physical drivenmuber (0..) */const BYTE *buff, /* Data to bewritten */DWORD sector, /* Sector address(LBA) */BYTE count /* Number ofsectors to write (1..255) */){if( !count ){return RES_PARERR; /* count不能等于0,否则返回参数错误 */}switch (drv){case 0:if(count==1) /* 1个sector的写操作 */{return RES_OK;} else /* 多个sector的写操作 */{return RES_OK;} case 1:if(count==1) /* 1个sector的写操作 */{return RES_OK;} else /* 多个sector的写操作 */{return RES_OK;}default:return RES_ERROR;}}FATFS磁盘控制函数:DRESULT disk_ioctl (BYTE drv, /* Physical drive nmuber(0..) */BYTE ctrl, /* Control code */void *buff /* Buffer tosend/receive control data */){if (drv==0){switch (ctrl){case CTRL_SYNC :return RES_OK;case GET_SECTOR_COUNT :return RES_OK;case GET_BLOCK_SIZE :return RES_OK;case CTRL_POWER :break;case CTRL_LOCK :break;case CTRL_EJECT :break;/* MMC/SDC command */case MMC_GET_TYPE :break;case MMC_GET_CSD :break;case MMC_GET_CID :break;case MMC_GET_OCR :break;case MMC_GET_SDSTAT :break;}}else if(drv==1){switch (ctrl){case CTRL_SYNC :return RES_OK;case GET_SECTOR_COUNT :return RES_OK;case GET_SECTOR_SIZE :return RES_OK;case GET_BLOCK_SIZE :return RES_OK;case CTRL_POWER :break;case CTRL_LOCK :break;case CTRL_EJECT :break;/* MMC/SDC command */case MMC_GET_TYPE :break;case MMC_GET_CSD :break;case MMC_GET_CID :break;case MMC_GET_OCR :break;case MMC_GET_SDSTAT :break;}}else{return RES_PARERR;}return RES_PARERR;}以上函数都只是实现一个框架,并没有做实际的事情,下一步就需要把操作SD卡的程序填充在这个框架里面。

FAT文件系统学习笔记

FAT文件系统学习笔记

1. FAT简介FAT是windows系统硬盘分区格式的一种。

从最早期的FAT12,FAT16到现在的FAT32,都是基于文件分配表(File Allocation Table)的。

一个FAT文件系统包括四个不同的部分:1、保留扇区,位于最开始的位置。

第一个保留扇区是引导区(分区启动记录)。

它包括一个称为基本输入输出参数块的区域(包括一些基本的文件系统信息尤其是它的类型和其它指向其它扇区的指针),通常包括操作系统的启动调用代码。

保留扇区的总数记录在引导扇区中的一个参数中。

引导扇区中的重要信息可以被DOS和OS/2中称为驱动器参数块的操作系统结构访问。

2、FAT区域。

文件分配表区共保存了两个相同的文件分配表,因为文件所占用的存储空间(簇链)及空闲空间的管理都是通过FAT实现的,FAT如此重要,保存两个以便第一个损坏时,还有第二个可用。

文件系统对数据区的存储空间是按簇进行划分和管理的,簇是空间分配和回收的基本单位,即,一个文件总是占用若干个整簇,文件所使用的最后一簇剩余的空间就不再使用,而是浪费掉了。

3、根目录区域。

它是在根目录中存储文件和目录信息的目录表。

在FAT32下它可以存在分区中的任何位置,但是在早期的版本中它永远紧随FAT区域之后。

4、数据区域。

这是实际的文件和目录数据存储的区域,它占据了分区的绝大部分。

通过简单地在 FAT中添加文件链接的个数可以任意增加文件大小和子目录个数(只要有空簇存在)。

然而需要注意的是每个簇只能被一个文件占有,这样的话如果在32KB大小的簇中有一个1KB大小的文件,那么31KB的空间就浪费掉了。

其中,与读取文件相关的两个部分是文件分配表(FAT)和文件目录表(FDT)。

通过文件目录表可以知道该文件的起始簇的位置,而通过文件分配表的簇链分布,可以知道该文件在硬盘中的所有簇的分布。

结合这两个部分就可以达到完全的文件读取了。

2. FAT文件分配表保留扇区不再多讲,下面介绍一下FAT区域。

fatfs结构体

fatfs结构体

FatFS结构体1. 什么是FatFS结构体FatFS(File Allocation Table File System)是一个用于嵌入式系统的开源文件系统,适用于各种类型的存储介质,如SD卡、闪存等。

FatFS结构体是FatFS库中最重要的数据结构,它定义了文件系统的各种参数和状态,为文件系统的正常运行提供了必要的支持。

2. FatFS结构体的成员FatFS结构体包含了以下成员:2.1 FATFS结构体定义typedef struct {Uint32 fs_type; /* 文件系统类型 */Uint8 drv; /* 逻辑驱动器号 */Uint8 csize; /* 链表块大小(单位为扇区) */Uint8 n_fats; /* FAT表数量 */Uint8 wflag; /* 写入标志 */Uint8 fsi_flag; /* FSI标志 */Uint16 id; /* 文件系统ID标识 */Uint16 n_rootdir; /* 根目录条目数 */Uint16 winsect; /* 当前窗口的开始扇区 */Uint32 max_clust; /* 最大簇号 */CLUST fatbase; /* FAT表起始扇区号 */CLUST dirbase; /* 根目录起始扇区号 */CLUST database; /* 数据起始扇区号 */CLUST sects_fat; /* FAT表扇区数 */CLUST sects_reserv; /* 保留扇区数 */CLUST sects_clust; /* 每簇扇区数 */FATFS* fs; /* 文件系统对象指针 */BYTE* buff; /* I/O缓冲区指针 */BYTE* dirbuf; /* 目录扫描缓冲区指针 */DWORD win[FF_MAX_SS / 4];/* 当前窗口块数据保存缓冲区 */} FATFS;2.2 成员说明•fs_type:文件系统类型,可以是FAT12、FAT16或FAT32。

fatfs 读写模式解析

fatfs 读写模式解析

fatfs 读写模式解析(实用版)目录1.FATFS 文件系统简介2.FATFS 文件系统的读写模式3.FATFS 文件系统的优缺点4.FATFS 文件系统的应用实例正文【FATFS 文件系统简介】FATFS(File Allocation Table File System)是一种常见的文件系统,主要用于管理闪存设备上的文件和文件夹。

FATFS 文件系统起源于DOS 时代,随后被 Windows 操作系统沿用,并逐渐发展为目前的 FAT32 和 exFAT 等格式。

FATFS 文件系统之所以广泛应用,主要是因为其简单易用、兼容性强以及对闪存设备友好等特点。

【FATFS 文件系统的读写模式】FATFS 文件系统的读写模式主要包括两种:顺序读写和随机读写。

1.顺序读写:顺序读写模式是指按照文件在存储设备上的物理顺序进行读写操作。

这种模式的优点是速度快,因为不需要在文件中进行跳跃查找。

缺点是如果需要对文件进行频繁的修改,会导致文件碎片化,影响存储效率。

2.随机读写:随机读写模式是指根据文件的逻辑地址进行读写操作,不受物理地址的限制。

这种模式的优点是可以根据需要对文件进行任意位置的读写,方便灵活。

缺点是需要进行地址转换,可能会影响读写速度。

【FATFS 文件系统的优缺点】FATFS 文件系统的优点包括:1.兼容性强:FATFS 文件系统可以兼容多种操作系统,如 Windows、Mac OS 和 Linux 等。

2.支持大容量存储:FATFS 文件系统可以管理大容量的闪存设备。

3.支持多种文件类型:FATFS 文件系统可以支持各种类型的文件,如文本文件、图片文件、音频文件和视频文件等。

FATFS 文件系统的缺点包括:1.文件碎片化:随着文件的频繁修改和删除,FATFS 文件系统可能会出现文件碎片化现象,影响存储效率。

2.存储空间利用率低:FATFS 文件系统采用固定大小的簇来管理文件,可能会导致存储空间的浪费。

fatfs学习笔记

fatfs学习笔记

fatfs学习笔记FatFsThe f_open function opens a file.FRESULT f_open (FIL* fp, /* [OUT] Pointer to the file object structure */const TCHAR* path, /* [IN] File name */BYTE mode/* [IN] Mode flags */);ParametersfpPointer to the blank file object structure.pathPointer to the null-terminated string that specifies the file name to open or create.modeMode flags that specifies the type of access and open method for the file. It is specified by a combination of following flags.Mode flags of POSIX fopen() corresponds to FatFs mode flags as follows:*1: glibc extensionReturn ValuesFR_OK, FR_DISK_ERR, FR_INT_ERR, FR_NOT_READY, FR_NO_F ILE, FR_NO_PATH, FR_INVALID_NAME, FR_DENIED, FR_EXIST, FR_ INVALID_OBJECT,FR_WRITE_PROTECTED, FR_INVALID_DRIVE, FR _NOT_ENABLED, FR_NO_FILESYSTEM, FR_TIMEOUT, FR_LOCKED, FR_NOT_ENOUGH_CORE,FR_TOO_MANY_OPEN_FILES DescriptionThe f_open function opens a file and creates a file object. The file object is used for subsequent read/write operations to the file to identify the file. Open file should be closed with f_close function after the session of the file access. If any change to the file is made and not closed prior to power down, media removal or re-mount, or the file can be collapsed.If duplicated file open is needed, read here carefully. However duplicated open of a file with any write mode flag is always prohibited.QuickInfoAlways available. Only FA_READ and FA_OPEN_EXISTING are supported when FF_FS_READONLY == 1.Example/* Read a text file and display it */FATFS FatFs; /* Work area (filesystem object) for logical drive */int main (void){FIL fil; /* File object */char line[100]; /* Line buffer */FRESULT fr; /* FatFs return code *//* Register work area to the default drive */f_mount(&FatFs, "", 0);/* Open a text file */fr = f_open(&fil, "message.txt", FA_READ);if (fr) return (int)fr;/* Read all lines and display it */while (f_gets(line, sizeof line, &fil)) {printf(line);}/* Close the file */f_close(&fil);return 0;}/* Copy a file "file.bin" on the drive 1 to drive 0 */int main (void){FATFS fs[2]; /* Work area (filesystem object) for logical drives */FIL fsrc, fdst; /* File objects */BYTE buffer[4096]; /* File copy buffer */FRESULT fr; /* FatFs function common result code */UINT br, bw; /* File read/write count *//* Register work area for each logical drive */f_mount(&fs[0], "0:", 0);f_mount(&fs[1], "1:", 0);/* Open source file on the drive 1 */fr = f_open(&fsrc, "1:file.bin", FA_READ);if (fr) return (int)fr;/* Create destination file on the drive 0 */fr = f_open(&fdst, "0:file.bin", FA_WRITE | FA_CREATE_ALWAYS);if (fr) return (int)fr;/* Copy source to destination */for (;;) {fr = f_read(&fsrc, buffer, sizeof buffer, &br); /* Read a chunk of source file */if (fr || br == 0) break; /* error or eof */fr = f_write(&fdst, buffer, br, &bw); /* Write it to the destination file */if (fr || bw < br) break; /* error or disk full */}/* Close open files */f_close(&fsrc);f_close(&fdst);/* Unregister work area prior to discard it */ f_mount(NULL, "0:", 0);f_mount(NULL, "1:", 0);return (int)fr;}。

Fatfs文件系统2015-04要点

Fatfs文件系统2015-04要点

2015-04-18FATFS文件管理系统一、FATFS简介FATFS 是一个完全免费开源的FAT 文件系统模块,专门为小型的嵌入式系统而设计。

它完全用标准 C 语言编写,所以具有良好的硬件平台独立性,可以移植到8051、PIC、AVR、SH、Z80、H8、ARM 等系列单片机上而只需做简单的修改。

它支持FATl2、FATl6 和FAT32,支持多个存储媒介;有独立的缓冲区,可以对多个文件进行读/写,并特别对8 位单片机和16 位单片机做了优化。

FATFS 的特点有:✧ 代码量少、效率高✧ 多种配置选项✧ 支持多卷(物理驱动器或分区,最多10 个卷)✧ 多个ANSI/OEM 代码页包括DBCS✧ 支持长文件名、ANSI/OEM 或Unicode✧ 支持RTOS✧ 支持多种扇区大小✧ 只读、最小化的API 和I/O 缓冲区等二、FATFS层次结构图最顶层是应用层,使用者无需理会FATFS 的内部结构和复杂的FAT 协议,只需要调用FATFS 模块提供给用户的一系列应用接口函数,如f_open,f_read,f_write 和f_close 等,就可以像在PC 上读/写文件那样简单。

中间层FATFS 模块,实现了FAT 文件读/写协议。

FATFS 模块提供的是ff.c 和ff.h。

除非有必要,使用者一般不用修改,使用时将头文件直接包含进去即可。

需要我们编写移植代码的是FATFS 模块提供的底层接口,它包括存储媒介读/写接口(disk I/O)和供给文件创建修改时间的实时时钟。

三、FATFS源码1.源码下载(1)在/fsw/ff/00index_e.html下载FatFs源码R0.10b版本;(2)打开压缩包,里面有doc和src两个文件夹,doc是对FatFs的一些介绍及更新说明,src为FatFs的源码;2.FatFs源码介绍(1)与硬件平台无关的文件✧ffconf.h FATFS 模块配置文件✧ff.h FATFS 和应用模块公用的包含文件✧ff.c FATFS 模块✧diskio.h FATFS 和disk I/O 模块公用的包含文件✧interger.h 数据类型定义✧option 可选的外部功能(比如支持中文等)(2) 与硬件平台相关的文件✧diskio.c FATFS 和disk I/O 模块接口层文件(3) 移植时,重要的选项配置✧_FS_TINY。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

2. 在对文件的f_read和f_write过程中(不考虑f_lseek的情况),只有需要读写的最后一个扇区(内容小于512字节) 才会被暂存到buffer中,而前面的扇区内容是直接通过磁盘驱动disk_read/disk_write在用户缓冲区和物理磁盘之间进 行交互的。
注意:FatFs 0.01与最新的版本还是不少差异的,如在0.01中,buffer只是个指针,需要用户自己定义文件缓冲区,并 将buffer指向该缓冲区。而最新版本中,FIL已经有自己的buf[_MAX_SS]。在0.01中没有f_mount()函数,所以需要手动 将全局指针FatFs指向自己定义的变量fs。具体的操作流程可参考官网上的示例代码。
……
扇区B
四、源码注释 本人在不破坏源码逻辑的前提下,对FatFs 0.01源代码进行了中文注释,个别函数重新修改了排版布局,以方便阅 读。结合以上示意图即伪代码,相信大家会很快理解FatFs 0.01的核心思想及架构。 源码如下:
ff
ff
FatFs学习笔记 Page 6
FatFs学习笔记 Page 3
文件实际大小 ……
用户源缓冲区 512的整数倍
不足 1个扇区的内容
FatFs文件系统
SD卡物理空间
系统缓冲区
文件对应的 目录项
win[]
2 move _window()
3
文件目录项对应的扇区
扇区0 扇区1
……
第n簇
文件缓冲区
不足 1个扇区的内容
1 disk_write()
三、关键函数总结:
1. f_open f_open() {
1. 初始化SD卡,初始化FATFS对象; 2. 查找文件的目录项; 3. 填充文件结构体FIL。 }
2. f_read f_read() {
1. 从物理磁盘直接读取所需扇区到用户缓冲区,这个过程中未使用buffer缓冲区; 2. 如果最后一扇区要读取的字节数少于512,则先将最后一扇区读到buffer中,然后再从buffer拷贝需要的字节 到用户缓冲区中。
fs_type files sects_clust n_fats n_rootdir dirtyflag = 0 pad1 sects_fat max_clust fatbase dirbase database winsect = B win[512]
扇区B
SD卡物理空间
扇区A (Modified)
FatFs 0.01学习笔记
2014年2月14日 9:20
——何小龙 博客:/hexiaolong2009
一、介绍: 本文以网上开源文件系统FatFs 0.01为研究对象,剖析FatFs文件系统的核心操作。FatFs目前最新版本已更新到0.10a版 本,而我之所以选择0.01版本,是因为这是最早的发布版本,与最新的版本相比,去掉了很多高级应用,且代码量 相对较小,宏开关也少了许多,易于阅读和理解,用来研究它的雏形再合适不过了,所以笔者选择 0.01版本进行剖 析。当大家了解了0.01的核心思想后,再回去看最新的版本,也就容易理解多了。
FatFs历史版本下载:/fsw/ff/00index_e.html 在官网的最下面,能找到所有版本的下载链接。
二、重点:
1. FatFs中有两个重要的缓冲区:win[]和buffer。win[]在FATFS结构体中,buffer在FIL结构体中。 win[]:系统缓冲区。当操作MBR,DBR,FAT表,根目录区时,使用该缓冲区; buffer:文件缓冲区。当对文件的内容进行操作时,如读、写、修改时,才使用该缓冲区。
扇区A (Modified)
SD卡物理空间
2 disk_write
扇区A ……
disk_read 3
扇区B
调用后:
FatFs学习笔记 Page 5
FATFS *FatFs
FATFS fs;
BYTE BYTE BYTE BYTE WORD BYTE BYTE DWORD DWORD DWORD DWORD DWORD DWORD BYTE
fs_type files sects_clust n_fats n_rootdir dirtyflag = 1 pad1 sects_fat max_clust fatbase dirbase database winsect = A win[512]
扇区A (Modified)
SD卡物理空间
扇区A …… 扇区B
2 读取最后一扇区 到buffer
buffer
扇区0 扇区1
……
第n簇
扇区0 扇区1
……
第n+1簇
扇区0 扇区1 ……
第n+2簇
……
3. f_write f_write() {
1. 从用户缓冲区直接写入到物理磁盘,这个过程中未使用buffer缓冲区; 2. 如果要写入的最后一扇区内容少于512字节,则先从物理磁盘读取最后一扇区的内容到buffer中,然后修改 buffer中的相应内容,并设置回写标记,这样下次调用f_close/f_write时,就会将buffer回写到物理磁盘中。 }
}
FatFs学习笔记 Page 1
文件实际大小 ……
FatFs文件系统
SD卡物理空间
用户缓冲区 大小由用户定义
系统缓冲区
move _window ()
文件目录项对应的扇区
512Bytes
win[] 1 由disk_read直接 读取连续扇区
文件缓冲区
3 再从buffer拷贝 到用户缓冲区
512Bytes
文件缓冲区
buffer
先读取最后一扇 区到buffer中2Βιβλιοθήκη 扇区0 扇区1……
第n簇
扇区0 扇区1
……
第n+1簇
扇区0 扇区1 ……
第n+2簇
……
4. f_close 关键是调用了f_sync函数。
5. f_sync f_sync() {
1. 将buffer回写到物理磁盘中; 2. 读取文件对应的目录项到win[]中,更新参数,并回写。 }
执行中:
FATFS *FatFs
FATFS fs;
1 判断是否修改过
BYTE BYTE BYTE BYTE WORD BYTE BYTE DWORD DWORD DWORD DWORD DWORD DWORD BYTE
fs_type files sects_clust n_fats n_rootdir dirtyflag = 1 pad1 sects_fat max_clust fatbase dirbase database winsect = A win[512]
FatFs学习笔记 Page 2
文件实际大小 ……
FatFs文件系统
SD卡物理空间
用户源缓冲区 512的整数倍
不足 1个扇区的内容
系统缓冲区
move _window ()
文件目录项对应的扇区
512Bytes
win[] 1 由disk_write直 接写入连续扇区
再从源缓冲区拷 3 贝到buffer中
buffer
扇区0 扇区1
……
第n+1簇
扇区0 扇区1 ……
第n+2簇
……
5. move_window move_window专用于操作win[]系统缓冲区。
move_window(B); 调用前:
FatFs学习笔记 Page 4
FATFS *FatFs
FATFS fs;
BYTE BYTE BYTE BYTE WORD BYTE BYTE DWORD DWORD DWORD DWORD DWORD DWORD BYTE
相关文档
最新文档