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.binand place it in the{SDK}\amebasmart_gcc_projectdirectory.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 Successindicating 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:
AUDIOandKVdirectories will be LittleFS directory in the Flash. Thetestdirectory is equivalent to the root directory.Use the command
$./mklittlefs -b 4096 -p 256 -s 0x20000 -c test image_littlefs.bininmklittlefstool located at\tools\littlefsto 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_configin{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
StartAddrof 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=1KBto createtest.binthat has 64 blocks and each block is 1KB.Use command
root@ubuntu # mkfs.fat -S 512-F 12 test.binto build a FAT file system.Use command
root@ubuntu # sudo mount test.bin ./fsto mounttest.binto file folder fs.Use command
root@ubuntu # sudo cp hello.txt ./fsto copy the files that users want to store intotest.bin.In this step,
hello.txtis stored intest.bin.Use command
root@ubuntu # sudo umount ./fsto generate the FatFS file after unmountingtest.bin.Users should find other related information from the internet, and copy
test.bininto user data area of Flash finally.