IC:

概述

本节描述虚拟文件系统(VFS)的类型、使用场景、使用方法等信息。

VFS 底层实现包含 FatFS 与 LittleFS:

  • FatFS 的优势在于兼容性、跨平台支持、开发便捷性。

  • LittleFS 的优势在于掉电恢复、闪存寿命优化、低资源消耗。

用户可通过使用VFS忽略不同文件系统之间的使用差异,专注于开发需求。

VFS 提供了 fopen、fclose、fwrite、fread 等 通用文件操作接口键值对(KV)接口 基于通用文件操作实现。

VFS 的架构如下图所示:

../../_images/vfs_architecture_lite_dplus.svg

VFS 初始化

Flash 中的 VFS 存在两块独立的区域:

  • VFS1区域初始化为LittleFS

  • VFS2区域初始化为FatFS

VFS2默认不分配Flash空间,用户可以根据需要自行修改配置。

如果开启了 APP固件中的VFS 功能,VFS2初始化时会从应用固件末尾寻找并识别 Fatfs二进制文件

备注

  • VFS 挂载至 Flash 时,若挂载失败,会检测Flash是否处于空白状态(全0xFF)。若是,将执行 Flash 编程操作以初始化 VFS。

  • 为确保合理使用 FatFS,参考 配置 SDK (menuconfig) 进入 CONFIG VFS 配置,选择 Enable VFS FATFS 且勾选需要使能的功能模块。

VFS 用法

Flash中的VFS

如果需要适当调整 VFS 位置,可以参考 Flash布局修改,对 VFS1VFS2 区域进行调整。

备注

  • VFS1 区域必须存在,且其大小必须大等于 128KB。

  • 最多可配置两个 VFS 区域。

APP固件中的VFS

如果文件系统中的内容有升级的需求,比如语音方案中替换提示音和语音包,VFS 对此提供了更方便的配置功能。详细步骤如下:

  1. 准备只读文件并将其转换成 FAT 格式的二进制文件,具体方法请参考 FatFS 二进制文件

  2. 将生成的二进制文件命名为 fatfs.bin,并放置于 {SDK}\amebadplus_gcc_project 目录下。

  3. 参考 配置 SDK (menuconfig) 进入 CONFIG VFS 配置,选择 Enable VFS FATFSFATFS within APP Image

  4. 重新编译应用程序固件。

应用程序固件 (km0_km4_app.bin) 将包含一个 FAT 格式的只读 VFS 区域,该区域将在启动过程中自动挂载。

启动后,出现日志 VFS-FAT Init Success,即表明 FAT 文件系统已成功挂载。

后续需要更新 FAT 文件系统内容时,通过 OTA 的方式可以跟随固件一起更新。

关于文件使用方法,请参考 通用文件操作KV 操作

备注

为了优化该文件系统的有效空间利用率,目前仅支持 FAT 格式。

通用文件操作

VFS 中常用的通用文件操作接口如下所示:

API

参数

描述

fopen

  • const char * filename

  • const char * mode

以指定模式打开指定文件

fclose

  • FILE * stream

关闭文件流

fread

  • void * ptr

  • size_t size

  • size_t count

  • FILE * stream

从文件流中读取数据到指定缓冲区

fwrite

  • const void * ptr

  • size_t size

  • size_t count

  • FILE * stream

将缓冲区数据写入文件流

fseek

  • FILE * stream

  • long int offset

  • int origin

设置文件流的读写位置到指定偏移量

rewind

  • FILE * stream

将文件流的读写位置重置到文件开头

fgetpos

  • FILE * stream

  • fpos_t * p

获取当前文件流的读写位置并保存到指定的位置

fsetpos

  • FILE * stream

  • fpos_t * p

设置文件流的读写位置为指定的位置

fflush

  • FILE * stream

刷新文件流的输出缓冲区

remove

  • const char * filename

删除指定文件,使其不可访问

rename

  • const char * oldname

  • const char * newname

将文件从旧路径重命名为新路径

feof

  • FILE * stream

检测文件流是否已到达末尾

ferror

  • FILE * stream

检测文件流是否发生错误

ftell

  • FILE * stream

返回当前文件流的读写位置

ftruncate

  • FILE * stream

  • off_t length

将文件截断至指定长度

opendir

  • const char * name

打开目录

readdir

  • DIR * pdir

读取目录内容

closedir

  • DIR * dirp

关闭已打开的目录

rmdir

  • const char * path

删除空目录

mkdir

  • const char * pathname

  • mode_t mode

创建新目录

access

  • const char * pathname

  • int mode

检查文件的可访问性

stat

  • const char * path

  • struct stat * buf

获取文件元数据

用户可以参考 VFS示例 测试通用文件操作是如何工作的。测试日志应包含如下关键信息:

[example_vfs_thread] fwrite succeeded !!!
[example_vfs_thread] fread succeeded !!!
[example_vfs_thread] remove file succeeded !!!

备注

fseek 接口的返回值与标准接口不同。如果成功,将返回当前文件指针相对于文件开头的偏移量。

KV 操作

我们同时提供了简单的键值对(KV)接口,这些接口位于 kv.c

用户可以参考 KV示例 测试 KV 接口是如何工作的。测试日志应包含如下关键信息:

rt_kv_set success, write 28 letters.
rt_kv_get success, read 28 letters.
rt_kv_delett success.

备注

KV 接口的操作都在 VFS1 分区的文件系统 KV 目录中进行。key-value 中的 key 对应文件名,value 对应文件内容。

代码转换

FatFS 默认不支持 Unicode 与其他编码之间的转换。

修改 ffconf.h 文件中的宏 FF_CODE_PAGE 可开启代码转换功能,开发者需根据目标代码页编号配置 FF_CODE_PAGE

#define FF_CODE_PAGE  999
/* This option specifies the OEM code page to be used on the target system.
/  Incorrect code page setting can cause a file open failure.
/   437 - U.S.
/   720 - Arabic
/   737 - Greek
/   771 - KBL
/   775 - Baltic
/   850 - Latin 1
/   852 - Latin 2
/   855 - Cyrillic
/   857 - Turkish
/   860 - Portuguese
/   861 - Icelandic
/   862 - Hebrew
/   863 - Canadian French
/   864 - Arabic
/   865 - Nordic
/   866 - Russian
/   869 - Greek 2
/   932 - Japanese (DBCS)
/   936 - Simplified Chinese (DBCS)
/   949 - Korean (DBCS)
/   950 - Traditional Chinese (DBCS)
/   999 - Realtek defined for code size
/     0 - Include all code pages above and configured by f_setcp()
*/

VFS 加密

对于特殊的存储安全需求,用户可通过配置 VFS 的加解密功能实现数据保护。

该功能需要用户参考 VFS加解密示例 提前准备加解密函数和密钥。

正确运行示例程序后,测试日志应包含如下关键信息:

[example_vfs_encrypt_thread] fwrite succeeded !!!
[example_vfs_encrypt_thread] fread succeeded !!!
[example_vfs_encrypt_thread] remove file succeeded !!!

备注

当启用 VFS 加密功能时,系统会对明文数据进行填充处理,这将导致额外的存储空间开销。

VFS 二进制文件生成

若需预先将数据存放至 Flash 中,可在 PC 端生成 VFS 二进制文件。生成完成后,需根据 Flash 布局将二进制文件下载至 VFS 区域。

LittleFS 二进制文件

  1. 在生成 LittleFS 二进制文件前,需准备一个包含所需文件的目录。例如:

    root:~$ ls -R test
    test:
    AUDIO KV
    
    test/AUDIO
    audio_test.mp3
    
    test/KV
    kv_test.txt
    

    在 Flash 中, AUDIOKV 目录作为 LittleFS 目录, test 则相当于文件系统的根目录。

  2. 通过 vfs.py,使用以下命令生成 LittleFS 二进制文件:

    $vfs.py -t LITTLEFS -s 4096 -c 32 -dir test -out image_littlefs.bin
    

    参数说明:

    • -s:块大小

    • -c:块数量

    • -dir:目标目录

    • -out:输出二进制文件名

    root:~$ vfs.py -t LITTLEFS -s 4096 -c 32 -dir test -out image_littlefs.bin
    image_littlefs.bin has been successfully generated.
    args:
    ├─ type: LITTLEFS
    ├─ block_size: 4096
    ├─ block_count: 32
    ├─ image_size: 131072
    ├─ source_directory: test
    └─ output_image: image_littlefs.bin
    

    备注

    • -s 4096 为LittleFS默认配置,用户需根据 littlefs_adapter.c 文件中的 lfs_config 中的 block_size 进行适配。

    • -c 32 应根据 Flash中的VFS 中提到的 VFS 区域大小来设置。VFS 区域大小等于块大小乘以块数量。

  3. 下载固件至 Flash 中。

    参考 固件下载 将二进制文件下载至 Flash 中。Image Tool 的起始地址应为 Flash中的VFS 中提到的 VFS Flash 区域的 StartAddr,结束地址应为 EndAddr + 1

FatFS 二进制文件

  1. 在生成 FatFS 二进制文件前,需准备一个包含所需文件的目录。例如:

    root:~$ ls -R test
    test:
    AUDIO KV
    
    test/AUDIO
    audio_test.mp3
    
    test/KV
    kv_test.txt
    

    在 Flash 中, AUDIOKV 目录作为 FatFS 目录, test 则相当于文件系统的根目录。

  2. 通过 vfs.py,使用以下命令生成 FatFS 二进制文件:

    $vfs.py -t FatFS -s 512 -c 256 -dir test -out image_fatfs.bin
    

    参数说明:

    • -s:扇区大小

    • -c:扇区数量

    • -dir:目标目录

    • -out:输出二进制文件名

    root:~$ vfs.py -t FATFS -s 512 -c 256 -dir test -out image_fatfs.bin
    image_fatfs.bin has been successfully generated.
    args:
    ├─ type: FATFS
    ├─ sector_size: 512
    ├─ sector_count: 256
    ├─ image_size: 131072
    ├─ source_directory: test
    └─ output_image: image_fatfs.bin
    

    备注

    • -s 512 为FatFS默认配置,此参数可省略。

    • -c 256 应根据 Flash中的VFS 中提到的 VFS 区域大小来设置。VFS 区域大小等于扇区大小乘以扇区数量。

  3. 下载固件至 Flash 中。

    参考 固件下载 将二进制文件下载至 Flash 中。Image Tool 的起始地址应为 Flash中的VFS 中提到的 VFS Flash 区域的 StartAddr,结束地址应为 EndAddr + 1