FATFS官网:http://elm-chan.org/fsw/ff/00index_e.html
本篇博客不讲解移植教程,只讲解常用API如何使用。
/**
* 挂载文件系统
* @param fs 文件系统句柄
* @param path 逻辑驱动器号码
* @param opt 初始化属性,=0:在第一次访问文件系统的时候挂载,=1:立刻挂载
* @return 成功返回FR_OK,失败返回其他值,具体看FRESULT定义
*
* FATFS fs;
* 示例:f_mount(&fs, "0:/", 1);
*/
FRESULT f_mount(FATFS* fs, const TCHAR* path, BYTE opt);
/**
* 解除挂载
* @param path 逻辑驱动器号码
* @return 成功返回FR_OK,失败返回其他值,具体看FRESULT定义
*
* 示例:f_unmount("0:/");
*/
FRESULT f_unmount (const TCHAR* path);
注意:旧版本的FATFS没有f_unmount函数,取消挂载是使用f_mount函数:
f_mount(NULL, "0:/", 1);
/**
* 打开文件
* @param fp 文件句柄
* @param path 文件路径
* @param mode 打开模式
* @return 成功返回FR_OK,失败返回其他值,具体看FRESULT定义
*
* FIL fp;
* 示例:f_open(&fp, "0:/helloworld.txt", FA_CREATE_ALWAYS | FA_WRITE | FA_READ)
*/
FRESULT f_open (FIL* fp, const TCHAR* path, BYTE mode);
/**
* 关闭文件
* @param fp 文件句柄
* @return 成功返回FR_OK,失败返回其他值,具体看FRESULT定义
*/
FRESULT f_close (FIL* fp);
mode参数说明:
以上参数可以组合使用。
读文件:
/**
* 从文件中读数据
* @param fp 文件句柄
* @param buff 存放读取到的数据
* @param btr 要读取的字节数
* @param br 实际读取到的字节数
* @return 成功返回FR_OK,失败返回其他值,具体看FRESULT定义
*
* 示例:
* FIL fp;
* char buf[128];
* UINT nread = 0;
* f_read(&fp, buf, sizeof(buf), &nread);
*/
FRESULT f_read (FIL* fp, void* buff, UINT btr, UINT* br);
写文件:
/**
* 向文件写数据
* @param fp 文件句柄
* @param buff 待写入的数据
* @param btw 待写入的数据字节数
* @param bw 实际写入的字节数
* @return 成功返回FR_OK,失败返回其他值,具体看FRESULT定义
*
* 示例:
* FIL fp;
* const char* str = "helloworld";
* UINT nwrite = 0;
* f_write(&fp, str, strlen(buf), &nwrite);
*/
FRESULT f_write (FIL* fp, const void* buff, UINT btw, UINT* bw);
获取打开的文件大小:
/**
* 获取文件大小
* @param fp 文件句柄
* @return 成功返回FR_OK,失败返回其他值,具体看FRESULT定义
*/
FSIZE_t f_size (FIL* fp);
注意:f_size只能用于文件被打开后,它其实是一个宏定义:
#define f_size(fp) ((fp)->obj.objsize)
//
/**
* @file fops.c
* @autor [email protected]
* @data 2020/3/5
*/
//
#include "fops.h"
#include
FILINFO USERFileInfo; //文件信息
DIR USERDir; //目录
void exf_getfree(SDCard_InfoTypedef *sdinfo)
{
FATFS *fs = NULL;
DWORD fre_clust = 0;
if (sdinfo != NULL)
{
memset(sdinfo, 0X00, sizeof(SDCard_InfoTypedef));
if (f_getfree(USERPath, &fre_clust, &fs) == FR_OK)
{
sdinfo->tot_sect = (fs->n_fatent - 2) * fs->csize; // 总扇区数
sdinfo->fre_sect = fre_clust * fs->csize; // 空闲扇区数
sdinfo->tol_capacity = sdinfo->tot_sect >> 11; // 转为MB
sdinfo->fre_capacity = sdinfo->fre_sect >> 11; // 转为MB
}
}
}
FRESULT exf_mount(void)
{
#if _USE_LFN
static char LFNAME[_MAX_LFN * 2 + 1]; /* 一个汉字占用2个字节 */
USERFileInfo.lfsize = sizeof(LFNAME);
USERFileInfo.lfname = LFNAME;
#endif
FATFS_LinkDriver(&USER_Driver, USERPath);
return f_mount(&USERFatFS, USERPath, 1);
}
FRESULT exf_format(
BYTE sfd, /* Partitioning rule 0:FDISK, 1:SFD */
UINT au /* Size of allocation unit in unit of byte or sector */
)
{
return f_mkfs(USERPath, sfd, au);
}
FRESULT exf_unmount(void)
{
FATFS_UnLinkDriver(USERPath);
return f_mount(NULL, USERPath, 1);
}
FRESULT exf_open(const void *filename, BYTE mode)
{
return f_open(&USERFile, filename, mode);
}
uint32_t exf_get_open_file_size(void)
{
return USERFile.fsize;
}
int exf_write(const void *buf, uint32_t len)
{
FRESULT res = FR_OK;
UINT btw = 0;
res = f_write(&USERFile, (uint8_t*) buf, len, &btw);
if(res != FR_OK)
{
return -1;
}
return (int)btw;
}
int exf_read(void *buf, uint32_t len)
{
FRESULT res = FR_OK;
UINT btr = 0;
res = f_read(&USERFile, buf, len, &btr);
if(res != FR_OK)
{
return -1;
}
return (int)btr;
}
bool exf_gets(void* buf, uint32_t len)
{
return f_gets((TCHAR *)buf, len, &USERFile) == NULL ? false : true;
}
FRESULT exf_scan_files (char* path)
{
FRESULT res;
DIR dir; //目录信息,注意这个结构很大
FILINFO USERFileInfo; //文件信息,注意这个结构很大
UINT i;
char *fn; /* This function is assuming non-Unicode cfg. */
res = f_opendir(&dir, path); /* Open the directory */
if (res == FR_OK)
{
for (;;)
{
res = f_readdir(&dir, &USERFileInfo); /* Read a directory item */
if (res != FR_OK || USERFileInfo.fname[0] == 0) break; /* Break on error or end of dir */
//if (USERFileInfo.fname[0] == '.') continue; /* 忽略上级目录 */
if (USERFileInfo.fattrib & AM_DIR) /* It is a directory */
{
i = strlen(path);
#if _USE_LFN
fn = *USERFileInfo.lfname ? USERFileInfo.lfname : USERFileInfo.fname;
#else
fn = USERFileInfo.fname;
#endif
sprintf(&path[i], "/%s", fn);
res = exf_scan_files(path); /* Enter the directory */
if (res != FR_OK) break;
path[i] = 0;
}
else /* It is a file. */
{
#if _USE_LFN
fn = *USERFileInfo.lfname ? USERFileInfo.lfname : USERFileInfo.fname;
#else
fn = USERFileInfo.fname;
#endif
printf("%s/%s\n", path, fn);
}
}
f_closedir(&dir);
}
return res;
}
bool exf_lseek(DWORD offset)
{
if(f_lseek(&USERFile, offset) == FR_OK)
{
return true;
}
return false;
}
void exf_close(void)
{
f_close(&USERFile);
}
//
/**
* @file fops.h
* @autor [email protected]
* @data 2020/3/5
* @note FatFs操作SD卡API
*/
//
#ifndef __FOPS_H
#define __FOPS_H
#include "main.h"
#include "fatfs.h"
#include
#include
typedef struct
{
DWORD fre_sect; /* 空闲扇区数 */
DWORD tot_sect; /* 总扇区数 */
DWORD fre_capacity; /* 空闲容量,单位MB */
DWORD tol_capacity; /* 总容量,单位MB */
} SDCard_InfoTypedef;
void exf_getfree(SDCard_InfoTypedef* sdinfo);
FRESULT exf_mount(void);
FRESULT exf_unmount(void);
FRESULT exf_open(const void* filename, BYTE mode);
int exf_write(const void *buf, uint32_t len);
int exf_read(void* buf, uint32_t len);
bool exf_gets(void* buf, uint32_t len);
bool exf_lseek(DWORD offset);
void exf_close(void);
FRESULT exf_format(BYTE sfd, UINT au);
uint32_t exf_get_open_file_size(void);
FRESULT exf_scan_files (char* path);
extern FILINFO USERFileInfo; //文件信息
extern DIR USERDir; //目录
#endif