Fatfs(文件系统的移植)
一、文件系统介绍
FatFs是用于小型嵌入式系统的通用 FAT / exFAT文件系统模块。FatFs模块是按照 ANSI C(C89)编写的,并且与磁盘 I / O层完全分开。因此,它独立于平台。它可以并入资源有限的小型微控制器中,例如8051,PIC,AVR,ARM,Z80,RX等;FatFs是作者 ChaN开发的个人项目。官网
二、移植条件、说明
1、FatFs模块在可移植性方面设定了以下条件:
- ANSI C
FatFs模块是用ANSI C(C89)编写的中间件。只要编译器符合C89或更高版本,就没有平台依赖性。仅exFAT功能需要C99。 - 整数类型的大小
char类型的大小必须为 8位。
int类型的大小必须为 16位或 32位。
当 C标准为 C89时,short和 long的大小必须分别为 16位和 32位。
在 C99或更高版本中时,使用 stdin .h获取整数大小。
2、数据类型说明
- BYTE :8-bit unsigned integer → uint8_t
- WORD : 16-bit unsigned integer →uint16_t
- DWORD : 32-bit unsigned integer →uint32_t
- QWORD : 64-bit unsigned integer → uint64_t
- UINT : Alias of unsigned int used to specify any number → uint32_t
- WCHAR : Alias of WORD used to specify a UTF-16 code unit.→uint16_t
- TCHAR :Alias of char, WCHAR or DWORD used to specify a character encoding unit. →uint16_t
- FSIZE_t : Alias of DWORD or QWORD used to address file offset and to specify file size. →uint32_t
- LBA_t : Alias of DWORD or QWORD used to address sectors in LBA and to specify number of sectors. →uint32_t
3、系统框架
下面显示的依赖关系图是带有FatFs模块的嵌入式系统的典型配置,但不是特定的配置。
(a)如果提供了用于 FatFs的工作磁盘模块,则不需要其他任何东西。(b)为使现有磁盘驱动具有不同的接口,需要一些glue功能来转换fatf和驱动之间的接口。
三、文件移植操作
1.首先前往官网下载(下载地址)
这里使用的 R0.14目前最新的版本;
我们需要的是source文件夹,直接并入我们的工程就行了。
文件名 | 功能 | 说明 |
---|---|---|
diskio.c | Fatfs和 disk I/O模块接口层文件 | 与平台相关的代码,需要用户根据存储介质来编写函数 |
diskio.h | Fatfs和 disk I/O模块公用的包含文件 | 不需要修改 |
ff.c | Fatfs模块源码 | 不需要修改 |
ff.h | Fatfs和应用模块公用的包含文件 | 不需要修改 |
ffconf.h | Fatfs模块配置文件 | 需要根据需求来配置参数 |
ffunicode.c | Fatfs所支持的字体代码转换表 | 不需要修改 |
ffsystem.c | Fatfs的 OS相关函数示例代码 | 没用到 |
- 这是添加到工程的结构
说明:mmc_sd.c实现的是SD卡底层的驱动。
四、接口的实现
Fatfs移植需要我们提供以下接口,而基本的接口,我们可以在官方提供的 diskio.c源文件中找到
在本例中,是接入 SD Card存储介质,因此,在 Fatfs文件系统包的 diskio.c源文件中添加对应的接口
从 diskio.c开端,我们可以看到以下宏定义
/* Definitions of physical drive number for each drive */
#define DEV_RAM 0 /* Example: Map Ramdisk to physical drive 0 */
#define DEV_MMC 1 /* Example: Map MMC/SD card to physical drive 1 */
#define DEV_USB 2 /* Example: Map USB MSD to physical drive 2 */
而 SD Card属于宏 DEV_MMC范畴内,在后面的接口函数中,我们只需要在与 DEV_MMC相关的位置上添加自己写的底层驱动,其他注释,例如
修改后的diskio.c
#include "ff.h" /* Obtains integer types */
#include "diskio.h" /* Declarations of disk functions */
#include "mmc_sd.h" //底层驱动文件
/* Definitions of physical drive number for each drive */
#define DEV_RAM 0 /* Example: Map Ramdisk to physical drive 0 */
#define DEV_MMC 1 /* Example: Map MMC/SD 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 = STA_NOINIT;
int result;
switch (pdrv) {
case DEV_RAM :
return stat;
case DEV_MMC :
result = SD_disk_status();
// translate the reslut code here
if(1 == result)
stat &= ~STA_NOINIT;
return stat;
case DEV_USB :
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_RAM :
return stat;
case DEV_MMC :
result = SD_disk_initialize();
if(1 == result)
stat &= ~STA_NOINIT;
return stat;
case DEV_USB :
return stat;
}
return STA_NOINIT;
}
/*-----------------------------------------------------------------------*/