前言
本文档主要针对WS63V100中LITTLE FILE SYSTEM(下简称LFS)文件系统模块的使用进行介绍。用于指导工程人员能够快速使用文件系统模块进行二次开发。
与本文档相对应的产品版本如下。
本文档主要适用于以下工程师:
技术支持工程师
软件工程师
在本文中可能出现下列标志,它们所代表的含义如下。
LFS简介
LFS文件系统是为小型嵌入式系统创建的一个文件系统,为用户提供了文件的打开、关闭、读取、写入、删除等功能,用户可以通过使用这些接口,将数据存储到NOR FLASH。
掉电恢复能力- LFS旨在处理随机掉电。所有文件操作都有强大的写时拷贝保证,如果断电,文件系统将回退到最后一个已知的良好状态。
动态磨损均衡- LFS在设计时考虑到了flash,并在动态块上提供了磨损均衡。此外,LFS可以检测坏块并解决它们。
有界RAM/ROM - LFS设计用于使用少量内存。RAM的使用是有严格限制的,这意味着RAM的使用不会随着文件系统的增长而改变。文件系统不包含无界递归,动态内存仅限于可以静态提供的可配置缓冲区。
LFS编译预置
当前SDK中提供了LFS特性,但默认不编译打开,如需使用,需按以下指导进行编译及特性配置
加入编译。在需要LFS特性的编译目标中加入组件 'little_fs', 'littlefs_adapt_ws63'
特性宏。使用menuconfig,在需要LFS特性的编译目标中打开该特性对应的特性宏,特性宏配置路径:middleware->chip->Choose Chip (ws63)-> Chip Configurations for ws63->打开littlefs adapt,即可打开CONFIG_MIDDLEWARE_SUPPORT_LFS特性宏,打开宏后,LFS会在运行过程中自行完成挂载操作
FLASH分配,关注代码(文件路径:middleware/chips/ws63/littlefs/littlefs_adapt.c)接口littlefs_adapt_get_block_info 读取分区表信息对应分区为
CONFIG_LFS_PARTITION_ID;
该宏需要替换或修改为分区表ID文件(middleware/chips/ws63/partition/include/partition_resource_id.h)中其他的分区ID宏,并在分区表配置文件(build/config/target_config/ws63/param_sector/param_sector.json)中对该宏ID对应的FLASH地址与大小进行配置,作为LFS的运行基础;
配置方式为通过menuconfig配置,在打开CONFIG_MIDDLEWARE_SUPPORT_LFS宏后,会自动显示该宏,默认值为0x21,修改为分配的对应ID即可,不过在menuconfig中只允许输入十进制数,注意进制转换;需要注意的是,每次调整LFS的地址后,LFS中的内容会丢失;
其他适配,为适配不同的上层VFS,对打开文件传入的oflag参数进行了转化,使得能够适配LFS的下层实现;为保证正常使用,需要重新实现fs_adapt_flag_format接口来适配上层flag。
支持posix文件接口函数open,read,write,lseek,close,该配置可按需开关,默认关闭。
可以通过menuconfig配置“Middleware->Chips->Chip Configurations for ws63->littlefs adapt->littlefs support posix interface ”打开对应特性宏。在不冲突的情况下,能够支持open、read、write、lseek、close、unlink、sync接口。
LFS接口API
API
当前提供的API不代表LFS的所有能力,请按需使用
表 1
编程实例
代码实现中提供一段基础调用示例lfs_test,打开根目录下名为lfs_test的文件,读取首个字节并按照整型数打印,字节加一后再写入到文件头,最后关闭文件;
void lfs_test(void)
{
// read current count
char boot_count = 0;
int fp = fs_adapt_open("/lfs_test", O_RDWR | O_CREAT);
if (fp < 0) {
return;
}
int ret = fs_adapt_read(fp, &boot_count, sizeof(boot_count));
lfs_debug_print_info("lfs_test read, ret = 0x%x\r\n", ret);
// print the boot count
lfs_debug_print_info("===========boot_count: %d=============\r\n", boot_count);
// update boot count
boot_count = (char)((uint8_t)boot_count + 1);
ret = fs_adapt_seek(fp, 0, LFS_SEEK_SET);
lfs_debug_print_info("lfs_test seek, ret = 0x%x\r\n", ret);
if (ret < LFS_ERR_OK) {
return;
}
ret = fs_adapt_write(fp, &boot_count, sizeof(boot_count));
lfs_debug_print_info("lfs_test write, ret = 0x%x\r\n", ret);
// remember the storage is not updated until the file is closed successfully
ret = fs_adapt_close(fp);
lfs_debug_print_info("lfs_test close, ret = 0x%x\r\n", ret);
if (ret < LFS_ERR_OK) {
return;
}
}