Introduction
This section introduces how to run Virtual File System (VFS) on RTL8721Dx, including FatFS and LittleFS as the underlying implementation. Users can ignore the differences between different file systems by using VFS. The VFS provides common file operation interfaces like fopen, fclose, fwrite, fread, etc. The Key-Value (KV) interfaces are based on these common file operations. The architecture of VFS is illustrated in Architecture of VFS.
Architecture of VFS
VFS Initialization
By default, the VFS has been initialized in main.c
as follows:
void app_filesystem_init(void)
{
int ret = 0;
vfs_init();
#ifdef CONFIG_FATFS_WITHIN_APP_IMG
ret = vfs_user_register("fat", VFS_FATFS, VFS_INF_FLASH, VFS_REGION_2, VFS_RO);
if (ret == 0) {
RTK_LOGI(TAG, "VFS-FAT Init Success \n");
} else {
RTK_LOGI(TAG, "VFS-FAT Init Fail \n");
}
#endif
ret = vfs_user_register(VFS_PREFIX, VFS_LITTLEFS, VFS_INF_FLASH, VFS_REGION_1, VFS_RW);
if (ret == 0) {
ret = rt_kv_init();
if (ret == 0) {
RTK_LOGI(TAG, "File System Init Success\n");
return;
}
}
RTK_LOGE(TAG, "File System Init Fail \n");
return;
}
The vfs_user_register()
API will mount VFS to the Flash by users’ configuration. If failed to mount, this API will check whether the Flash is clean (0xFF). And if the Flash is clean, it will program the Flash to initialize VFS.
int vfs_user_register(const char *prefix, int vfs_type, int interface, char region, char flag)
Where:
prefix
: defined by users, used to distinguish different file systemsvfs_type
: file system type of the underlying implementation (FatFS or LittleFS)interface
: memory type (Flash only)region
: Flash partition (VFS1 or VFS2, described in section VFS on Flash)flag
: operation authority of file system (read-write or read-only)
Note
vfs_type
of VFS_REGION_1 is set to LittleFS
by default for read-write balance and power failure protection. To ensure proper utilization of FatFS, it is essential to configure the relevant settings in the menuconfig.
Usage of VFS
VFS on Flash
Adjust the Flash partitions appropriately if the VFS interfaces are set to the Flash, and modify VFS1 or VFS2 (according to register region in main.c) in Flash_Layout[]
in {SDK}\component\soc\amebadplus\usrcfg\ameba_flashcfg.c
.
const FlashLayoutInfo_TypeDef Flash_Layout[] = {
/*Region_Type, [StartAddr, EndAddr] */
{IMG_BOOT, 0x08000000, 0x08013FFF}, //Boot Manifest(4K) + KM4 Bootloader(76K)
//Users should modify below according to their own memory
{IMG_APP_OTA1, 0x08014000, 0x081F3FFF}, //Certificate(4K) + Manifest(4K) + KM4 Application OTA1 + Manifest(4K) + RDP IMG OTA1
{IMG_BOOT_OTA2, 0x08200000, 0x08213FFF}, //Boot Manifest(4K) + KM4 Bootloader(76K) OTA
{IMG_APP_OTA2, 0x08214000, 0x083DCFFF}, //Certificate(4K) + Manifest(4K) + KM4 Application OTA2 + Manifest(4K) + RDP IMG OTA2
{FTL, 0x083DD000, 0x083DFFFF}, //FTL for BT(>=12K), The start offset of flash pages which is allocated to FTL physical map.
{VFS1, 0x083E0000, 0x083FFFFF}, //VFS region 1 (128K)
{VFS2, 0xFFFFFFFF, 0xFFFFFFFF}, //VFS region 2
{USER, 0xFFFFFFFF, 0xFFFFFFFF}, //Reserved for users
/* End */
{0xFF, 0xFFFFFFFF, 0xFFFFFFFF},
};
Note
The VFS1 region must exist, and its size should always be larger than 128KB. There are two VFS regions at most.
VFS within APP Image
If the user only intends to use read-only files through VFS, VFS provides a more convenient read-only configuration feature on flash. The detailed steps are as follows:
Prepare the read-only files and convert them into a FAT-formatted bin file. Refer to section FatFS Bin File Generation for the method.
Name the bin file
fatfs.bin
and place it in the{SDK}\amebasmart_gcc_project
directory.Enable the following configurations in the menuconfig:


Rebuild the application firmware. The application firmware (km0_km4_app.bin) will include a read-only VFS area in FAT format, which will be mounted during the startup process.
After startup, you will see the log
VFS-FAT Init Success
indicating that the read-only file system has been successfully mounted.For the file usage method, refer to sections Common File Operation or Key-Value Operation.
Note
To optimize the effective space utilization of the read-only file system, only FAT format is currently supported.
Common File Operation
The common file operation interfaces used in VFS are listed below:
API |
Parameter |
Description |
---|---|---|
fopen |
|
Open the filename pointed to, by filename using the given mode |
fclose |
FILE * stream |
Close the stream |
fread |
|
Read data from the given stream by ptr into the array pointed to |
fwrite |
|
Write data from the array pointed to by ptr to the given stream |
fseek |
|
Set the file position of the stream to the given offset |
rewind |
FILE * stream |
Set the file position to the beginning of the file of the given stream |
fgetpos |
|
Get the current file position of the stream and writes it to pos |
fsetpos |
|
Set the file position of the given stream to the given position |
fflush |
FILE * stream |
Flush the output buffer of a stream |
remove |
const char * filename |
Delete the given filename so that it is no longer accessible |
rename |
|
Cause the filename referred to from old_filename to new_filename |
feof |
FILE * stream |
Test the end-of-file indicator for the given stream |
ferror |
FILE * stream |
Test the error indicator for the given stream |
ftell |
FILE * stream |
Return the current file position of the given stream |
ftruncate |
|
Truncate a file to a specified length |
opendir |
const char * name |
Open a directory |
readdir |
DIR * pdir |
Read a directory |
closedir |
DIR * dirp |
Close a directory |
rmdir |
const char * path |
Remove a directory |
mkdir |
|
Make a directory |
access |
|
Determine accessibility of a file |
stat |
|
Get file status |
Users can rebuild the project by make all EXAMPLE=vfs
to test how common file operations work. Test logs should be like below:
[example_vfs_thread] fwrite succeeded !!!
[example_vfs_thread] fread succeeded !!!
[example_vfs_thread] remove file succeeded !!!
Note
If successful, fseek
returns offset according to the beginning of file which is different from standard interfaces.
Key-Value Operation
Simple KV interfaces are also provided for users. All KV APIs are placed in {SDK}\component\file_system\kv\kv.c
. Users can rebuild the project by make all EXAMPLE=kv
to test how KV APIs work. Test logs should be like below:
rt_kv_set success, write 28 letters.
rt_kv_get success, read 28 letters.
rt_kv_delett success.
Code Conversion
The conversion between Unicode and other codes is not supported on FatFS by default.
Modify the macro FF_CODE_PAGE
in {SDK}\component\file_system\fatfs\r0.14b\include\ffconf.h
to enable the code conversion function, where FF_CODE_PAGE
should be chosen as code page number which is desired.
#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 Encryption
For special storage security needs, users can configure encryption and decryption interfaces of vfs. Specific interface usage instructions are listed in {SDK}\component\example\storage\vfs_encrypt\readme.txt
. Users can rebuild the project by make all EXAMPLE=vfs_encrypt
to test how KV APIs work. Test logs should be like below:
[example_vfs_encrypt_thread] fwrite succeeded !!!
[example_vfs_encrypt_thread] fread succeeded !!!
[example_vfs_encrypt_thread] remove file succeeded !!!
Note
Plaintext will be padded according to the length of grouped data. It will take more cost of memory space if using vfs encryption.
VFS Bin File Generation
If data needs to be placed in the Flash in advance, VFS bin file can be generated on PC. After generating the bin file, it should be downloaded to VFS region according to the Flash layout.
LittleFS Bin File Generation
Prepare a needed object folder including files before generating LittleFS bin files. For example:
AUDIO
andKV
directories will be LittleFS directory in the Flash. Thetest
directory is equivalent to the root directory.Use the command
$./mklittlefs -b 4096 -p 256 -s 0x20000 -c test image_littlefs.bin
inmklittlefs
tool located at\tools\littlefs
to generate LittleFS bin files.Where:
b
: block size decided by Flashp
: page sizes
: bin file sizec
: object folder<Image_littlefs.bin>
: LittleFS bin file name
Note
“-b 4096” and “-p 256” are default configurations, users should adapt the configuration according to “block_size” and “cache_size” of
lfs_config
in{SDK}\component\file_system\littlefs\littlefs_adapter.c.
“-s 0x20000” is according to VFS region mentioned in section VFS on Flash.Download the image to the Flash.
The start address of Image Tool should be
StartAddr
of VFS Flash region mentioned in section VFS on Flash. The end address of Image Tool should be it’sEndAddr
+ 1;
FatFS Bin File Generation
The steps to generate FatFS bin files are listed below:
Use command
root@ubuntu # dd if=/dev/zero of=test.bin count=64 bs=1KB
to createtest.bin
that has 64 blocks and each block is 1KB.Use command
root@ubuntu # mkfs.fat -S 512-F 12 test.bin
to build a FAT file system.Use command
root@ubuntu # sudo mount test.bin ./fs
to mounttest.bin
to file folder fs.Use command
root@ubuntu # sudo cp hello.txt ./fs
to copy the files that users want to store intotest.bin
.In this step,
hello.txt
is stored intest.bin
.Use command
root@ubuntu # sudo umount ./fs
to generate the FatFS file after unmountingtest.bin
.Users should find other related information from the internet, and copy
test.bin
into user data area of Flash finally.