ℹ️ 本篇文章没有说明实现方法,仅是简单介绍了 FatFs 的部分函数和结构体定义。
FatFs API 应用程序接口
▶️ 根据 FatFS 的教程手册来看,将程序接口分为了四个部分。
- 文件访问
- 目录访问
- 文件和目录管理
- 卷管理和系统配置
1️⃣ 文件访问
名称 | 简介 |
---|---|
f_open | 打开/创建文件 |
f_close | 关闭已打开的文件 |
f_read | 从文件中读取数据 |
f_write | 将数据写入文件 |
f_lseek | 移动读/写指针,扩展大小 |
f_truncate | 截断文件大小 |
f_sync | 刷新缓存数据 |
f_forward | 为数据转发到流 |
f_expand | 为文件分配连续的块 |
f_gets | 读取字符串 |
f_putc | 写一个字符 |
f_puts | 编写字符串 |
f_printf | 编写格式化字符串 |
f_tell | 获取当前读/写指针 |
f_eof | 文件结尾测试 |
f_size | 获取大小 |
f_error | 测试错误 |
2️⃣ 目录访问
名称 | 简介 |
---|---|
f_opendir | 打开目录 |
f_closedir | 关闭打开的目录 |
f_readdir | 读取目录项 |
f_findfirst | 打开目录并读取匹配的第一个项目 |
f_findnext | 读取下一个匹配的项目 |
3️⃣ 文件和目录管理
名称 | 简介 |
---|---|
f_stat | 检查文件或子目录是否存在 |
f_unlink | 删除文件或子目录 |
f_rename | 重命名/移动文件或子目录 |
f_chmod | 更改文件或子目录的属性 |
f_utime | 更改文件或子目录的时间戳 |
f_mkdir | 创建子目录 |
f_chdir | 更改当前目录 |
f_chdrive | 更改当前驱动器 |
f_getcwd | 检索当前目录和驱动器 |
4️⃣ 卷管理和系统配置
名称 | 简介 |
---|---|
f_mount | 注册/注销卷的工作区域 |
f_mkfs | 在逻辑驱动器上创建 FAT 卷 |
f_fdisk | 在物理驱动器上创建分区 |
f_getfree | 获取卷上的可用空间 |
f_getlabel | 获取卷标 |
f_setlabel | 设置卷标 |
f_setcp | 设置活动代码页 |
介绍部分的函数
因为计划用 STM32 做一个音乐播放器,故只做部分函数介绍。
只需要读取文件,没有任何写、修改等文件操作!
挂载设备 f_mount
FRESULT f_mount (
FATFS* fs, /* [IN] 文件系统对象 */
const TCHAR* path, /* [IN] 逻辑驱动器号 */
BYTE opt /* [IN] 安装选项0/1 */
);
FRESULT f_unmount (
const TCHAR* path /* [IN] 逻辑驱动器号 */
);
打开目录 f_opendir
FRESULT f_opendir (
DIR* dp, /* [OUT] 指向目录对象结构的指针 */
const TCHAR* path /* [IN] 目录名称 */
);
读取目录文件 f_readdir
FRESULT f_readdir (
DIR* dp, /* [IN] 目录对象 */
FILINFO* fno /* [OUT] 文件信息结构 */
);
FRESULT f_rewinddir (
DIR* dp /* [IN] 目录对象 */
);
打开文件 f_open
FRESULT f_open (
FIL* fp, /* [OUT] 指向文件对象结构的指针 */
const TCHAR* path, /* [IN] 文件名 */
BYTE mode /* [IN] 模式标签 */
);
标签 | 意义 |
---|---|
FA_READ | 读取 |
FA_WRITE | 写入 |
FA_OPEN_EXISTING | 仅打开,若没有则返回错误 |
FA_CREATE_NEW | 仅创建,若有则不覆盖,返回错误 |
FA_CREATE_ALWAYS | 创建文件,若有同名文件,则覆盖 |
FA_OPEN_ALWAYS | 打开文件,没有则创建 |
FA_OPEN_APPEND | 与FA_OPEN_ALWAYS相同,只是读/写指针设置在文件末尾。 |
基本仅用到 FA_READ。
从文件读取数据 f_read
FRESULT f_read (
FIL* fp, /* [IN] 文件对象 */
void* buff, /* [OUT] 数据缓冲区 */
UINT btr, /* [IN] 读取的字节数 */
UINT* br /* [OUT] 指向接收读取字节数的 UINT 变量的指针 */
);
该函数开始在读/写指针指向的文件偏移处从文件中读取数据。读/写指针随着读取的字节数而前进。函数成功后,应检查 *br 以检测文件的末尾。如果 *br < btr,则表示读/写指针在读取操作期间到达文件末尾。
关闭打开的文件 f_close
FRESULT f_close (
FIL* fp /* [IN] 指向文件对象的指针 */
);
函数小结
到这里,基本读文件的操作就完成了!其实不难,做MP3只需要用到:
- 打开目录
- 读目录文件(可检查音频文件,可显示音乐列表)
- 打开文件
- 读取文件(解析文件以便于播放!)
- 关闭文件
结构体、参数定义
文件函数返回码
/* 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 parameter error */
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 > _FS_SHARE */
FR_INVALID_PARAMETER /* (19) Given parameter is invalid */
} FRESULT;
中文翻译,仅供参考
typedef enum {
FR_OK = 0, /* (0) 成功 */
FR_DISK_ERR, /* (1) 低级别磁盘I/O层中发生了一个硬盘错误 */
FR_INT_ERR, /* (2) 断言失败 */
FR_NOT_READY, /* (3) 物理驱动器无法工作 */
FR_NO_FILE, /* (4) 找不到该文件 */
FR_NO_PATH, /* (5) 找不到路径 */
FR_INVALID_NAME, /* (6) 路径名格式无效 */
FR_DENIED, /* (7) 由于禁止访问或目录已满而拒绝访问 */
FR_EXIST, /* (8) 由于禁止访问而拒绝访问 */
FR_INVALID_OBJECT, /* (9) 文件/目录对象无效 */
FR_WRITE_PROTECTED, /* (10) 物理驱动器受写保护 */
FR_INVALID_DRIVE, /* (11) 逻辑驱动器号无效 */
FR_NOT_ENABLED, /* (12) 卷没有工作区 */
FR_NO_FILESYSTEM, /* (13) 没有有效的FAT卷 */
FR_MKFS_ABORTED, /* (14) The f_mkfs()因任何参数错误中止 */
FR_TIMEOUT, /* (15) 无法在定义的时间段内获得访问卷的授权 */
FR_LOCKED, /* (16) 根据文件共享策略拒绝操作 */
FR_NOT_ENOUGH_CORE, /* (17) 无法分配LFN工作缓冲区 */
FR_TOO_MANY_OPEN_FILES, /* (18) 打开的文件数 > _FS_SHARE */
FR_INVALID_PARAMETER /* (19) 给定参数无效 */
} FRESULT;
目录对象结构
/* Directory object structure (DIR) */
typedef struct {
FFOBJID obj; /* Object identifier */
DWORD dptr; /* Current read/write offset */
DWORD clust; /* Current cluster */
LBA_t sect; /* Current sector (0:Read operation has terminated) */
BYTE* dir; /* Pointer to the directory item in the win[] */
BYTE fn[12]; /* SFN (in/out) {body[8],ext[3],status[1]} */
#if FF_USE_LFN
DWORD blk_ofs; /* Offset of current entry block being processed (0xFFFFFFFF:Invalid) */
#endif
#if FF_USE_FIND
const TCHAR* pat; /* Pointer to the name matching pattern */
#endif
} DIR;
中文翻译,仅供参考
typedef struct {
FFOBJID obj; /* 对象标识符 */
DWORD dptr; /* 当前读/写偏移量 */
DWORD clust; /* 当前群集 */
LBA_t sect; /* 当前扇区(0:读取操作已终止) */
BYTE* dir; /* 指向win[]中目录项的指针 */
BYTE fn[12]; /* SFN(输入/输出){正文[8],分机[3],状态[1]} */
#if FF_USE_LFN
DWORD blk_ofs; /* 正在处理的当前条目块的偏移量(0xFFFFFFFF:无效) */
#endif
#if FF_USE_FIND
const TCHAR* pat; /* 指向名称匹配模式的指针 */
#endif
} DIR;
文件信息结构
/* File information structure (FILINFO) */
typedef struct {
FSIZE_t fsize; /* File size */
WORD fdate; /* Modified date */
WORD ftime; /* Modified time */
BYTE fattrib; /* File attribute */
#if FF_USE_LFN
TCHAR altname[FF_SFN_BUF + 1];/* Altenative file name */
TCHAR fname[FF_LFN_BUF + 1]; /* Primary file name */
#else
TCHAR fname[12 + 1]; /* File name */
#endif
} FILINFO;
中文翻译,仅供参考
typedef struct {
FSIZE_t fsize; /* 文件大小 */
WORD fdate; /* 修改日期 */
WORD ftime; /* 修改时间* */
BYTE fattrib; /* 文件属性 */
#if FF_USE_LFN
TCHAR altname[FF_SFN_BUF + 1];/* 可选文件名 */
TCHAR fname[FF_LFN_BUF + 1]; /* 主文件名 */
#else
TCHAR fname[12 + 1]; /* 文件名 */
#endif
} FILINFO;
FatFs 版本更新后这些结构也有些许变化!!
小结
只分析关于 STM32 播放 MP3 文件相关的代码,其他的并没有介绍。
嗯,今天状态不是很好!就到这吧 ~