一、数据类型
FatFs使用的数据类型在ff.h中定义,适用于绝大多数平台:
BYTE | 8-bit无符号整形数据,范围0~28-1 |
WORD | 16-bit无符号整形数据,范围0~216-1 |
DWORD | 32-bit无符号整形数据,范围0~232-1 |
QWORD | 64-bit无符号整型数据,范围0~264-1 |
UINT | 无符号int |
WCHAR | UTF-16代码单位的WORD |
TCHAR | 字符编码单位的CHAR、WCHAR、DCHAR |
FSIZE_t | DWORD、QWORD别名,用于寻址文件偏移量和指定文件大小 |
LBA_t | DWORD、QWORD别名,用于寻址LBA的扇区并指定扇区数 |
二、ffconf.h
相关配置宏:
_FS_TINY | mini版本的FATFS |
_FS_READONLY | 设置只读,可以减少所占的空间 |
_FS_MINIMIZE | 削减函数 |
_USE_STRFUNC | 字符及字符串操作函数 |
_USE_MKFS | 是否启用格式化 |
_USE_FASTSEEK | 使能快速定位 |
_USE_LABEL | 是否支持磁盘盘符的设置和读取 |
_CODE_PAGE | 设置语言936-中文GBK编码 |
_USE_LFN | 是否支持长文件名,值不同存储的位置不同 |
_MAX_LFN | 文件名的最大长度 |
_VOLUMES | 支持的逻辑设备数目 |
_MAX_SS | 扇区缓冲最大值,一般为512 |
三、diskio.c
底层驱动涉及的6个接口函数:
- Storage Device Controls
- disk status - Get device status
- disk initialize - Initialize device
- disk read - Read data
- disk write - Write data
- disk ioct1 - Control device dependent functions
- Real Time Clock
- get fattime - Get current time
宏定义:
/* 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 */
FatFs支持多物理设备,必须为每个物理设备定义一个不同的编号。
实际中根据接入的物理设备(flash、SD卡等)进行修改。
设备状态读取函数 disk_status()
/*-----------------------------------------------------------------------*/
/* Get Drive Status */
/*-----------------------------------------------------------------------*/
DSTATUS disk_status (
BYTE pdrv /* Physical drive nmuber to identify the drive */
)
{
DSTATUS stat;
int result;
switch (pdrv) {
case DEV_RAM :
result = RAM_disk_status();
// translate the reslut code here
return stat;
case DEV_MMC :
result = MMC_disk_status();
// translate the reslut code here
return stat;
case DEV_USB :
result = USB_disk_status();
// translate the reslut code here
return stat;
}
return STA_NOINIT;
}
函数只有一个参数pdrv,表示宏定义中的物理设备的编号。
函数中使用switch函数实现判断。
各case中需要编写相应的硬件底层函数。
设备初始化函数 disk_initialize()
/*-----------------------------------------------------------------------*/
/* Inidialize a Drive */
/*-----------------------------------------------------------------------*/
DSTATUS disk_initialize (
BYTE pdrv /* Physical drive nmuber to identify the drive */
)
{
DSTATUS stat;
int result;
switch (pdrv) {
case DEV_RAM :
result = RAM_disk_initialize();
// translate the reslut code here
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;
}
函数只有一个参数prdv,指定物理设备的编号。
各case中需要编写相应的硬件底层函数。
读取扇区函数 disk_read()
/*-----------------------------------------------------------------------*/
/* Read Sector(s) */
/*-----------------------------------------------------------------------*/
DRESULT disk_read (
BYTE pdrv, /* Physical drive nmuber to identify the drive */
BYTE *buff, /* Data buffer to store read data */
LBA_t sector, /* Start sector in LBA */
UINT count /* Number of sectors to read */
)
{
DRESULT res;
int result;
switch (pdrv) {
case DEV_RAM :
// translate the arguments here
result = RAM_disk_read(buff, sector, count);
// translate the reslut code here
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;
}
函数包含4个参数:
pdrv:设备物理编号
buff:指向用于存放读取到的数据的存储位置首地址
sector:指定要读取数据的扇区首地址
count:指定扇区数量
各case中需要编写相应的硬件底层函数。
写扇区函数 disk_write()
/*-----------------------------------------------------------------------*/
/* 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 */
LBA_t sector, /* Start sector in LBA */
UINT count /* Number of sectors to write */
)
{
DRESULT res;
int result;
switch (pdrv) {
case DEV_RAM :
// translate the arguments here
result = RAM_disk_write(buff, sector, count);
// translate the reslut code here
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
如果是只读模式,该函数无效。
函数包含4个参数:
pdrv:物理设备编号
buff:指向待写入扇区数据的首地址
sector:指定要写入数据的扇区首地址
count:指定扇区数量
各case中需要编写相应的硬件底层函数
其他功能控制函数 disk_ioct1():
/*-----------------------------------------------------------------------*/
/* 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_RAM :
// Process of the command for the RAM drive
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;
}
时间函数 get_fattime():
DWORD get_fattime (void)
{
time_t t;
struct tm *stm;
t = time(0);
stm = localtime(&t);
return (DWORD)(stm->tm_year - 80) << 25 |
(DWORD)(stm->tm_mon + 1) << 21 |
(DWORD)stm->tm_mday << 16 |
(DWORD)stm->tm_hour << 11 |
(DWORD)stm->tm_min << 5 |
(DWORD)stm->tm_sec >> 1;
}