FlashDB移植与应用
最近工作需要,对设备参数进行备份存储,由于之前使用的是简单的分区备份方法。Easyflash的单实例不再适用。后面发现大神基于easyflash进行了新版本更新,但是不向前兼容,新版命名为FlashDB。
简介
FlashDB 是一款超轻量级的嵌入式数据库,专注于提供嵌入式产品的数据存储方案。与传统的基于文件系统的数据库不同,FlashDB 结合了 Flash 的特性,具有较强的性能及可靠性。并在保证极低的资源占用前提下,尽可能延长 Flash 使用寿命。
FlashDB 提供两种数据库模式:
键值数据库 :是一种非关系数据库,它将数据存储为键值(Key-Value)对集合,其中键作为唯一标识符。KVDB 操作简洁,可扩展性强。 时序数据库 :时间序列数据库 (Time Series Database , 简称 TSDB),它将数据按照 时间顺序存储 。TSDB 数据具有时间戳,数据存储量大,插入及查询性能高。
这里只用到了基础的KV功能。
FlashDB和FAL介绍
移植的主要工作都在 FAL 这边,其他接口并不是强依赖,可以根据自己的情况进行对接。 FAL 底层将不同的 Flash 存储介质进行了统一封装,并提供了分区表机制,暴露给上层用户。
FlashDB 的每个数据库就是基于 FAL 提供的分区机制,每个数据库都坐落在某个 FAL 的分区上,相当于一个分区对应一个数据库。
定义 flash 设备
在定义 Flash 设备表前,需要先定义 Flash 设备。可以是片内 flash, 也可以是片外基于 SFUD 的 spi flash:
定义具体的 Flash 设备对象,用户需要根据自己的 Flash 情况分别实现 init、 read、 write、 erase 这些操作函数: static int init(void):可选 的初始化操作。 static int read(long offset, uint8_t *buf, size_t size):读取操作。 static int write(long offset, const uint8_t *buf, size_t size) :写入操作。 static int erase(long offset, size_t size) :擦除操作。 用户需要根据自己的 Flash 情况分别实现这些操作函数。在文件最底部定义了具体的 Flash 设备对象 ,如下示例定义了 stm32f2 片上 flash:stm32f2_onchip_flash
const struct fal_flash_dev stm32f2_onchip_flash = { .name = “stm32_onchip”, .addr = 0x08000000, .len = 10241024, .blk_size = 1281024, .ops = {init, read, write, erase}, .write_gran = 8 };
8 : 设置写粒度,单位 bit, 0 表示未生效(默认值为 0 ),该成员是 fal 版本大于 0.4.0 的新增成员。各个 flash 写入粒度不尽相同,可通过该成员进行设置,以下列举几种常见 Flash 写粒度:
nor flash: 1 bit stm32f2/f4: 8 bit stm32f1: 32 bit stm32l4: 64 bit
定义 flash 设备表
Flash 设备表定义在 fal_cfg.h 头文件中,定义分区表前需 新建 fal_cfg.h 文件 ,请将该文件统一放在对应 BSP 或工程目录的 port 文件夹下,并将该头文件路径加入到工程。fal_cfg.h 可以参考 示例文件 fal/samples/porting/fal_cfg.h 完成。
设备表示例:
/* ===================== Flash device Configuration ========================= */
extern const struct fal_flash_dev stm32f2_onchip_flash;
extern struct fal_flash_dev nor_flash0;
/* flash device table */
#define FAL_FLASH_DEV_TABLE \
{ \
&stm32f2_onchip_flash, \
&nor_flash0, \
}
Flash 设备表中,有两个 Flash 对象,一个为 STM32F2 的片内 Flash ,一个为片外的 Nor Flash。
定义 flash 分区表
分区表也定义在 fal_cfg.h 头文件中。Flash 分区基于 Flash 设备,每个 Flash 设备又可以有 N 个分区,这些分区的集合就是分区表。在配置分区表前,务必保证已定义好 Flash 设备 及 设备表。fal_cfg.h 可以参考 示例文件 fal/samples/porting/fal_cfg.h 完成。
分区表示例:
#define NOR_FLASH_DEV_NAME "norflash0"
/* ====================== Partition Configuration ========================== */
#ifdef FAL_PART_HAS_TABLE_CFG
/* partition table */
#define FAL_PART_TABLE \
{ \
{FAL_PART_MAGIC_WORD, "bl", "stm32_onchip", 0, 64*1024, 0}, \
{FAL_PART_MAGIC_WORD, "app", "stm32_onchip", 64*1024, 704*1024, 0}, \
{FAL_PART_MAGIC_WORD, "easyflash", NOR_FLASH_DEV_NAME, 0, 1024*1024, 0}, \
{FAL_PART_MAGIC_WORD, "download", NOR_FLASH_DEV_NAME, 1024*1024, 1024*1024, 0}, \
}
#endif /* FAL_PART_HAS_TABLE_CFG */
上面这个分区表详细描述信息如下: 分区名保证 不能重复; 关联的 Flash 设备 务必已经在 Flash 设备表中定义好 ,并且 名称一致 ,否则会出现无法找到 Flash 设备的错误; 分区的起始地址和大小 不能超过 Flash 设备的地址范围 ,否则会导致包初始化错误; 注意:每个分区定义时,除了填写上面介绍的参数属性外,需在前面增加 FAL_PART_MAGIC_WORD 属性,末尾增加 0 (目前用于保留功能)
|