5. fat文件系统

FatFs是一个通用的文件系统,在本机中,支持对FAT12/16/32、exFAT文件系统进行读写操作;
FAT文件系统能使用的接口如图1.3所示:
"fat文件系统支持的接口"

图1.3 fat文件系统支持的接口

5.1. FAT文件系统管理函数

下面的函数为仅FAT使用的接口,在appbspcommonfsfatfat_resource.c中的fat_demo()接口,可以找到下列函数的使用示例;

5.1.1. 函数int fs_ftell(void *pvfile, void *parm)

此函数实现获取文件读写指针,仅FAT可使用该功能。其中参数:

1、pvfile:已打开的文件句柄;
2、param:用于保存文件系统读写指针;
3、返回值:
    成功 0;
    失败 错误请查看errno-base.h。

5.1.2. 函数int vfs_get_fsize(void *pvfile, void *parm)

此函数实现获取文件大小,仅FAT可使用该功能。其中参数:

1、pvfile:已打开的文件句柄;
2、param:用于保存文件大小的指针;
3、返回值:
    成功 0;
    失败 错误请查看errno-base.h。

5.1.3. 函数struct vfscan *vfs_fscan_new(void *pvfs, const char *path, const char *arg, u8 max_deepth, int (*callback)(void), strcut vfscan *fsn, struct vfscan_reset_info *info)

此函数实现FAT文件系统的文件扫描配置,会返回文件扫描句柄供其他扫描接口使用,与vfs_fscan_release()搭配调用,可在ac104n sdk中的play_file.c中查看该函数具体使用示例。其中参数:

1、pvfs:已挂载的文件系统句柄;
2、path:文件扫描的起始路径;
3、arg:文件扫描配置参数;
    例:static const char scan_parm_test[] = “-t”
                                            “MP1MP2MP3WAVTXT”
                                            “ -sn -r”
                                            ;
    ① 首行”-t”表示需要扫描的文件类型,后面”MP1MP2MP3WAVTXT”即为扫描的后缀名,三个字符为一种类型,最多不可超过20种文件类型;
    ② 第三行” -sn”表示扫描文件的顺序是按照文件号排序,另一种组合” -st”表示按照时间排序;
    ③ 第三行” -r”表示搜索会包含文件夹子目录;
    ④ 各种扫描参数配置间,需要以空格隔开,其他配置有:
        a)扫描是否将文件夹算入总数,可配置” -d”;
        b)扫描只读文件配置” -ar”,扫描非读文件配置” -a/r”,不配置默认扫描所有文件;
4、max_deep:扫描深度,最大为8;
5、callback:扫描回调;
6、fsn:文件扫描句柄;
7、info:扫描结果信息,包含文件总数和文件夹总数等信息;
8、返回值:
    成功 返回文件扫描句柄;
    失败 错误请查看errno-base.h。

5.1.4. 函数void fs_fscan_release(void *pvfs, struct vfscan *fs)

此函数实现释放文件扫描句柄,仅FAT可使用该功能,与vfs_fscan()搭配调用。其中参数:

1、pvfs:已挂载的文件系统句柄;
2、fs:文件扫描句柄;
3、返回值:无。

5.1.5. 函数int fs_get_folderinfo(void **pvfile, struct vfscan *fs, int *start_num, int *end_num)

此函数实现文件夹扫描,需使用vfs_fscan()返回的文件扫描句柄,仅FAT可使用该功能。其中参数:

1、pvfile:需要扫描的设备里的文件;
2、fs:文件扫描句柄;
3、Start_num:用于保存第一个文件夹的第一个文件号;
4、End_num:用于保存最后一个文件夹的最后一个文件号;
5、返回值:
    成功 0;
    失败 错误请查看errno-base.h。

5.1.6. 函数int fs_get_encfolder_info(void *pvfs, char *folder, char *ext, u32 *last_num, u32 *total_num)

此函数实现获取录音文件夹信息,包括录音文件总数,仅FAT可使用该功能。其中参数:

1、pvfs:已挂载的文件系统句柄;
2、folder:文件夹路径,如”/JL_REC”;
3、ext:录音文件的后缀名,如”MP3”;
4、last_num:第一个可以使用的录音文件的文件序号;
5、total_num:总录音文件数;
6、返回值:
    成功 0;
    失败 错误请查看errno-base.h。

5.1.7. 函数u32 vfs_file_name(void *pvfile, void *name, u32 len)

此函数实现获取文件的名字。
该函数在获取文件名小于16byte(带后缀名)时,返回的为u8字符;
在获取大于16byte(带后缀名)时,返回的是unicode码,且不会返回完整的文件名。
具体需要获取文件长名并最终转化为u8字符进行打印出来,可参考该issue步骤:
1、pvfile:已打开的文件句柄;
2、name:获取文件名指针。
3、len:获取文件名长度。
4、返回值:文件名长度;

5.1.8. 函数int fs_select(void *pvfs, void **ppvfile, struct vfscan *fs, int sel_mode, int arg)

此函数实现FAT文件系统的文件查找,支持多种查找方式,具体示例可查看fat_demo(void)接口。其中参数:

1、pvfs:已挂载的文件系统句柄;
2、ppvfile:文件句柄指针,若句柄指向为NULL,函数会自行申请空间;
3、fs:文件扫描句柄;
4、sel_mode:文件查找方式:
    ① FSEL_BY_NUMBER:按文件号查找;
    ② FSEL_BY_SCLUST:按簇号查找;
    ③ FSEL_BY_PATH:按路径查找;
5、arg:文件查找参数;
    ① 按文件号查找时传入文件号;
    ② 按簇号查找时传入簇号;
    ③ 按路径查找时传入相应路径,支持通配符查找;
6、返回值:
    成功 0;
    失败 错误请查看errno-base.h。

5.1.9. 函数int vfs_mk_dir(void *pvfs, char *folder, u8 mode)

此函数实现获取创建文件夹,仅FAT可使用该功能。其中参数:

1、pvfs:已挂载的文件系统句柄;
2、folder:文件夹路径,如”/JL_REC”;
3、mode:目录属性;
    1:设置为隐藏属性;
    0:不设置;
4、返回值:
    成功 0;
    失败 错误请查看errno-base.h。

5.1.10. 函数int vfs_delete_dir(void *pvfs, char *path)

此函数实现获取删除文件夹,仅FAT可使用该功能。其中参数:

1、pvfs:已挂载的文件系统句柄;
2、path:文件夹路径,如”/JL_REC”;
3、返回值:
    成功 0;
    失败 错误请查看errno-base.h。

使用demo:

log_info("vfs_delete_dir\n");
err = vfs_delete_dir(pvfs, "/test_dir/adir");
if (err != 0) {
        log_error("vfs_delet_dir 0x%x\n", err);
        goto __vfs_delete_fs_close;
}

5.1.11. 函数int vfs_get_encfolder_info(void *pvfs, char *folder, char *ext, u32 *last_num, u32 *total_num)

此函数实现获取录音文件夹信息,包括录音文件总数,仅FAT可使用该功能。其中参数:

1、pvfs:已挂载的文件系统句柄;
2、folder:文件夹路径,如”/JL_REC”;
3、ext:录音文件的后缀名,如”MP3”;
4、last_num:第一个可以使用的录音文件的文件序号;
5、total_num:总录音文件数;
6、返回值:
    成功 0;
    失败 错误请查看errno-base.h。

5.1.12. 函数u32 vfs_file_delete(void *pvfile)

此函数实现文件的删除,仅FAT可使用该功能。其中参数:

1、pvfile:已打开的文件句柄;
2、返回值:
    成功 0;
    失败 错误请查看errno-base.h。

5.1.13. 函数int vfs_select(void *pvfs, void **ppvfile, struct vfscan *fs, int sel_mode, int arg)

此函数实现FAT文件系统的文件查找,支持多种查找方式,具体示例可查看fat_demo(void)接口。其中参数:

1、pvfs:已挂载的文件系统句柄;
2、ppvfile:文件句柄指针,若句柄指向为NULL,函数会自行申请空间;
3、fs:文件扫描句柄;
4、sel_mode:文件查找方式:
    ① FSEL_BY_NUMBER:按文件号查找;
    ② FSEL_BY_SCLUST:按簇号查找;
    ③ FSEL_BY_PATH:按路径查找;
5、arg:文件查找参数;
    ① 按文件号查找时传入文件号;
    ② 按簇号查找时传入簇号;
    ③ 按路径查找时传入相应路径,支持通配符查找;
6、返回值:
    成功 0;
    失败 错误请查看errno-base.h。

5.1.14. 函数int vfs_format(void **ppvfs, const char *dev_name, const char *type, u32 clust_size, u8 create_new)

此函数实现FAT文件系统格式化。 其中参数:

1、ppvfs:已挂载的文件系统句柄;
2、dev_name:目标设备;
3、type:格式化后的文件系统;
4、clust_size:格式化后文件系统的簇大小,单位为k
5、create_new:设置为1为格式化成新的文件系统是由内部格式化接口自行判断当前设备容量适合哪种fat文件系统。
6、返回值:成功为0;有值为失败

使用demo:

ret = vfs_format(&format_pfs, "udisk0", "fat", 64 * 1024, 1);   //格式化u盘成fat文件系统,簇大小为64*1024k
ret = vfs_format(&format_pfs, "ext_flsh", "fat", 64 * 1024, 1); //格式化外挂flash成fat文件系统,簇大小为64*1024k
ret = vfs_format(&format_pfs, "ext_flsh", "fat", 512, 1);       //格式化外挂flash成fat文件系统,簇大小为512k

备注

1、若ppvfs指针为空,则create_new参数不能传0;
2、格式化前最好先mount一下目标设备是否里面存在文件系统再去格式化。
3、格式化成功后,如需继续使用该设备,需要再重新mount;

5.1.15. 函数int vfs_ioctl(void *pfile, int cmd, int arg)

fat文件系统支持多种命令操作,CMD命令如下:
  1. 创建文件夹 FS_IOCTL_MK_DIR

  2. 获取文件夹序号和文件夹内文件数目 FS_IOCTL_GET_FOLDER_INFO_3

  3. 获取录音文件信息 FS_IOCTL_GET_ENCFOLDER_INFO

  4. 重置扫描句柄 FS_IOCTL_RESET_VFSCAN

  5. 设置卷标 FS_IOCTL_SET_VOL

  6. 获取分区信息,簇大小,容量 FS_IOCTL_GET_PARTITION_INFO

  7. 获取剩余空间 FS_IOCTL_GET_FREE_SPACE

  8. 获取当前文件的相对路径和绝对路径 FS_IOCTL_GET_PATH

获取获取当前文件的相对路径和绝对路径demo:

len = vfs_fget_path(pfile, fsn, (u8 *)name, sizeof(name), 0);    //获取绝对路径
len = vfs_fget_path(pfile, fsn, (u8 *)name, sizeof(name), 1);    //获取相对路径
/*如果路径里的文件夹大于16byte,获取出来的是Unicode码,小于16byte的则为utf8*/
/*返回值为路径长度,name即为获取的路径*/

获取剩余空间demo:

u32 cap = 0;
res = vfs_ioctl(pvfs, (int)FS_IOCTL_GET_FREE_SPACE, (int)&cap);
log_info("cap 0x%x\n",res,cap);     //cap为获取到fat文件系统的剩余容量,单位为k

获取分区信息,簇大小,容量demo:

u32 res = 0;
FS_PARTITION_INFO part_info = {0};
res = vfs_ioctl(pvfs, (int)FS_IOCTL_GET_PARTITION_INFO, (int)&part_info);
log_info("0x%x 0x%x 0x%x \n",part_info.clust_size,part_info.total_size, part_info.fs_type);
/*分别对应簇大小,文件系统总容量大小,文件系统类型*/