2. 文件系统管理

AD16N FLASH方案 和 AW30N mbox_flash方案 支持只读sydfs、录音读写norfs以及fatfs文件系统;
OTP方案只支持只读fatfs文件系统,且不使用vfs文件系统管理,直接调用fat文件系统接口,可节约代码空间;
文件系统涉及的文件:
1、apps/app/bsp/common/fs目录下的所有c文件;
2、include_lib/fs目录下的所有头文件
3、errno-base.h文件。

支持的文件系统列表:

文件系统

OTP方案

flash方案

详情

sydfs

不支持

支持

只读文件系统,用于存放资源文件到norflash;

norfs

不支持

支持

循环覆盖文件系统,可读写;针对norflash设计;

simple_fat

简单fat文件系统驱动,占用资源少,不支持搜索;支持FAT12/16/32, EXFAT;

fatfs

支持

支持

完整的fat文件系统驱动,占用资源多,支持搜索;支持FAT12/16/32, EXFAT;

fs有以下主要函数:

void fs_init(void);
u32 fs_mount(void **ppvfs, void *device, void *type);
u32 fs_openbypath(void *pvfs, void **ppvfile, const char *path);
int fs_select(void *pvfs, void **ppvfile, struct vfscan *fs, int sel_mode, int arg);
u32 fs_read(void *pvfile, void *buf, u32 len);
u32 fs_seek(void *pvfile, u32 offset, u32 mode);
u32 fs_file_close(void **ppvfile);
u32 fs_fs_close(void **ppvfs);
u32 fs_file_name(void *pvfile, void *name, u32 len);
int fs_get_attrs(void *pvfile, void *pvfs_attr);
int fs_ioctl(void *pvfile, int cmd, int arg);
int fs_ftell(void *pvfile, void *parm);
int fs_get_fsize(void *pvfile, void *parm);
struct vfscan *fs_fscan_new(void *pvfs, const char *path, const char *arg, u8 max_deepth, int (*callback)(void), struct vfscan *fsn, struct vfscan_reset_info *info);
int fs_fscan_release(void *pvfs, struct vfscan *fs);
int vs_get_folderinfo(void **pvfile, struct vfscan *fs, int *start_num, int *end_num);
int fs_get_encfolder_info(void *pvfs, char *folder, char *ext, u32 *last_num, u32 *total_num);

2.1. 文件系统介绍

SDK中支持的文件系统有:只读sydfs、录音读写norfs以及fatfs;可以在app/bsp/fs目录下查看各文件系统的文件以及支持的接口;
本小节将介绍适用于各个文件系统的使用流程和相关接口。

2.2. 文件系统使用一般流程

如图,fs运行大致流程如下;

"fs 运行大致流程"

图2.1 fs 运行大致流程

通用的文件系统使用流程

1、文件系统初始化:
    调用函数void fs_init(void),完成对所有文件系统驱动的初始化;

2、mount挂载:
    调用u32 fs_mount(void **ppvfs, void *device, void *type),传递指定设备句柄,并完成对具体文件系统的挂载,并获取文件系统的句柄;

3、打开文件:
    调用u32 fs_openbypath(void *pvfs, void **ppvfile, const char *path)或u32 fs_select(void *fsn, void *pfs, int sel_mode, void **ppfile, int arg)打开文件,并获取文件句柄;

4、读取文件数据:
    调用u32 fs_read(void *pvfile, void *buf, u32 len)对文件进行读操作;

5、对文件进行不同的命令操作:
    调用int fs_ioctl(void *pvfile, int cmd, int arg)使用不同的命令进行不同的操作,如获取文件号、获取文件总数、获取文件地址、获取文件名字等;

6、关闭文件:
    调用u32 fs_file_close(void **ppvfile)关闭文件,并释放文件句柄。

7、关闭文件系统:
    调用u32 fs_fs_close(void **ppvfs)关闭文件系统,并释放文件系统句柄。

可以通过调用接口得到的返回值查看是否调用成功,以及失败的原因;失败原因可在include_lib/common/errno-base.h中查看。

2.3. 通用文件系统管理函数

该小节介绍适用于各个文件系统的接口。

2.3.1. 函数void fs_init(void)

此函数实现对所有文件系统驱动的初始化;在开机调用一次即可。


2.3.2. 函数u32 fs_mount(void **ppvfs, void *device, void *type)

此函数实现对指定设备挂在指定类型的文件系统,所挂载的系统必须设备自身支持;其中参数:

1、ppvfs:文件系统句柄指针,若句柄指向为NULL,函数会自行申请空间;
2、device:设备句柄;
3、type:文件系统类型的字符串;
    ① “sydfs”:挂载sydfs文件系统;
    ② “norfs”:挂载norfs文件系统;
    ③ “fat”:挂载fatfs文件系统;
    ④ “NULL”:将在现有的文件系统,轮询哪个文件系统可以使用(除去norfs文件系统),默认即使用syd文件系统;
4、返回值:
    成功 0;
    失败 错误请查看errno-base.h。
示例1:
    void *device = device_open(SD0_INDEX);//获取SD卡设备句柄
    void *pfs = NULL;
    u32 err = fs_mount(&pfs, device, “fat”); //SD卡挂载fatfs系统
    if (pfs != NULL && err == 0) {
        //SD卡挂载fatfs成功
    }
示例2:
    void *device = device_open(UDISK_INDEX);//获取U盘卡设备句柄
    void *pfs = NULL;
    u32 err = vfs_mount(&pfs, device, “fat”); //U盘挂载fatfs系统
    if (pfs != NULL && err == 0) {
        //U盘挂载fatfs成功
    }

2.3.3. 函数u32 fs_openbypath(void *pvfs, void **ppvfile, const char *path)

此函数实现打开指定路径的文件,其中参数:

1、pvfs:已挂载的文件系统句柄;
2、ppvfile:文件句柄指针,若句柄指向为NULL,函数会自行申请空间;
3、path:路径字符串;
    ① 如果字符串只是包含文件夹名,那么会打开文件夹;
    ② 如果字符串里面包含了完整的文件名,那么会打开对应的文件;
    ③ 如果字符串为空,则返回错误;
4、返回值:成功 0;
        失败 错误请查看errno-base.h。
示例:
    void *pfile = NULL;
    u32 err = vfs_openbypath(pfs, &pfile, “dir_song/so001.f1a”);
    if (pfile != NULL && err == 0) {
        //成功打开dir_song文件夹里的so001.f1a文件
    }

2.3.4. 函数u32 fs_read(void *pvfile, void *buf, u32 len)

此函数实现对指定文件的读操作。其中参数:

1、pvfile:已打开的文件句柄;
2、buf:用来获取数据的buff;
3、len:需要读取的字节长度;
4、返回值:
    成功 读取的字节数;
    失败 0。
示例:
    u8 read_buf[32];
    u32 read_len = fs_read(pfile, (void *)read_buf, 32);
    if (read_len != 0) {
        //成功读取pfile中read_len长度的数据到read_buf里
    }

2.3.5. 函数u32 fs_seek(void *pvfile, u32 offset, u32 mode)

此函数实现改变指定文件中读写指针的偏移。其中参数:

1、pvfile:已打开的文件句柄;
2、offset:偏移量;
3、mode:seek模式选择。如图3.1,seek模式有3种,分别为:
    ① SEEK_SET:从文件起始位置开始向后偏移,首先会判断偏移量是否大于文件长度,若小于则使文件读写指针rw_p = offset;
    ② SEEK_CIR:从文件读写指针位置开始向后偏移,使rw_p = rw_p + offset;
    ③ SEEK_END:从文件末尾位置向前偏移,首先会判断偏移量是否大于文件长度,若小于则使rw_p = 文件长度 - offset;
4、返回值:0。
"fs seek"

图3.1 seek模式选择


2.3.6. 函数u32 fs_file_close(void **ppvfile)

此函数实现关闭文件并释放句柄。其中参数:

1、ppvfile:已打开的文件句柄指针;
2、返回值:0。
示例:
    vfs_file_close(&pfile);
    if (pfile == NULL) {
        //成功关闭pfile文件
    }

2.3.7. 函数u32 fs_fs_close(void **ppvfs)

此函数实现关闭文件系统并释放相关句柄。其中参数:

1、ppvfs:已挂载的文件系统句柄指针;
2、返回值:NULL。
示例:
    fs_fs_close(&pfs);
    if (pfs == NULL) {
    //成功关闭pfs文件系统
    }

2.3.8. 函数u32 fs_file_name(void *pvfile, void *name, u32 len)

此函数实现获取指定文件的文件名。其中参数:

1、pvfile:已打开的文件句柄;
2、name:存放文件名的buf;
3、len:获取文件名的长度;
4、返回值:成功 返回获取文件名的长度;

备注

sydfs 和 norfs 文件系统文件名只支持小于16个byte(包含后缀名) fatfs小于等于16byte为短名,默认支持;大于16byte为长名,需要打开长名功能(详情请看);


2.3.9. 函数int fs_get_attrs(void *pvfile, void *pvfs_attr)

此函数实现获取文件的相关属性,包括文件大小和地址,nor_fs无法使用此功能。其中参数:

1、pvfile:已打开的文件句柄;
2、pvfs_attr:文件系统属性,需要传入vfs_attr结构体类型的指针;
3、返回值:0。
示例:
    struct vfs_attr file_attr;
    fs_get_attrs(pfile, &file_attr);
        //文件的flash地址和大小分别保存在file_attr.sclust和file_attr.fsize中

2.3.10. 函数int fs_ioctl(void *pvfile, int cmd, int arg)

此函数实现对指定文件的相关操作,各文件系统具体的cmd命令请查看《1文件系统介绍》小节。其中参数:

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