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.

../../../_images/vfs_architecture.svg

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 systems

  • vfs_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:

  1. Prepare the read-only files and convert them into a FAT-formatted bin file. Refer to section FatFS Bin File Generation for the method.

  2. Name the bin file fatfs.bin and place it in the {SDK}\amebasmart_gcc_project directory.

  3. Enable the following configurations in the menuconfig:

../../../_images/vfs_within_app_image_1.png
../../../_images/vfs_within_app_image_2.png
  1. 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.

  2. After startup, you will see the log VFS-FAT Init Success indicating that the read-only file system has been successfully mounted.

  3. 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:

Tabel name

API

Parameter

Description

fopen

  • const char * filename

  • const char * mode

Open the filename pointed to, by filename using the given mode

fclose

FILE * stream

Close the stream

fread

  • void * ptr

  • size_t size

  • size_t count

  • FILE * stream

Read data from the given stream by ptr into the array pointed to

fwrite

  • const void * ptr

  • size_t size

  • size_t count

  • FILE * stream

Write data from the array pointed to by ptr to the given stream

fseek

  • FILE * stream

  • long int offset

  • int origin

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

  • FILE * stream

  • fpos_t * p

Get the current file position of the stream and writes it to pos

fsetpos

  • FILE * stream

  • fpos_t * p

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

  • const char * oldname

  • const char * newname

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

  • FILE * stream

  • off_t length

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

  • const char * pathname

  • mode_t mode

Make a directory

access

  • const char * pathname

  • int mode

Determine accessibility of a file

stat

  • const char * path

  • struct stat * buf

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

  1. Prepare a needed object folder including files before generating LittleFS bin files. For example:

    ../../../_images/littlefs_bin_generation_step1.png

    AUDIO and KV directories will be LittleFS directory in the Flash. The test directory is equivalent to the root directory.

  2. Use the command $./mklittlefs -b 4096 -p 256 -s 0x20000 -c test image_littlefs.bin in mklittlefs tool located at \tools\littlefs to generate LittleFS bin files.

    Where:

    • b: block size decided by Flash

    • p: page size

    • s: bin file size

    • c: object folder

    • <Image_littlefs.bin>: LittleFS bin file name

    ../../../_images/littlefs_bin_generation_step2.png

    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.

  3. 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’s EndAddr + 1;

    ../../../_images/littlefs_bin_download.png

FatFS Bin File Generation

The steps to generate FatFS bin files are listed below:

  1. Use command root@ubuntu # dd if=/dev/zero of=test.bin count=64 bs=1KB to create test.bin that has 64 blocks and each block is 1KB.

  2. Use command root@ubuntu # mkfs.fat -S 512-F 12 test.bin to build a FAT file system.

  3. Use command root@ubuntu # sudo mount test.bin ./fs to mount test.bin to file folder fs.

  4. Use command root@ubuntu # sudo cp hello.txt ./fs to copy the files that users want to store into test.bin.

    In this step, hello.txt is stored in test.bin.

  5. Use command root@ubuntu # sudo umount ./fs to generate the FatFS file after unmounting test.bin.

    Users should find other related information from the internet, and copy test.bin into user data area of Flash finally.