FatFs介绍
FatFs 是面向小型嵌入式系统的一种通用的 FAT 文件系统。 它完全是由 ANSI C 语言编写并且完
全独立于底层的
I/O
介质。因此它可以很容易地不加修改地移植到其他的处理器当中,如
8051
、
PIC
、
AVR
、
SH
、
Z80
、
H8
、
ARM
等。
如果我们需要手动移植FatFs的话,可以从fatfs官网下载源码:
http://elm-chan.org/fsw/ff/00index_e.html
在下载的src文件夹中,主要用到的文件有:
option
文件夹下是一些可选的外部
c
文件,包含了多语言支持需要用到的文件和转换函数。
diskio.c
文件是
FatFs
移植最关键的文件,它为文件系统提供了最底层的访问
SPI Flash
芯片的方
法,
FatFs
有且仅有它需要用到与
SPI Flash
芯片相关的函数。
ff.c:
FatFs
核心文件,文件管理的实现方法。该文件独立于底层介质操作文件的函数,利用
这些函数实现文件的读写。
ffffconf.h:
这个头文件包含了对
FatFs
功能配置的宏定义,通过修改这些宏定义就可以裁剪
FatFs
的功能。如
下面简单介绍下,
FatFs源文件的分布:

FatFs
组件是
FatFs
的主体,文件都在源码
src
文件夹中,其中
ff.c
、
ff.h
、
integer.h
以及
diskio.h
四 个文件我们不需要改动,只需要修改 ffconf.h
和
diskio.c
两个文件。
用户应用程序需要由用户编写,想实现什么功能就编写什么的程序,一般我们只用到
f_mount()
、
f_open()
、
f_write()
、
f_read()
就可以实现文件的读写操作。
Flash文件系统FatFs使用实验
使用STM32Cube添加FatFs文件系统:
接下来就是fatfs的参数配置,根据个人的需求进行修改,也可以使用默认参数:
使用STM32Cube自动生成FatFs文件系统代码后,接下来就是修改底层驱动的相关函数了,我们这以外部flash为例:
在user_diskio.c文件中分别写入USER_initialize()、USER_status()、USER_read()、USER_write(),也就是增加spi_flash的底层驱动。
DSTATUS USER_initialize (
BYTE pdrv /* Physical drive nmuber to identify the drive */
)
{
/* USER CODE BEGIN INIT */
Stat = STA_NOINIT;
/* 初始化SPI Flash */
if(sFLASH_ID == SPI_FLASH_ReadID())
{
SPI_FLASH_Init();
Stat =RES_OK;
}
else
{
Stat =RES_ERROR;
}
return Stat;
/* USER CODE END INIT */
}
DSTATUS USER_status (
BYTE pdrv /* Physical drive number to identify the drive */
)
{
/* USER CODE BEGIN STATUS */
Stat = STA_NOINIT;
if(sFLASH_ID == SPI_FLASH_ReadID())
{
SPI_FLASH_Init();
Stat =RES_OK;
}
else
{
Stat =RES_ERROR;
}
return Stat;
/* USER CODE END STATUS */
}
DRESULT USER_read (
BYTE pdrv, /* Physical drive nmuber to identify the drive */
BYTE *buff, /* Data buffer to store read data */
DWORD sector, /* Sector address in LBA */
UINT count /* Number of sectors to read */
)
{
/* USER CODE BEGIN READ */
SPI_FLASH_BufferRead(buff,sector,count);
return RES_OK;
/* USER CODE END READ */
}
DRESULT USER_write (
BYTE pdrv, /* Physical drive nmuber to identify the drive */
const BYTE *buff, /* Data to be written */
DWORD sector, /* Sector address in LBA */
UINT count /* Number of sectors to write */
)
{
/* USER CODE BEGIN WRITE */
/* USER CODE HERE */
SPI_FLASH_BufferWrite((uint8_t *)buff,sector,count);
return RES_OK;
/* USER CODE END WRITE */
}
增加SPI_Flash底层驱动后,就可以正常调用FatFs文件系统应用层函数接口,完成文件操作。
#include "main.h"
#include "bsp_usart.h"
#include "ff.h"
#include "string.h"
#include "bsp_spi_flash.h"
FATFS fs; /* FatFs文件系统对象 */
FIL fnew; /* 文件对象 */
FRESULT res_flash; /* 文件操作结果 */
UINT fnum; /* 文件成功读写数量 */
char readbuffer[512]; /* 读缓冲区 */
char Writebuffer[] ={Test App!!!/r/n}; /* 写缓冲区 */
int main(void)
{
HAL_Init();
/* 配置系统时钟为72 MHz */
SystemClock_Config();
/*初始化USART 配置模式为 115200 8-N-1,中断接收*/
DEBUG_USART_Config();
printf("******** 这是一个SPI FLASH 文件系统实验 *******\r\n");
//在外部SPI Flash挂载文件系统,文件系统挂载时会对SPI设备初始化
res_flash = f_mount(&fs,"1:",1);
if(res_flash == FR_OK)
{
printf("Mount OK\r\n");
}
else
{
printf("Mount False\r\n");
res_flash = f_mount(&fs,"1:",1);
if(res_flash == FR_OK)
printf("Mount OK\r\n");
else
printf("Mount False\r\n");
}
//打开文件操作
res_flash = f_open(&fnew, "1:FatFs读写测试文件.txt",FA_OPEN_ALWAYS|FA_WRITE|FA_READ );
if ( res_flash == FR_OK )
{
printf("File open OK\r\n");
}
else
{
printf("Mount False\r\n");
res_flash = f_open(&fnew, "1:FatFs读写测试件.txt",
FA_OPEN_ALWAYS|FA_WRITE|FA_READ);
if(res_flash == FR_OK)
printf("File open OK\r\n");
else
printf("Mount False\r\n");
}
//向文件系统写操作
res_flash=f_write(&fnew,Writebuffer,sizeof(WriteBuffer),&fnum);
if ( res_flash == FR_OK )
printf("Write open OK\r\n");
else
printf("Mount False\r\n");
//读文件系统数据操作
res_flash = f_lseek(&fnew,0);
res_flash=f_read(&fnew,Readbuffer,sizeof(ReadBuffer),&fnum);
if ( res_flash == FR_OK )
{
printf("Read OK\r\n");
printf("ReadBuffer =%s\r\n", ReadBuffer);
}
else
printf("Read False\r\n");
//关闭文件系统
f_close(&fnew);
}
最后就是打开串口助手,查看打印结果了。