EasyFlash是一款开源的轻量级面向嵌入式平台的Flash存储器库,方便开发者更加轻松的实现基于Flash存储器的常见应用开发。非常适合智能家居、可穿戴、工控、医疗等需要断电存储功能的产品,资源占用极低,支持各种 MCU 片上存储器。该库目前提供 三大实用功能 :
a. Env 小型KV数据库,支持 写平衡(磨损平衡) 及掉电保护模式
让Flash变为NoSQL(非关系型数据库)模型的小型键值(Key-Value)存储数据库。在产品上,能够更加简捷的实现 设定参数 或 运行日志等信息掉电保存的功能。
b.IAP 在线升级再也不是难事儿
该库封装了IAP(In-Application Programming)功能常用的接口,支持CRC32校验,同时支持Bootloader及Application的升级。
c.Log 无需文件系统,日志可直接存储在Flash上
非常适合应用在小型的不带文件系统的产品中,方便开发人员快速定位、查找系统发生崩溃或死机的原因。同时配合EasyLogger(我开源的超轻量级、高性能C日志库,它提供与EasyFlash的无缝接口)一起使用,轻松实现C日志的Flash存储功能。
编译器:RT-Thread Studio
系统:RT-Thread 4.0.2
easyflash依赖 Flash 的驱动,可以使用如下两款。
fal : Flash 抽象层
SFUD : 万能 SPI Flash 驱动库
SFUD驱动移植见,《RT-Thread SPI万能驱动 SFUD 驱动Flash W25Q64》
打开RT-Thread Settings
在 软件包 里面 点Add 进去后搜索 easyflash 找到后添加软件包,添加后点击保存,系统会自动下载添加软件包,添加成功后如下图。
双击图标进入软件包的基本设置,最后点击保存,
软件包添加到 packager 目录
移植信息先看 ports ->README.md
移植参考文件位于 /ports/ef_sfud_port.c 。先将该文件拷贝至项目中,
这里把 ef_sfud_port.c 文件复制到应用程序的文档里面
/**
* Flash port for hardware initialize.
*
* @param default_env default ENV set for user
* @param default_env_size default ENV size
*
* @return result
*/
EfErrCode ef_port_init(ef_env const **default_env, size_t *default_env_size) {
EfErrCode result = EF_NO_ERR;
*default_env = default_env_set;
*default_env_size = sizeof(default_env_set) / sizeof(default_env_set[0]);
rt_sem_init(&env_cache_lock, "env lock", 1, RT_IPC_FLAG_PRIO);
/* 从 RT-Thread 的 SPI Flash 设备中获取 SFUD Flash 设备对象 */
extern rt_spi_flash_device_t W25Q128JV;
//flash = (sfud_flash_t)(W25Q128JV->user_data);/*源码的内容*/
flash = rt_sfud_flash_find("spi10"); /*修改的对象赋值代码:获取 sfud_dev ,赋值给flash*//
return result;
}
上述代码中的 W25Q128JV,是在 Flash 设备初始化时,执行 W25Q128JV= rt_sfud_flash_probe("W25Q128JV", "spi10");
成功的返回值。该对象是 RT-Thread 的 SPI Flash 对象,其内部元素 user_data 里存放了 SFUD Flash 对象,将其赋值给静态的 flash 变量即可。
使用easyflash前需要初始化,使用如下函数;
注意:需要在 SFUD 完成初始化后,再初始化 easyflash
easyflash_init();
以下测试内容参考博文
EasyFlash | 让 Flash 成为小型 KV 数据库-CSDN博客
测试读取默认环境变量
在main.c中编写一个EasyFlash测试函数:
void test_env(void)
{
char wifi_ssid[20] = {0};
char wifi_passwd[20] = {0};
size_t len = 0;
/* 读取默认环境变量值 */
//环境变量长度未知,先获取 Flash 上存储的实际长度 */
ef_get_env_blob("wifi_ssid", NULL, 0, &len);
//获取环境变量
ef_get_env_blob("wifi_ssid", wifi_ssid, len, NULL);
//打印获取的环境变量值
printf("wifi_ssid env is:%s\r\n", wifi_ssid);
//环境变量长度未知,先获取 Flash 上存储的实际长度 */
ef_get_env_blob("wifi_passwd", NULL, 0, &len);
//获取环境变量
ef_get_env_blob("wifi_passwd", wifi_passwd, len, NULL);
//打印获取的环境变量值
printf("wifi_passwd env is:%s\r\n", wifi_passwd);
/* 将环境变量值改变 */
ef_set_env_blob("wifi_ssid", "SSID_TEST", 9);
ef_set_env_blob("wifi_passwd", "66666666", 8);
}
此时环境变量已经被修改,直接复位开发板,可以看到读取出的新值:
注意:最重要需要配置 easyflash 存储数据的空间范围。以下有介绍
EasyFlash的核心功能配置文件在ef_cfg.h,修改说明如下。
① 环境变量功能相关
② Flash擦除粒度和写入粒度
③ 备份区相关(在这里设置 EasyFlash 存储数据空间的范围,开始地址,存储扇区大小,注意以扇区为单位)
④ 调试日志是否开启
⑤配置 ENV 长度
另外字符串 ENV 也有长度的限制,默认 EF_STR_ENV_VALUE_MAX_SIZE 配置为 128 字节,超过长度的可能无法使用 ef_get_env 获取,只能使用 ef_get_env_blob 获取。
EF_STR_ENV_VALUE_MAX_SIZE
在如下目录
至此,EasyFlash移植、配置完成,接下来就可以愉快的使用了!
初始化
easyflash_init();
删除
ef_set_env("boot_times",NULL);
增加、修改
ef_set_env("boot_times", c_new_boot_times);
保存
ef_save_env();
读取
ef_get_env("boot_times");