FATFS常见面试题
它是文件系统操作的基准目录,如果在程序中不指定文件的绝对路径,操作系统会默认从工作目录中寻找文件。FATFS(FAT File System)是一个开源的文件系统模块,它被设计用于嵌入式系统中,支持FAT(File Allocation Table)文件系统。中,存在下面这个宏定义,将这个宏定义置1,即可开启相对路径的支持,从而可以设置工作目录。这样的操作时,如果没有指定绝对路径,系统会假定文件位
什么是FATFS?
FATFS(FAT File System)是一个开源的文件系统模块,它被设计用于嵌入式系统中,支持FAT(File Allocation Table)文件系统。
FATFS支持哪些存储设备?
- SD卡、TF卡
- MMC卡
- USB存储设备
- NOR和NAND闪存
FATFS中常用的文件操作函数有哪些?
以下函数全部在ff.c文件中定义。
/*-----------------------------------------------------------------------*/
/* Mount/Unmount a Logical Drive */
/*-----------------------------------------------------------------------*/
FRESULT f_mount (
FATFS* fs, /* Pointer to the filesystem object (NULL:unmount)*/
const TCHAR* path, /* Logical drive number to be mounted/unmounted */
BYTE opt /* Mode option 0:Do not mount (delayed mount), 1:Mount immediately */
);
/*-----------------------------------------------------------------------*/
/* Open or Create a File */
/*-----------------------------------------------------------------------*/
FRESULT f_open (
FIL* fp, /* Pointer to the blank file object */
const TCHAR* path, /* Pointer to the file name */
BYTE mode /* Access mode and file open mode flags */
);
FRESULT f_close (
FIL* fp /* Pointer to the file object to be closed */
);
/*-----------------------------------------------------------------------*/
/* Read File */
/*-----------------------------------------------------------------------*/
FRESULT f_read (
FIL* fp, /* Pointer to the file object */
void* buff, /* Pointer to data buffer */
UINT btr, /* Number of bytes to read */
UINT* br /* Pointer to number of bytes read */
);
FRESULT f_write (
FIL* fp, /* Pointer to the file object */
const void* buff, /* Pointer to the data to be written */
UINT btw, /* Number of bytes to write */
UINT* bw /* Pointer to number of bytes written */
);
/*-----------------------------------------------------------------------*/
/* Delete a File/Directory */
/*-----------------------------------------------------------------------*/
FRESULT f_unlink (
const TCHAR* path /* Pointer to the file or directory path */
);
/*-----------------------------------------------------------------------*/
/* Rename a File/Directory */
/*-----------------------------------------------------------------------*/
FRESULT f_rename (
const TCHAR* path_old, /* Pointer to the object name to be renamed */
const TCHAR* path_new /* Pointer to the new name */
);
/*-----------------------------------------------------------------------*/
/* Get File Status */
/*-----------------------------------------------------------------------*/
FRESULT f_stat (
const TCHAR* path, /* Pointer to the file path */
FILINFO* fno /* Pointer to file information to return */
);
/*-----------------------------------------------------------------------*/
/* Create a Directory Object */
/*-----------------------------------------------------------------------*/
FRESULT f_opendir (
DIR* dp, /* Pointer to directory object to create */
const TCHAR* path /* Pointer to the directory path */
);
/*-----------------------------------------------------------------------*/
/* Read Directory Entries in Sequence */
/*-----------------------------------------------------------------------*/
FRESULT f_readdir (
DIR* dp, /* Pointer to the open directory object */
FILINFO* fno /* Pointer to file information to return */
);
/*-----------------------------------------------------------------------*/
/* Close Directory */
/*-----------------------------------------------------------------------*/
FRESULT f_closedir (
DIR *dp /* Pointer to the directory object to be closed */
);
/*-----------------------------------------------------------------------*/
/* Synchronize the File */
/*-----------------------------------------------------------------------*/
FRESULT f_sync (
FIL* fp /* Pointer to the file object */
);
什么是工作目录(Working Directory)?如何设置工作目录?
工作目录(Working Directory)是指当前程序或进程访问和操作文件时的默认目录。它是文件系统操作的基准目录,如果在程序中不指定文件的绝对路径,操作系统会默认从工作目录中寻找文件。
例如,在FATFS文件系统中,当你执行 f_open("myfile.txt", FA_READ); 这样的操作时,如果没有指定绝对路径,系统会假定文件位于当前的工作目录中。
在ffconf.h中,存在下面这个宏定义,将这个宏定义置1,即可开启相对路径的支持,从而可以设置工作目录。
#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.
*/
下面的f_chdir()和f_chdrive()在FF_FS_RPATH为1的时候就可以使用,但f_getcwd()必须在FF_FS_RPATH为2的时候才可以使用。
// 该函数用于切换工作目录
FRESULT f_chdir (
const TCHAR* path /* Pointer to the directory path */
)
/*-----------------------------------------------------------------------*/
/* Change Current Directory or Current Drive, Get Current Directory */
/*-----------------------------------------------------------------------*/
FRESULT f_chdrive (
const TCHAR* path /* Drive number to set */
)
//该函数用于获取当前工作目录
FRESULT f_getcwd (
TCHAR* buff, /* Pointer to the directory path */
UINT len /* Size of buff in unit of TCHAR */
)
FATFS中文件名的限制有哪些?
在ffconf.h中,有下面的宏定义:
#define FF_USE_LFN 3
#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.
/ 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 it 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() exemplified in ffsystem.c, need to be added to the project. */
如果将FF_USE_LFN定义为0,则只能使用短文件名,文件名最多8个字符,扩展名最多3个字符。
如果将FF_USE_LFN定义为1或2或3,则根据FF_MAX_LFN确定最大文件名。
如何挂载和卸载一个文件系统?
查看f_mount()函数。fs参数传入NULL则是代表卸载。
如何检查存储设备的剩余空间?
在ff.c中,存在下面这个函数:
/*-----------------------------------------------------------------------*/
/* Get Number of Free Clusters */
/*-----------------------------------------------------------------------*/
FRESULT f_getfree (
const TCHAR* path, /* Logical drive number */
DWORD* nclst, /* Pointer to a variable to return number of free clusters */
FATFS** fatfs /* Pointer to return pointer to corresponding filesystem object */
);
通过它可以计算设备剩余空间。
/**
* @brief 获取磁盘剩余容量
* @param pdrv : 磁盘编号("0:"~"9:")
* @param total: 总容量 (KB)
* @param free : 剩余容量 (KB)
* @retval 0, 正常; 其他, 错误代码
*/
uint8_t exfuns_get_free(uint8_t *pdrv, uint32_t *total, uint32_t *free)
{
FATFS *fs1;
uint8_t res;
uint32_t fre_clust = 0, fre_sect = 0, tot_sect = 0;
/* 得到磁盘信息及空闲簇数量 */
res = (uint32_t)f_getfree((const TCHAR *)pdrv, (DWORD *)&fre_clust, &fs1);
if (res == 0)
{
tot_sect = (fs1->n_fatent - 2) * fs1->csize; /* 得到总扇区数 */
fre_sect = fre_clust * fs1->csize; /* 得到空闲扇区数 */
#if FF_MAX_SS!=512 /* 扇区大小不是512字节,则转换为512字节 */
tot_sect *= fs1->ssize / 512;
fre_sect *= fs1->ssize / 512;
#endif
*total = tot_sect >> 1; /* 单位为KB */
*free = fre_sect >> 1; /* 单位为KB */
}
return res;
}
如何使用FATFS创建、删除或重命名文件?
创建:
FIL file;
FRESULT res;
res = f_open(&file, "0:/newfile.bmp", FA_CREATE_ALWAYS | FA_WRITE);
if (res == FR_OK) {
// 文件创建成功
f_close(&file);
} else {
// 处理错误
}
//写入数据,下面这行代码来自bmp文件头的写入。
f_write(&file, &bmpFileHeader, sizeof(BMPFileHeader), &bw);
f_close(&file);
删除:
f_unlink(file_path);
重命名:
FRESULT res;
res = f_rename("0:/oldname.txt", "0:/newdir/newname.txt");
if (res == FR_OK) {
// 移动并重命名成功
} else {
// 处理错误
}
重命名不仅仅可以在相同目录下进行,也可以起到移动文件的作用,但新旧文件必须位于同一逻辑驱动器上。
如何遍历FATFS中的目录和文件?
void scan_files(void)
{
f.fr = f_opendir(&f.dir, f.cur_path); /* 打开文件目录 */
if(f.fr == FR_OK)
{
while(true) {
f.fr = f_readdir(&f.dir, &f.SD_fno);
if(f.fr != LV_FS_RES_OK || f.SD_fno.fname[0] == 0) break;
list_btn_data *btn_data = (list_btn_data *) pvPortMalloc(sizeof(list_btn_data));
if(f.SD_fno.fattrib & AM_DIR)
{
//是文件夹
}
else
{
//是文件
}
}
f_closedir(&f.dir); /* 关闭文件目录 */
}
}
如何处理FATFS中的错误?如何解析错误代码?
在ff.h中,有下列定义:
/* File function return code (FRESULT) */
typedef enum {
FR_OK = 0, /* (0) Succeeded */
FR_DISK_ERR, /* (1) A hard error occurred in the low level disk I/O layer */
FR_INT_ERR, /* (2) Assertion failed */
FR_NOT_READY, /* (3) The physical drive cannot work */
FR_NO_FILE, /* (4) Could not find the file */
FR_NO_PATH, /* (5) Could not find the path */
FR_INVALID_NAME, /* (6) The path name format is invalid */
FR_DENIED, /* (7) Access denied due to prohibited access or directory full */
FR_EXIST, /* (8) Access denied due to prohibited access */
FR_INVALID_OBJECT, /* (9) The file/directory object is invalid */
FR_WRITE_PROTECTED, /* (10) The physical drive is write protected */
FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */
FR_NOT_ENABLED, /* (12) The volume has no work area */
FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume */
FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any problem */
FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */
FR_LOCKED, /* (16) The operation is rejected according to the file sharing policy */
FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */
FR_TOO_MANY_OPEN_FILES, /* (18) Number of open files > FF_FS_LOCK */
FR_INVALID_PARAMETER /* (19) Given parameter is invalid */
} FRESULT;
如何通过FATFS实现文件的随机读写(Seek操作)?
/*-----------------------------------------------------------------------*/
/* Seek File Read/Write Pointer */
/*-----------------------------------------------------------------------*/
FRESULT f_lseek (
FIL* fp, /* Pointer to the file object */
FSIZE_t ofs /* File pointer from top of file */
);
FATFS的f_sync函数的作用是什么?为什么需要它?
在FATFS文件系统中,f_sync函数的主要作用是将文件的缓存数据同步到存储介质,确保已写入的数据被实际保存。这对于长时间以写模式打开文件的应用(如数据记录器)尤为重要。
/*-----------------------------------------------------------------------*/
/* Synchronize the File */
/*-----------------------------------------------------------------------*/
FRESULT f_sync (
FIL* fp /* Pointer to the file object */
);
更多推荐



所有评论(0)