一、文件系统系统格式化
经常听说格式化硬盘、格式化 U 盘,可以把设备上的数据全部清空,事实是格式化操作并不是把设备上所有的空间都清零,而是在这个设备上重建了文件系统用于管理文件的那一整套数据结构,即只是标记介质上的数据块为空闲状态,而不会实际删除数据。这也解释了为什么格式化后的设备,还能通过一些反删除软件找回一些文件。
在存储设备上创建文件系统,其实就是执行这个格式化操作,即重建文件系统的数据结构。
不同文件系统采用不同的方法来管理磁盘空间,各有优劣;文件系统是具体到分区的,所以格式化针对的是分区,分区格式化是指采用指定的文件系统类型对分区空间进行登记、索引并建立相应的管理表格的过程。
二、文件系统系统格式化具体步骤
建立文件系统的超级块:一个文件系统有很多重要的信息,例如文件系统标识、版本、状态,储存介质大小,文件系统逻辑储存块大小,位图所在的储存块,还有根目录等。
建立用于管理存储设备空间的位图:把一个储存设备分成一个个逻辑储存块(4KB),当储存一个文件数据时,就按逻辑储存块进行分配。这里的位图,就是利用一块储存空间中所有位的状态,达到映射逻辑储存块状态(是否已分配)的目的。
建立根目录:为了方便用户查找和归纳越来越多的文件,才产生了目录。其实从本质上来说,目录也是一种数据,这种数据中包含了目录类型、状态、指向文件数据管理头的块号、名称等信息。
三、不同文件系统分类
FAT16:MS—DOS和win95采用的磁盘分区格式,采用16位的文件分配表,只支持2GB的磁盘分区,最大单文件2GB,且磁盘利用率低
FAT32:采用32位的文件分配表,支持最大分区128GB,最大文件4GB。 FAT32格式兼容性好,但不支持4GB以上的文件
NTFS:支持最大分区2TB,最大文件2TB,安全性和稳定性非常好,不易出现文件碎片。NTFS格式支持大容量文件和超大分区,但对闪盘芯片有伤害
四、FatFs文件系统
FatFs 支持 FAT12、 FAT16、 FAT32 等格式,所以我们利用写好的 SPI Flash 芯片驱动或者SD驱动或者USB驱动,把 FatFs 文件系统代码移植到工程之中,就可以利用文件系统的各种函数,对 SPI Flash 芯片以“文件”格式进行读写操作了。
FATFS 的特点有:
Windows 兼容的 FAT 文件系统(支持 FAT12/FAT16/FAT32)
与平台无关,移植简单
代码量少、效率高
多种配置选项
支持多卷(物理驱动器或分区,最多 10 个卷)
多个 ANSI/OEM 代码页包括 DBCS
支持长文件名、 ANSI/OEM 或 Unicode
支持 RTOS
支持多种扇区大小
只读、最小化的 API 和 I/O 缓冲区等
五、ffconf.h文件详解
1、在<ffconf.h>中的“#define FF_MAX_SS 512”设置不对,此处的数值表示所挂的所有设备中,设备扇区的最大值。如w25qxx的扇区是4096,如果此处还是设置成512,就会造成栈溢出而陷入HardFault_Handler的死循环中。
2、“#define FF_MIN_SS 512”表示所挂的所有设备中,设备扇区的最小值,一般设置为512即可,因为扇区最小值就是512。
3、挂载后返回不存在文件系统的错误,即“res == FR_NO_FILESYSTEM”。可能是设备格式存在问题,对硬件进行格式化后重新挂载。(1)将<ffconf.h> 中的“#define FF_USE_MKFS 0”配置为1。
(2)书写下述代码
FATFS fsobject; //一定是一个全局变量
BYTE work[FF_MAX_SS]; //一定是一个全局变量,否则可能导致无法读写FLASHint main(void)
{
FRESULT res ; //局部变量
res = f_mount(&fsobject, "1:", 1); //挂载文件系统 , "1:"就是挂载的设备号为1的设备if(res == FR_NO_FILESYSTEM) //FR_NO_FILESYSTEM值为13,表示没有有效的设备
{
res = f_mkfs("1:",0,work,sizeof(work));
res = f_mount(NULL, "1:", 1); //取消文件系统
res = f_mount(&fsobject, "1:", 1); //挂载文件系统
}
}
4、FF_VOLUMES:指定物理设备数量,这里设置为1,因为本工程只使用了SD卡。5、需要支持简体中文,需要把ffconf.h中的_CODE_PAGE的宏改成936。并把上面的ffunicode.c文件(包含了多语言支持的编码格式)加入到工程之中。
六、diskio文件详解
/*-----------------------------------------------------------------------*/
/* Low level disk I/O module SKELETON for FatFs (C)ChaN, 2019 */
/*-----------------------------------------------------------------------*/
/* If a working storage control module is available, it should be */
/* attached to the FatFs via a glue function rather than modifying it. */
/* This is an example of glue functions to attach various exsisting */
/* storage control modules to the FatFs module with a defined API. */
/*-----------------------------------------------------------------------*/
#include "ff.h" /* Obtains integer types */
#include "diskio.h" /* Declarations of disk functions */
#include "sdio_sdcard.h"
#include "w25q128.h"
//是将不同的设备定义为不同的编号,告诉底层要操作的介质是哪一个,以便后续函数进行根据编号的不同执行相应的函数,设备号从0开始
/* Definitions of physical drive number for each drive */
#define DEV_MMC 0 /* Example: Map MMC/SD card to physical drive 1 */
#define DEV_FLASH 1 //本次操作的w25qxx设备,1就是w25qxx的设备编号
#define DEV_USB 2 /* Example: Map USB MSD to physical drive 2 */
/*-----------------------------------------------------------------------*/
/* 返回值:
STA_NOINIT:标识该设备未初始化成功,未进入就绪状态。
STA_NODISK:FatFs不引用此标志。
STA_PROTECT:表示该设备已进行了写保护。如果设置了STA_NODISK,则无效。
0:表示该设备初始化成功。*/
/*-----------------------------------------------------------------------*/
DSTATUS di