FatFs文件系统笔记--R0.13c

目录

1. FatFs文件系统简介

1.1 FatFs的目录结构

1.2  FatFs帮助文档

1.3  FatFs源码

2.  FatFs 文件系统的移植

2.1 FatFs 分层体系

2.1 FatFs 移植步骤

2.1.1 添加 FatFs 源码到工程

2.2 FatFs主要功能配置点

3. FatFs模块应用说明

4. FatFs 文件系统的缺点


1. FatFs文件系统简介

简而言之,文件系统即为,在存储设备上组织文件的方法。常见的windows下的文件系统格式包括FAT32、NTFS、exFAT。在使用文件系统前,要先对存储介质进行格式化。格式化先擦除原来内容,在存储介质上新建一个文件分配表和目录。这样,文件系统就可以记录数据存放的物理地址,剩余空间。

FatFs是面向小型嵌入式系统的一种通用的FAT文件系统。它完全是由AISI C语言编写并且完全独立于底层的I/O介质。因此它可以很容易地不加修改地移植到其他的处理器当中,如8051、PIC、AVR、SH、Z80、H8、ARM等。FatFs支持FAT12、FAT16、FAT32等格式。

官方文档及源码可以从FatFs官网获取:

http://elm-chan.org/fsw/ff/00index_e.html

FatFs文件系统笔记--R0.13c

以下皆以最新的R0.13c版本移植。

1.1 FatFs的目录结构

FatFs的官网获取源码,最新版本为R0.13c,解压之后可看到里面有 documents和 source 这两个文件夹。

FatFs文件系统笔记--R0.13c

1.2  FatFs帮助文档

打开 documents文件夹

FatFs文件系统笔记--R0.13c

 其中,doc 这两个文件夹里面是编译好的html文档,讲的是FATFS里面各个函数的使用方法; res 需要用到的图片。

00index_e.html 直接打开,可以看到系统简介,及相关API的介绍,具体链接doc的相关函数介绍文档。

1.3  FatFs源码

打开 source 文件夹

FatFs文件系统笔记--R0.13c

  •   00readme.txt   This file.
  •   00history.txt  版本历史
  •   ff.c           FatFs核心文件,文件管理的实现方法。该文件独立于底层介质操作文件的函数,利用这些函数实现文件的读写。
  •   ffconf.h       FatFs功能配置的宏定义,可以根据需要裁剪其功能
  •   ff.h           FatFs和应用程序模块的通用包含文件。
  •   diskio.h       FatFs和磁盘I / O模块的公共包含文件。
  •   diskio.c       包含底层存储介质的操作函数,这些函数需要用户自己实现,主要添加底层驱动函数。
  •   ffunicode.c    可选的Unicode实用程序功能
  •   ffsystem.c     可选的O / S相关功能的。 

文件阅读顺序   diskio.c --> ff.c,阅读文件系统源码ff.c文件需要一定的功底,建议读者先阅读FAT32的文件格式,再去分析ff.c文件。

2.  FatFs 文件系统的移植

2.1 FatFs 分层体系

FatFs文件系统笔记--R0.13c

用户应用程序需要由用户编写,一般我们只用到f_mount()、f_open()、f_write()、f_read()就可以实现文件的读写操作.

FatFs组件是FatFs的主体,文件都在源码src文件夹中,其中ff.c、ff.h、ffunicode.c.以及diskio.h四个文件我们不需要改动,只需要修改ffconf.h和diskio.c两个文件,根据是否有操作系统修改ffsystem.c。

2.1 FatFs 移植步骤

在此以秉火429 SPI Flash芯片作为物理存储设备,驱动具体驱动不做赘述,具体见链接

https://blog.csdn.net/XieWinter/article/details/95077050

2.1.1 添加 FatFs 源码到工程

源码直接解压拷贝,添加到工程,并包含相关的H文件。因为未使用到操作系统,所以屏蔽掉了ffsystem.c,如下图:

FatFs文件系统笔记--R0.13c

如果直接编译会发现会出错,因此需要修改diskio.c,系统默认使用日语,需要支持中文的话需要修改ffconf.h,当然,相关的裁剪根据需要,配置ffconf.h相关的宏。

配置ffconf.h,宏定义对应的功能,代码中都有说明,具体的配置范围可以见官方配置说明

http://elm-chan.org/fsw/ff/doc/config.html

具体配置,可以通过对比软件来查看与官方源码的差异点,这样有助于理解。

/*---------------------------------------------------------------------------/
/  FatFs Functional Configurations
/---------------------------------------------------------------------------*/

#define FFCONF_DEF	86604	/* Revision ID */

/*---------------------------------------------------------------------------/
/ Function Configurations
/---------------------------------------------------------------------------*/

#define FF_FS_READONLY	0
/* 此选项可切换只读配置,默认为可读写(0). (0:Read/Write or 1:Read-only)
/  Read-only configuration removes writing API functions, f_write(), f_sync(),
/  f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree()
/  and optional writing functions as well. */


#define FF_FS_MINIMIZE	0
/* 此选项定义最小化级别以删除一些基本API函数。
/
/   0: Basic functions are fully enabled.
/   1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_truncate() and f_rename()
/      are removed.
/   2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1.
/   3: f_lseek() function is removed in addition to 2. */


#define FF_USE_STRFUNC	0
/* 此选项切换字符串函数, f_gets(), f_putc(), f_puts() and f_printf().
/ 如果工作在windows下,为保证文件兼容性(如换行符’\n’和回车符’\r’)建议将此项设置为2
/
/  0: Disable string functions.
/  1: Enable without LF-CRLF conversion.
/  2: Enable with LF-CRLF conversion. */


#define FF_USE_FIND		0
/* 此选项可切换筛选的目录读取功能, f_findfirst() and
/  f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */
/* 用于搜索文件夹相关的文件 */

#define FF_USE_MKFS		1
/* 此选项可切换f_mkfs()函数。 (0:Disable or 1:Enable) */

#define FF_USE_FASTSEEK	0
/* 此选项可切换快速搜索功能. (0:Disable or 1:Enable) */
/* 开启后,会使用FIL结构体中的cltbl元素来加快搜索 */

#define FF_USE_EXPAND	0
/* 此选项可切换f_expand函数 (0:Disable or 1:Enable) */
/* 文件准备或分配连续的数据区域。 */

#define FF_USE_CHMOD	0
/* 此选项可切换属性操作功能, f_chmod() and f_utime().
/  (0:Disable or 1:Enable) Also FF_FS_READONLY needs to be 0 to enable this option. */


#define FF_USE_LABEL	0
/* 此选项可切换卷标功能, f_getlabel() and f_setlabel().
/  (0:Disable or 1:Enable) */


#define FF_USE_FORWARD	0
/* 此选项可切换 f_forward() 功能. (0:Disable or 1:Enable) */
/* 数据立即转存到数据流中,以节省RAM空间 */

/*---------------------------------------------------------------------------/
/ Locale and Namespace Configurations
/ 区域设置和命名空间配置
/---------------------------------------------------------------------------*/

#define FF_CODE_PAGE	936
/* This option specifies the OEM(Original Equipment Manufacture) code page to be used on the target system.
/  此选项指定目标系统上使用的OEM代码页。代码页是字符集编码的别称,亦称内码表。 
/  Incorrect code page setting can cause a file open failure.
/  代码页设置不正确可能导致文件打开失败。
/
/   437 - U.S.
/   720 - Arabic
/   737 - Greek
/   771 - KBL
/   775 - Baltic
/   850 - Latin 1
/   852 - Latin 2
/   855 - Cyrillic
/   857 - Turkish
/   860 - Portuguese
/   861 - Icelandic
/   862 - Hebrew
/   863 - Canadian French
/   864 - Arabic
/   865 - Nordic
/   866 - Russian
/   869 - Greek 2
/   932 - Japanese (DBCS)
/   936 - Simplified Chinese (DBCS)
/   949 - Korean (DBCS)
/   950 - Traditional Chinese (DBCS)
/     0 - Include all code pages above and configured by f_setcp()
*/
/* OEM是什么意思呢?在OS编码中,unicode是一种双字节字符编码,无论中文还是英文,或者其他语言统一到2个字节,
/  它与现有的任何编码(ASCII,GB等)都不兼容。WindowsNT(2000)的内核即使用该编码,所有数据进入内核前转换成UNICODE,
/  退出内核后在转换成版本相关的编码(通常称为OEM,在简体中文版下即为GB);*/

#define FF_USE_LFN		2
#define FF_MAX_LFN		255				// 可存储长文件的最大长度
/* The FF_USE_LFN switches the support for LFN (long file name).
/  主要用于长文件名的支持及缓冲区的动态分配
/
/   0: Disable LFN. FF_MAX_LFN has no effect.( 不支持长文件名)
/   1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe.(支持长文件名存储的静态分配,一般是存储在BSS 段)
/   2: Enable LFN with dynamic working buffer on the STACK. (支持长文件名存储的动态分配,存储在栈上)
/   3: Enable LFN with dynamic working buffer on the HEAP. (支持长文件名存储的动态分配,存储在堆上)
/
/  To enable the LFN, ffunicode.c needs to be added to the project. The LFN function
/  requiers certain internal working buffer occupies (FF_MAX_LFN + 1) * 2 bytes and
/  additional (FF_MAX_LFN + 44) / 15 * 32 bytes when exFAT is enabled.
/  The FF_MAX_LFN defines size of the working buffer in UTF-16 code unit and it can
/  be in range of 12 to 255. It is recommended to be set 255 to fully support LFN
/  specification.
/  When use stack for the working buffer, take care on stack overflow. When use heap
/  memory for the working buffer, memory management functions, ff_memalloc() and
/  ff_memfree() in ffsystem.c, need to be added to the project. */


#define FF_LFN_UNICODE	0
/* This option switches the character encoding on the API when LFN is enabled.
/  启用LFN时,此选项可在API上切换字符编码。
/
/   0: ANSI/OEM in current CP (TCHAR = char)
/   1: Unicode in UTF-16 (TCHAR = WCHAR)
/   2: Unicode in UTF-8 (TCHAR = char)
/   3: Unicode in UTF-32 (TCHAR = DWORD)
/
/  Also behavior of string I/O functions will be affected by this option.
/  When LFN is not enabled, this option has no effect. */


#define FF_LFN_BUF		255
#define FF_SFN_BUF		12
/* 这组选项定义FILINFO结构中文件名成员的大小,用于读出目录项  */
/* This set of options defines size of file name members in the FILINFO structure
/  which is used to read out directory items. These values should be suffcient for
/  the file names to read. The maximum possible length of the read file name depends
/  on character encoding. When LFN is not enabled, these options have no effect. */


#define FF_STRF_ENCODE	3
/* When FF_LFN_UNICODE >= 1 with LFN enabled, string I/O functions, f_gets(),
/  f_putc(), f_puts and f_printf() convert the character encoding in it.
/  This option selects assumption of character encoding ON THE FILE to be
/  read/written via those functions.
/
/   0: ANSI/OEM in current CP
/   1: Unicode in UTF-16LE
/   2: Unicode in UTF-16BE
/   3: Unicode in UTF-8
*/


#define FF_FS_RPATH		0
/* This option configures support for relative path.
/  配置相对路径函数
/
/   0: Disable relative path and remove related functions.
/   1: Enable relative path. f_chdir() and f_chdrive() are available.
/   2: f_getcwd() function is available in addition to 1.
*/


/*---------------------------------------------------------------------------/
/ Drive/Volume Configurations
/ 驱动器/卷配置
/---------------------------------------------------------------------------*/

#define FF_VOLUMES		2
/* Number of volumes (logical drives) to be used. (1-10) */
/* 支持的逻辑设备数目 */

#define FF_STR_VOLUME_ID	0
/* 使能或禁用字符串卷标识。要使能字符串卷标识,需要预先定义标识字符串,使用宏_VOLUME_STRS定义。 
/  0	Only DOS/Windows style drive prefix in numeric ID can be used.	0:/filename
/  1	Also DOS/Windows style drive prefix in string ID can be used.	flash:/filename
/  2	Also Unix style drive prefix in string ID can be used.			/flash/filename
*/

#define FF_VOLUME_STRS		"RAM","NAND","CF","SD","SD2","USB","USB2","USB3"
/* FF_STR_VOLUME_ID switches support for volume ID in arbitrary strings.
/  When FF_STR_VOLUME_ID is set to 1 or 2, arbitrary strings can be used as drive
/  number in the path name. FF_VOLUME_STRS defines the volume ID strings for each
/  logical drives. Number of items must not be less than FF_VOLUMES. Valid
/  characters for the volume ID strings are A-Z, a-z and 0-9, however, they are
/  compared in case-insensitive. If FF_STR_VOLUME_ID >= 1 and FF_VOLUME_STRS is
/  not defined, a user defined volume string table needs to be defined as:
/
/  const char* VolumeStr[FF_VOLUMES] = {"ram","flash","sd","usb",...
*/


#define FF_MULTI_PARTITION	0
/* This option switches support for multiple volumes on the physical drive.
/  By default (0), each logical drive number is bound to the same physical drive
/  number and only an FAT volume found on the physical drive will be mounted.
/  When this function is enabled (1), each logical drive number can be bound to
/  arbitrary physical drive and partition listed in the VolToPart[]. Also f_fdisk()
/  funciton will be available. */


#define FF_MIN_SS		512
#define FF_MAX_SS		4096
/* 配置扇区大小 
/ 当_MAX_SS > _MIN_SS,FatFs被配置为扇区大小可变的并且必须在函数disk_ioctl中实现GET_SECTOR_SIZE命令*/

/* This set of options configures the range of sector size to be supported. (512,
/  1024, 2048 or 4096) Always set both 512 for most systems, generic memory card and
/  harddisk. But a larger value may be required for on-board flash memory and some
/  type of optical media. When FF_MAX_SS is larger than FF_MIN_SS, FatFs is configured
/  for variable sector size mode and disk_ioctl() function needs to implement
/  GET_SECTOR_SIZE command. */



#define FF_USE_TRIM		0
/* This option switches support for ATA-TRIM. (0:Disable or 1:Enable)
/  To enable Trim function, also CTRL_TRIM command should be implemented to the
/  disk_ioctl() function. */


#define FF_FS_NOFSINFO	0
/* If you need to know correct free space on the FAT32 volume, set bit 0 of this
/  option, and f_getfree() function at first time after volume mount will force
/  a full FAT scan. Bit 1 controls the use of last allocated cluster number.
/
/  bit0=0: Use free cluster count in the FSINFO if available.
/  bit0=1: Do not trust free cluster count in the FSINFO.
/  bit1=0: Use last allocated cluster number in the FSINFO if available.
/  bit1=1: Do not trust last allocated cluster number in the FSINFO.
*/



/*---------------------------------------------------------------------------/
/ System Configurations
/ 系统配置
/---------------------------------------------------------------------------*/

#define FF_FS_TINY		0
/* This option switches tiny buffer configuration. (0:Normal or 1:Tiny)
/  At the tiny configuration, size of file object (FIL) is shrinked FF_MAX_SS bytes.
/  Instead of private sector buffer eliminated from the file object, common sector
/  buffer in the filesystem object (FATFS) is used for the file data transfer. */


#define FF_FS_EXFAT		0
/* EXFAT 文件系统支持 */
/* This option switches support for exFAT filesystem. (0:Disable or 1:Enable)
/  To enable exFAT, also LFN needs to be enabled. (FF_USE_LFN >= 1)
/  Note that enabling exFAT discards ANSI C (C89) compatibility. */


#define FF_FS_NORTC		0
#define FF_NORTC_MON	1
#define FF_NORTC_MDAY	1
#define FF_NORTC_YEAR	2020
/* 时间戳配置,使用RTC需要实现 get_fattime()函数 */
/* The option FF_FS_NORTC switches timestamp functiton. If the system does not have
/  any RTC function or valid timestamp is not needed, set FF_FS_NORTC = 1 to disable
/  the timestamp function. Every object modified by FatFs will have a fixed timestamp
/  defined by FF_NORTC_MON, FF_NORTC_MDAY and FF_NORTC_YEAR in local time.
/  To enable timestamp function (FF_FS_NORTC = 0), get_fattime() function need to be
/  added to the project to read current time form real-time clock. FF_NORTC_MON,
/  FF_NORTC_MDAY and FF_NORTC_YEAR have no effect.
/  These options have no effect at read-only configuration (FF_FS_READONLY = 1). */


#define FF_FS_LOCK		0
/* 选项FF_FS_LOCK切换文件锁定功能,以控制打开对象的重复文件打开和非法操作 */
/* The option FF_FS_LOCK switches file lock function to control duplicated file open
/  and illegal operation to open objects. This option must be 0 when FF_FS_READONLY
/  is 1.
/
/  0:  Disable file lock function. To avoid volume corruption, application program
/      should avoid illegal open, remove and rename to the open objects.
/  >0: Enable file lock function. The value defines how many files/sub-directories
/      can be opened simultaneously under file lock control. Note that the file
/      lock control is independent of re-entrancy. */


/* #include <somertos.h>	// O/S definitions */
#define FF_FS_REENTRANT	0
#define FF_FS_TIMEOUT	1000
#define FF_SYNC_t		HANDLE
/* 选项FF_FS_REENTRANT切换FatFs模块本身的重入(线程安全)。 
/  请注意,无论此选项如何,对不同卷的文件访问始终是可重入的,并且卷控制函数f_mount(),
/  f_mkfs()和f_fdisk()函数始终不可重入。 只有对同一卷的文件/目录访问权限才能受此功能的控制。*/

/* The option FF_FS_REENTRANT switches the re-entrancy (thread safe) of the FatFs
/  module itself. Note that regardless of this option, file access to different
/  volume is always re-entrant and volume control functions, f_mount(), f_mkfs()
/  and f_fdisk() function, are always not re-entrant. Only file/directory access
/  to the same volume is under control of this function.
/
/   0: Disable re-entrancy. FF_FS_TIMEOUT and FF_SYNC_t have no effect.
/   1: Enable re-entrancy. Also user provided synchronization handlers,
/      ff_req_grant(), ff_rel_grant(), ff_del_syncobj() and ff_cre_syncobj()
/      function, must be added to the project. Samples are available in
/      ffsystem.c.
/
/  The FF_FS_TIMEOUT defines timeout period in unit of time tick.
/  The FF_SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*,
/  SemaphoreHandle_t and etc. A header file for O/S definitions needs to be
/  included somewhere in the scope of ff.h. */



/*--- End of configuration options ---*/
/*-----------------------------------------------------------------------*/
/* Low level disk I/O module skeleton for FatFs     (C)ChaN, 2016        */
/*-----------------------------------------------------------------------*/
/* 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 "flash/bsp_spi_flash.h"

/* Definitions of physical drive number for each drive */
#define DEV_MMC					0				/* Example: Map MMC/SD to physical drive 0 */
#define DEV_EX_FLASH			1				/* Example: Map SPI FLASH card to physical drive 1 */
#define DEV_USB					2				/* Example: Map USB MSD to physical drive 2 */


/*-----------------------------------------------------------------------*/
/* Get Drive Status   (获取磁盘状态)                                                   */
/*-----------------------------------------------------------------------*/

DSTATUS disk_status (
	BYTE pdrv		/* Physical drive nmuber to identify the drive */
)
{
	DSTATUS stat;
//	int result;

	switch (pdrv) {
		
	case DEV_EX_FLASH :
//		result = RAM_disk_status();
		if (sFLASH_ID == SPI_FLASH_ReadID()) {
			
			stat = RES_OK;
		} else {
			
			stat = STA_NOINIT;
		}
		
		return stat;

	case DEV_MMC :
//		result = MMC_disk_status();

		// translate the reslut code here
		stat = RES_OK;
		return stat;

	case DEV_USB :
//		result = USB_disk_status();

		// translate the reslut code here
		stat = RES_OK;
		return stat;
	}
	return STA_NOINIT;
}



/*-----------------------------------------------------------------------*/
/* Inidialize a Drive                                                    */
/*-----------------------------------------------------------------------*/

DSTATUS disk_initialize (
	BYTE pdrv				/* Physical drive nmuber to identify the drive */
)
{
	DSTATUS stat=STA_NOINIT;
//	int result;

	switch (pdrv) {
		
	case DEV_EX_FLASH : {
		uint16_t i;
		/* 初始化 */
		SPI_FLASH_Init ();
		
		/* 延时一小会 */
		i=500;
		while(--i);
		/* 唤醒 FLASH */
		SPI_Flash_WAKEUP ();
		/* 检查状态 */
		stat = disk_status(pdrv);
		
		return stat;
	}
		
	case DEV_MMC :
//		result = MMC_disk_initialize();

		// translate the reslut code here

		return stat;

	case DEV_USB :
//		result = USB_disk_initialize();

		// translate the reslut code here

		return stat;
	}
	return STA_NOINIT;
}



/*-----------------------------------------------------------------------*/
/* Read Sector(s)                                                        */
/*-----------------------------------------------------------------------*/

DRESULT disk_read (
	BYTE pdrv,		/* Physical drive nmuber to identify the drive */
	BYTE *buff,		/* Data buffer to store read data */
	DWORD sector,	/* Start sector in LBA */
	UINT count		/* Number of sectors to read */
)
{
	DRESULT res=RES_PARERR;
//	int result;

	switch (pdrv) {
		
	case DEV_EX_FLASH : {
		/* 初始位置偏移6M */
      sector+=1536;      
      SPI_FLASH_BufferRead(buff, (sector*SPI_FLASH_SECTOR_SIZE), (count*SPI_FLASH_SECTOR_SIZE));
      res = RES_OK;		
	}
		return res;

	case DEV_MMC :
		// translate the arguments here

//		result = MMC_disk_read(buff, sector, count);

		// translate the reslut code here

		return res;

	case DEV_USB :
		// translate the arguments here

//		result = USB_disk_read(buff, sector, count);

		// translate the reslut code here

		return res;
	}

	return RES_PARERR;
}



/*-----------------------------------------------------------------------*/
/* Write Sector(s)                                                       */
/*-----------------------------------------------------------------------*/

#if FF_FS_READONLY == 0

DRESULT disk_write (
	BYTE pdrv,			/* Physical drive nmuber to identify the drive */
	const BYTE *buff,	/* Data to be written */
	DWORD sector,		/* Start sector in LBA */
	UINT count			/* Number of sectors to write */
)
{
	DRESULT res=RES_PARERR;
//	int result;

	switch (pdrv) {
		
	case DEV_EX_FLASH : {
		uint32_t write_addr;
		sector +=1536;
		write_addr = (sector*SPI_FLASH_SECTOR_SIZE);    
		SPI_FLASH_SectorErase(write_addr);
		SPI_FLASH_BufferWrite((u8 *)buff,write_addr,(count*SPI_FLASH_SECTOR_SIZE));
		res = RES_OK;		
	}

		return res;

	case DEV_MMC :
		// translate the arguments here

//		result = MMC_disk_write(buff, sector, count);

		// translate the reslut code here

		return res;

	case DEV_USB :
		// translate the arguments here

//		result = USB_disk_write(buff, sector, count);

		// translate the reslut code here

		return res;
	}

	return RES_PARERR;
}

#endif


/*-----------------------------------------------------------------------*/
/* Miscellaneous Functions                                               */
/*-----------------------------------------------------------------------*/

DRESULT disk_ioctl (
	BYTE pdrv,		/* Physical drive nmuber (0..) */
	BYTE cmd,		/* Control code */
	void *buff		/* Buffer to send/receive control data */
)
{
	DRESULT res;
	int result;

	switch (pdrv) {
		
	case DEV_EX_FLASH : {
			switch (cmd) {
        /* 扇区数量:2560*4096/1024/1024=10(MB) */
        case GET_SECTOR_COUNT:
          *(DWORD * )buff = 2560;		
        break;
        /* 扇区大小  */
        case GET_SECTOR_SIZE :
          *(WORD * )buff = SPI_FLASH_SECTOR_SIZE;
        break;
        /* 同时擦除扇区个数 */
        case GET_BLOCK_SIZE :
          *(DWORD * )buff = 1;
        break;        
      }
	  
      res = RES_OK;		
	}
		return res;

	case DEV_MMC :

		// Process of the command for the MMC/SD card

		return res;

	case DEV_USB :

		// Process of the command the USB drive

		return res;
	}

	return RES_PARERR;
}

__weak DWORD get_fattime(void) {
	/* 返回当前时间戳 */
	return	  ((DWORD)(2020 - 1980) << 25)	/* Year 2020 */
			| ((DWORD)1 << 21)				/* Month 1 */
			| ((DWORD)1 << 16)				/* Mday 1 */
			| ((DWORD)0 << 11)				/* Hour 0 */
			| ((DWORD)0 << 5)				  /* Min 0 */
			| ((DWORD)0 >> 1);				/* Sec 0 */
}

2.2 FatFs主要功能配置点

ffconf.h文件是FatFs功能配置文件,根据需要来裁剪,已到达高效实用设备资源的目的。

  • #define FF_USE_MKFS        1

格式化功能选择,为使用FatFs格式化功能,需要配置为1

  • #define FF_CODE_PAGE    936

语言功能选择,并要求把相关语言文件添加到工程宏。为支持简体中文文件名需要使用“936”,编码文件ffunicode.c需要添加

  • #define FF_USE_LFN        2

长文件名支持,默认不支持长文件名,这里配置为2,支持长文件名,并指定使用栈空间为缓冲区。

  • #define FF_VOLUMES        2

指定物理设备数量,这里设置为2,包括预留SD卡和SPI Flash芯片。

  • #define FF_STR_VOLUME_ID    0

使能或禁用字符串卷标识,可以实现DOS/Windows style或Unix style文件或路径格式

  • #define FF_MIN_SS        512
  • #define FF_MAX_SS        4096

指定扇区大小的最小值和最大值。SD卡扇区大小一般都为512字节,SPI Flash芯片扇区大小一般设置为4096字节,所以需要把_MAX_SS改为4096。

  • #define FF_FS_NORTC        0

时间戳配置,使用时间戳的话,需要实现get_fattime()并关联硬件RTC

  • #define FF_FS_REENTRANT    0

可重入,用于有操作系统的时候;使用该功能,需要实现ffsystem.c中的相关函数;前后台模式,则不需要关系。

3. FatFs模块应用说明

官方应用说明,理解该文档,基本大多数的疑问都可以得到解答

http://elm-chan.org/fsw/ff/doc/appnote.html

4. FatFs 文件系统的缺点

  • 无掉电保护,异常掉电会损坏文件系统
  • 不支持负载均衡

在许多物联网使用案例中,需要具有电源丢失弹性,数据完整性和更长的存储器使用寿命,littlefs以其更加优秀的性能提供更好的体验,后续将详解。源码链接https://github.com/ARMmbed/littlefs

 

 

上一篇:PHP之Trait详解


下一篇:Springboot 打jar包分离lib,配置文件正确方式(二)