概述
本节描述虚拟文件系统(VFS)的类型、使用场景、使用方法等信息。
VFS 底层实现包含 FatFS 与 LittleFS:
FatFS 的优势在于兼容性、跨平台支持、开发便捷性。
LittleFS 的优势在于掉电恢复、闪存寿命优化、低资源消耗。
用户可通过使用VFS忽略不同文件系统之间的使用差异,专注于开发需求。
VFS 提供了 fopen、fclose、fwrite、fread 等 通用文件操作接口,键值对(KV)接口 基于通用文件操作实现。
VFS 的架构如下图所示:
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布局修改,对 VFS1 或 VFS2 区域进行调整。
备注
VFS1 区域必须存在,且其大小必须大等于 128KB。
最多可配置两个 VFS 区域。
APP固件中的VFS
如果文件系统中的内容有升级的需求,比如语音方案中替换提示音和语音包,VFS 对此提供了更方便的配置功能。详细步骤如下:
准备只读文件并将其转换成 FAT 格式的二进制文件,具体方法请参考 FatFS 二进制文件。
将生成的二进制文件命名为
fatfs.bin
,并放置于{SDK}\amebadplus_gcc_project
目录下。参考 配置 SDK (menuconfig) 进入
CONFIG VFS
配置,选择Enable VFS FATFS
和FATFS within APP Image
。重新编译应用程序固件。
应用程序固件 (km0_km4_app.bin
) 将包含一个 FAT 格式的只读 VFS 区域,该区域将在启动过程中自动挂载。
准备只读文件并将其转换成 FAT 格式的二进制文件,具体方法请参考 FatFS 二进制文件。
将生成的二进制文件命名为
fatfs.bin
,并放置于{SDK}\amebalite_gcc_project
目录下。参考 配置 SDK (menuconfig) 进入
CONFIG VFS
配置,选择Enable VFS FATFS
和FATFS within APP Image
。重新编译应用程序固件。
应用程序固件 (kr4_km4_app.bin
) 包含一个 FAT 格式的只读 VFS 区域,该区域将在启动过程中自动挂载。
准备只读文件并将其转换成 FAT 格式的二进制文件,具体方法请参考 FatFS 二进制文件。
将生成的二进制文件命名为
fatfs.bin
,并放置于{SDK}\amebalite_gcc_project
目录下。参考 配置 SDK (menuconfig) 进入
CONFIG VFS
配置,选择Enable VFS FATFS
和FATFS within APP Image
。重新编译应用程序固件。
应用程序固件 (kr4_km4_app.bin
) 包含一个 FAT 格式的只读 VFS 区域,该区域将在启动过程中自动挂载。
准备只读文件并将其转换成 FAT 格式的二进制文件,具体方法请参考 FatFS 二进制文件。
将生成的二进制文件命名为
fatfs.bin
,并放置于{SDK}\amebasmart_gcc_project
目录下。参考 配置 SDK (menuconfig) 进入
CONFIG VFS
配置,选择Enable VFS FATFS
和FATFS within APP Image
。重新编译应用程序固件。
应用程序固件 (km0_km4_ca32_app.bin
) 包含一个 FAT 格式的只读 VFS 区域,该区域将在启动过程中自动挂载。
启动后,出现日志 VFS-FAT Init Success,即表明 FAT 文件系统已成功挂载。
后续需要更新 FAT 文件系统内容时,通过 OTA 的方式可以跟随固件一起更新。
备注
为了优化该文件系统的有效空间利用率,目前仅支持 FAT 格式。
通用文件操作
VFS 中常用的通用文件操作接口如下所示:
API |
参数 |
描述 |
---|---|---|
fopen |
|
以指定模式打开指定文件 |
fclose |
|
关闭文件流 |
fread |
|
从文件流中读取数据到指定缓冲区 |
fwrite |
|
将缓冲区数据写入文件流 |
fseek |
|
设置文件流的读写位置到指定偏移量 |
rewind |
|
将文件流的读写位置重置到文件开头 |
fgetpos |
|
获取当前文件流的读写位置并保存到指定的位置 |
fsetpos |
|
设置文件流的读写位置为指定的位置 |
fflush |
|
刷新文件流的输出缓冲区 |
remove |
|
删除指定文件,使其不可访问 |
rename |
|
将文件从旧路径重命名为新路径 |
feof |
|
检测文件流是否已到达末尾 |
ferror |
|
检测文件流是否发生错误 |
ftell |
|
返回当前文件流的读写位置 |
ftruncate |
|
将文件截断至指定长度 |
opendir |
|
打开目录 |
readdir |
|
读取目录内容 |
closedir |
|
关闭已打开的目录 |
rmdir |
|
删除空目录 |
mkdir |
|
创建新目录 |
access |
|
检查文件的可访问性 |
stat |
|
获取文件元数据 |
用户可以参考 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 二进制文件
在生成 LittleFS 二进制文件前,需准备一个包含所需文件的目录。例如:
root:~$ ls -R test test: AUDIO KV test/AUDIO audio_test.mp3 test/KV kv_test.txt
在 Flash 中, AUDIO 和 KV 目录作为 LittleFS 目录, test 则相当于文件系统的根目录。
通过 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 区域大小等于块大小乘以块数量。
下载固件至 Flash 中。
参考 固件下载 将二进制文件下载至 Flash 中。Image Tool 的起始地址应为 Flash中的VFS 中提到的 VFS Flash 区域的
StartAddr
,结束地址应为EndAddr + 1
。
FatFS 二进制文件
在生成 FatFS 二进制文件前,需准备一个包含所需文件的目录。例如:
root:~$ ls -R test test: AUDIO KV test/AUDIO audio_test.mp3 test/KV kv_test.txt
在 Flash 中, AUDIO 和 KV 目录作为 FatFS 目录, test 则相当于文件系统的根目录。
通过 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 区域大小等于扇区大小乘以扇区数量。
下载固件至 Flash 中。
参考 固件下载 将二进制文件下载至 Flash 中。Image Tool 的起始地址应为 Flash中的VFS 中提到的 VFS Flash 区域的
StartAddr
,结束地址应为EndAddr + 1
。