1 FATFS(R0.15)
FATFS(FAT文件系统)是一个开源的文件系统模块,主要用于嵌入式系统和微控制器。它支持FAT12、FAT16和FAT32文件系统,能够在各种存储介质上进行文件操作,如SD卡、USB闪存等。
FATFS的设计目标是轻量级、高效和简易集成,它允许用户在资源有限的环境中进行文件管理。FATFS支持基本的文件操作,如创建、读取、写入和删除文件,并且具有良好的移植性,适用于多种开发环境和平台。
FATFS的主要特点包括:
- 开放源代码:可以自由使用和修改。
- 广泛兼容:支持多种FAT格式,适应不同的存储设备。
- 易于集成:适合与各种嵌入式操作系统或裸机环境结合使用。
- 支持文件管理功能:如目录管理、文件属性设置等。
FATFS被广泛应用于需要文件存储的各种嵌入式应用中,如数据记录仪、音频播放器和工业控制系统等。
2 FATFS格式
3 FATFS参数配置
4 FATFS对象
FATFS *fs; // 文件系统对象指针 DIR* dp // 目录对象指针 FIL* fp // 文件对象指针(文件读写指针) FILINFO* fno // 文件/目录信息对象指针 const TCHAR* path // 目录/文件 路径指针
4.1 FATFS
/** * @note The FATFS structure (filesystem object) holds dynamic work area of individual logical drives. It is given by application program and registerd/unregisterd to the FatFs module with f_mount function. Initialization of the structure is done by volume mount process whenever necessary. Application program must not modify any member in this structure, or the FAT volume will be collapsed. */ typedef struct { BYTE fs_type; /* FAT type (0, FS_FAT12, FS_FAT16, FS_FAT32 or FS_EXFAT) */ BYTE pdrv; /* Hosting physical drive of this volume */ BYTE n_fats; /* Number of FAT copies (1,2) */ BYTE wflag; /* win[] flag (b0:win[] is dirty) */ BYTE fsi_flag; /* FSINFO flags (b7:Disabled, b0:Dirty) */ WORD id; /* Volume mount ID */ WORD n_rootdir; /* Number of root directory entries (FAT12/16) */ WORD csize; /* Sectors per cluster */ #if FF_MAX_SS != FF_MIN_SS WORD ssize; /* Sector size (512,1024,2048 or 4096) */ #endif #if FF_FS_EXFAT BYTE* dirbuf; /* Directory entry block scratchpad buffer */ #endif #if FF_FS_REENTRANT FF_SYNC_t sobj; /* Identifier of sync object */ #endif #if !FF_FS_READONLY DWORD last_clust; /* FSINFO: Last allocated cluster (0xFFFFFFFF if invalid) */ DWORD free_clust; /* FSINFO: Number of free clusters (0xFFFFFFFF if invalid) */ #endif #if FF_FS_RPATH DWORD cdir; /* Cluster number of current directory (0:root) */ #if FF_FS_EXFAT DWORD cdc_scl; /* Containing directory start cluster (invalid when cdir is 0) */ DWORD cdc_size; /* b31-b8:Size of containing directory, b7-b0: Chain status */ DWORD cdc_ofs; /* Offset in the containing directory (invalid when cdir is 0) */ #endif #endif DWORD n_fatent; /* Number of FAT entries (Number of clusters + 2) */ DWORD fsize; /* Sectors per FAT */ LBA_t volbase; /* Volume base LBA */ LBA_t fatbase; /* FAT base LBA */ LBA_t dirbase; /* Root directory base (LBA|Cluster) */ LBA_t database; /* Data base LBA */ LBA_t winsect; /* Sector LBA appearing in the win[] */ BYTE win[FF_MAX_SS]; /* Disk access window for directory, FAT (and file data at tiny cfg) */ } FATFS;
4.2 DIR
/** * @note The DIR structure is used for the work area to read a directory by f_oepndir, f_readdir, f_findfirst and f_findnext function. Application program must not modify any member in this structure, or f_readdir function will not work properly. */ typedef struct { FFOBJID obj; /* Object identifier */ DWORD dptr; /* Current read/write offset */ DWORD clust; /* Current cluster */ LBA_t sect; /* Current sector */ BYTE* dir; /* Pointer to the current SFN entry in the win[] */ BYTE* fn; /* Pointer to the SFN buffer (in/out) {file[8],ext[3],status[1]} */ #if FF_USE_LFN DWORD blk_ofs; /* Offset of the entry block (0xFFFFFFFF:Invalid) */ WCHAR* lfn; /* Pointer to the LFN working buffer (in/out) */ #endif #if FF_USE_FIND const TCHAR* pat; /* Ponter to the matching pattern */ #endif } DIR;
4.3 FIL
/** * @note The FIL structure (file object) holds the state of an open file. It is created by f_open function and discarded by f_close function. Application program must not modify any member in this structure except for cltbl, or the FAT volume will be collapsed. Note that a sector buffer is defined in this structure at non-tiny configuration (FF_FS_TINY == 0), so that the FIL structures at that configuration should not be defined as auto variable. */ typedef struct { FFOBJID obj; /* Object identifier */ BYTE flag; /* File object status flags */ BYTE err; /* Abort flag (error code) */ FSIZE_t fptr; /* File read/write pointer (Byte offset origin from top of the file) */ DWORD clust; /* Current cluster of fptr (One cluster behind if fptr is on the cluster boundary. Invalid if fptr == 0.) */ LBA_t sect; /* Current data sector (Can be invalid if fptr is on the cluster boundary.)*/ #if !FF_FS_READONLY LBA_t dir_sect; /* Sector number containing the directory entry */ BYTE* dir_ptr; /* Ponter to the directory entry in the window */ #endif #if FF_USE_FASTSEEK DWORD* cltbl; /* Pointer to the cluster link map table (Nulled on file open. Set by application.) */ #endif #if !FF_FS_TINY BYTE buf[FF_MAX_SS]; /* File private data transfer buffer (Always valid if fptr is not on the sector boundary but can be invalid if fptr is on the sector boundary.) */ #endif } FIL;
4.4 FILINFO
/** * @note The FILINFO structure holds information about the object retrieved by f_readdir, f_findfirst, f_findnext and f_stat function. Be careful in the size of structure when LFN is enabled. */ typedef struct { FSIZE_t fsize; /* File size */ WORD fdate; /* Last modified date */ WORD ftime; /* Last modified time */ BYTE fattrib; /* Attribute */ #if FF_USE_LFN TCHAR altname[FF_SFN_BUF + 1]; /* Alternative object name */ TCHAR fname[FF_LFN_BUF + 1]; /* Primary object name */ #else TCHAR fname[12 + 1]; /* Object name */ #endif } FILINFO;
5 FATFS函数
5.1 卷管理和系统配置
f_fdisk
/** * @brief The f_fdisk fucntion divides a physical drive. * @note 在物理驱动器上创建分区(逻辑分区) */ FRESULT f_fdisk ( BYTE pdrv, /* [IN] Physical drive number */ // 指定要分配的物理驱动器号,是传递给底层磁盘功能的驱动器标识符 const LBA_t ptbl[], /* [IN] Partition map table */ // 要在物理驱动器上创建的分区大小列表 void* work /* [IN] Work area */ // 指向工作缓存区 );
f_mkfs
/** * @brief The f_mkfs function creates an FAT/exFAT volume on the logical drive. * @note 在逻辑驱动器上创建 FAT 卷 */ FRESULT f_mkfs ( const TCHAR* path, /* [IN] Logical drive number */ const MKFS_PARM* opt,/* [IN] Format options */ void* work, /* [-] Working buffer */ UINT len /* [IN] Size of working buffer */ );
f_mount
/** * @brief The f_mount fucntion gives work area to the FatFs module.(f_mount 也会起到格式化 FAT 卷的作用) * @note 为 FAT 卷注册/取消注册工作区 */ FRESULT f_mount ( FATFS* fs, /* [IN] Filesystem object */ // 文件系统对象指针(逻辑驱动器的工作区) const TCHAR* path, /* [IN] Logical drive number */ // 逻辑驱动器号 BYTE opt /* [IN] Initialization option */ // 挂载选项(0:暂不挂载,1:立即挂载) ); FRESULT f_unmount ( const TCHAR* path /* [IN] Logical drive number */ // 取消挂载对应的逻辑驱动器 );
f_setcp
/** * @brief The f_setcp function sets the active code page. * @note 设置系统要使用的 OEM 代码页 */ FRESULT f_setcp ( WORD cp /* [IN] Code page to be set */ );
f_setlabel
/** * @brief The f_setlabel function sets/removes the label of a volume. * @note 为逻辑驱动器设置卷标 */ FRESULT f_setlabel ( const TCHAR* label /* [IN] Volume label to be set */ );
f_getlabel
/** * @brief The f_getlabel function returns volume label and volume serial number of a volume. * @note 获取逻辑驱动器的卷标 */ FRESULT f_getlabel ( const TCHAR* path, /* [IN] Drive number */ TCHAR* label, /* [OUT] Volume label */ DWORD* vsn /* [OUT] Volume serial number */ );
f_getfree
/** * @brief The f_getfree function gets number of the free clusters on the volume. * @note 获取卷上的可用空间 */ FRESULT f_getfree ( const TCHAR* path, /* [IN] Logical drive number */ DWORD* nclst, /* [OUT] Number of free clusters */ FATFS** fatfs /* [OUT] Corresponding filesystem object */ );
5.2 文件和目录管理
f_chdrive
/** * @brief The f_chdrive function changes the current drive. * @note 更改当前驱动器 */ FRESULT f_chdrive ( const TCHAR* path /* [IN] Logical drive number */ // 将指定的逻辑驱动器设置为当前驱动器 );
f_mkdir
/** * @brief The f_mkdir function creates a new directory. * @note 创建一个目录 */ FRESULT f_mkdir ( const TCHAR* path /* [IN] Directory name */ // 将指向的字符串视为绝对路径创建目录 );
f_chdir
/** * @brief The f_chdir function changes the current directory of the logical drive. * @note 更改当前目录 */ FRESULT f_chdir ( const TCHAR* path /* [IN] Path name */ // 指向以空结尾的字符串,将该字符串指定的目录切换为当前目录 );
f_chmod
/** * @brief The f_chmod function changes the attribute of a file or sub-directory. * @note 更改文件或子目录的属性 */ FRESULT f_chmod ( const TCHAR* path, /* [IN] Object name */ BYTE attr, /* [IN] Attribute flags */ BYTE mask /* [IN] Attribute masks */ );
f_stat
/** * @brief The f_stat function checks the existence of a file or sub-directory. * @note 检查文件或子目录是否存在 */ FRESULT f_stat ( const TCHAR* path, /* [IN] Object name */ FILINFO* fno /* [OUT] FILINFO structure */ );
f_getcwd
/** * @brief The f_getcwd function retrieves the current directory of the current drive. * @note 检索当前目录和驱动器 */ FRESULT f_getcwd ( TCHAR* buff, /* [OUT] Buffer to return path name */ // 指向接收当前目录字符串的缓冲区 UINT len /* [IN] The length of the buffer */ // 以TCHAR为单位的缓冲区大小 );
f_utime
/** * @brief The f_utime function changes the timestamp of a file or sub-directory. * @note 更改文件或子目录的时间戳 */ FRESULT f_utime ( const TCHAR* path, /* [IN] Object name */ // 要修改 修改时间 的文件/目录的绝对路径 const FILINFO* fno /* [IN] Time and data to be set */ );
f_rename
/** * @brief The f_rename function renames and/or moves a file or sub-directory. * @note 重命名/移动文件或子目录 */ FRESULT f_rename ( const TCHAR* old_name, /* [IN] Old object name */ const TCHAR* new_name /* [IN] New object name */ );
f_unlink
/** * @brief The f_unlink function removes a file or sub-directory from the volume. * @note 删除文件或子目录 */ FRESULT f_unlink ( const TCHAR* path /* [IN] Object name */ // 指向要删除的文件或子目录(绝对路径) );
5.3 目录访问
f_opendir
/** * @brief The f_opendir function opens a directory. * @note 打开指定目录 */ FRESULT f_opendir ( DIR* dp, /* [OUT] Pointer to the directory object structure */ const TCHAR* path /* [IN] Directory name */ );
f_readdir
/** * @brief The f_readdir function reads an item of the directory. * @note 读取当前打开目录下的一个对象(子目录/文件)(循环调用即可遍历整个目录) */ FRESULT f_readdir ( DIR* dp, /* [IN] Directory object */ // 指向已经打开的目录对象 FILINFO* fno /* [OUT] File information structure */ // 用于存储目录对象下的子目录/文件的有关信息 ); /* When a null pointer is given to the fno, the read index of the directory object is rewinded. The f_rewinddir function is implemented as a macro. */ #define f_rewinddir(dp) f_readdir((dp), 0)
f_findfirst
/** * @brief The f_findfirst function searches a directroy for an item. * @note 检索打开的目录中匹配的第一个对象 */ FRESULT f_findfirst ( DIR* dp, /* [OUT] Poninter to the directory object */ // 指向打开的目录对象 FILINFO* fno, /* [OUT] Pointer to the file information structure */ // 指向信息对象 const TCHAR* path, /* [IN] Pointer to the directory name to be opened */ // 指向要打开的目录 const TCHAR* pattern /* [IN] Pointer to the matching pattern string */ );
f_findnext
/** * @brief The f_findnext function searches for a next matched object * @note 检索打开的目录中下一个匹配的对象 */ FRESULT f_findnext ( DIR* dp, /* [IN] Poninter to the directory object */ FILINFO* fno /* [OUT] Pointer to the file information structure */ );
f_closedir
/** * @brief The f_closedir function closes an open directory. * @note 关闭打开的目录 */ FRESULT f_closedir ( DIR* dp /* [IN] Pointer to the directory object */ // 指向要关闭的已打开的路径对象 );
5.4 文件访问
f_open
/** * @brief The f_open function opens a file. * @note 打开/创建文件 */ 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 */ )
f_expand
/** * @brief The f_expand function prepares or allocates a contiguous data area to the file. * @note 为文件分配一个连续的块 */ FRESULT f_expand ( FIL* fp, /* [IN] File object */ FSIZE_t fsz, /* [IN] File size expanded to */ BYTE opt /* [IN] Allocation mode. Prepare to allocate (0) or Allocate now (1) */ );
f_read
/** * @brief The f_read function reads data from a file. * @note 读取文件内容。从文件对象指针fp中读取btr个字节缓存到buff中,返回已读出的字节数br。 */ 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 */ )
f_write
/** * @brief The f_write writes data to a file * @note 将数据写入文件 */ FRESULT f_write ( FIL* fp, /* [IN] Pointer to the file object structure */ const void* buff, /* [IN] Pointer to the data to be written */ UINT btw, /* [IN] Number of bytes to write */ UINT* bw /* [OUT] Pointer to the variable to return number of bytes written */ );
f_lseek
/** * @brief The f_lseek function moves the file read/write pointer of an open file object. It can also be used to expand the file size (cluster pre-allocation). * @note 移动读/写指针,扩展大小 */ FRESULT f_lseek ( FIL* fp, /* [IN] File object */ FSIZE_t ofs /* [IN] Offset of file read/write pointer to be set */ ); FRESULT f_rewind ( FIL* fp /* [IN] File object */ );
f_truncate
/** * @brief The f_truncate function truncates the file size. * @note 截断文件大小 */ FRESULT f_truncate ( FIL* fp /* [IN] File object */ );
f_sync
/** * @brief The f_sync function flushes the cached information of a writing file. * @note 刷新缓存数据 */ FRESULT f_sync ( FIL* fp /* [IN] File object */ );
f_forward
/** * @brief The f_forward function reads the file data and forward it to the data streaming device. * @note 将数据转发到流 */ FRESULT f_forward ( FIL* fp, /* [IN] File object */ UINT (*func)(const BYTE*,UINT), /* [IN] Data streaming function */ UINT btf, /* [IN] Number of bytes to forward */ UINT* bf /* [OUT] Number of bytes forwarded */ );
f_gets
/** * @brief The f_gets reads a string from the file. * @note 读取字符串 */ TCHAR* f_gets ( TCHAR* buff, /* [OUT] Read buffer */ int len, /* [IN] Size of the read buffer */ FIL* fp /* [IN] File object */ );
f_putc
/** * @brief The f_putc funciton puts a character to the file. * @note 写入一个字符 */ int f_putc ( TCHAR chr, /* [IN] A character to write */ FIL* fp /* [IN] File object */ );
f_puts
/** * @brief The f_puts function writes a string to the file. * @note 写入一个字符串 */ int f_puts ( const TCHAR* str, /* [IN] String */ FIL* fp /* [IN] File object */ );
f_printf
/** * @brief The f_printf function writes formatted string to the file. * @note 写一个格式化的字符串 */ int f_printf ( FIL* fp, /* [IN] File object */ const TCHAR* fmt, /* [IN] Format stirng */ ... );
f_tell
/** * @brief The f_tell function gets the current read/write pointer of a file. * @note 获取当前读/写指针 */ FSIZE_t f_tell ( FIL* fp /* [IN] File object */ );
f_size
/** * @brief The f_tell function gets the current read/write pointer of a file. * @note 获取大小 */ FSIZE_t f_size ( FIL* fp /* [IN] File object */ );
f_eof
/** * @brief The f_eof function tests for end-of-file on a file. * @note 测试文件结尾(返回0表示未到文件尾) */ int f_eof ( FIL* fp /* [IN] File object */ );
f_error
/** * @brief The f_error tests for an error on a file. * @note 测试文件错误(返回0表示文件未发生错误) */ int f_error ( FIL* fp /* [IN] File object */ );
f_close
/** * @brief The f_close function closes an open file. * @note 关闭打开的文件(确保文件更改的所有信息缓存全部写回卷) */ FRESULT f_close ( FIL *fp /* Pointer to the file object to be closed */ )