FlashDB 是一款面向嵌入式系统的超轻量级数据库,旨在为资源受限的嵌入式产品提供可靠、高效的数据存储方案。它不仅支持基于文件系统的数据库,还深度结合 Flash 存储器的物理特性,在保证极低资源占用的前提下,优化性能与可靠性,并尽可能延长 Flash 的使用寿命。
FlashDB 主要提供两种数据模型:
- 键值数据库 (KVDB):一种非关系型数据库,数据以键值对的形式存储,其中键作为唯一标识符。其特点是接口简洁、操作高效,易于扩展。
- 时序数据库 (TSDB):专门用于存储按时间顺序产生的数据。每条记录都包含时间戳,非常适合数据量大、插入和查询频繁的场景。
KVDB 典型应用场景:
TSDB 典型应用场景:
- 存储动态产生的结构化数据,例如温湿度传感器采集的环境监测信息、智能手环记录的健康数据等。
- 记录系统运行日志、历史告警信息等。


与 EasyFlash 的对比
EasyFlash 和 FlashDB 均由开发者 armink 开源,同为轻量级嵌入式存储解决方案,但设计定位不同。FlashDB 可视为 EasyFlash 的功能增强与演进版本。

| 对比维度 |
EasyFlash |
FlashDB |
| 核心定位 |
轻量级 Flash 存储器库,侧重参数存储。 |
超轻量级嵌入式数据库,提供结构化数据管理。 |
| 数据模型 |
键值对 (Key-Value),用于存储环境变量。 |
1. 键值对 (KVDB)<br>2. 时序数据 (TSDB) |
| 关键功能 |
ENV(环境变量)、IAP、Log。 |
在KVDB基础上,新增时序数据库(TSDB),支持按时间序列高效存取。 |
| 性能与资源 |
资源占用极低。 |
功能更多,在保持低资源占用的同时优化了查询性能。 |
| 依赖关系 |
可独立使用,或依赖 RT-Thread 的FAL抽象层。 |
底层依赖于FAL(Flash Abstraction Layer),需先完成FAL移植。 |
| 版本关系 |
早期项目,其v5.0.0版本重命名为FlashDB。 |
由EasyFlash发展而来,功能更全面。 |
- 选择 EasyFlash:如果需求非常简单,仅需存储少量设备参数、配置,且对资源消耗极其敏感。
- 选择 FlashDB:如果需要记录大量带时间戳的数据(如传感器历史、运行日志),或未来可能需要更复杂的数据查询与管理功能。
移植与配置(以STM32F407ZG为例)
FlashDB 底层的 Flash 操作依赖于 RT-Thread 的 FAL (Flash Abstraction Layer) 抽象层。该软件包同样支持裸机平台,因此移植工作的核心是将目标 Flash 设备对接到 FAL。

FAL 的配置可参考相关文章。本文以使用 STM32 片内 Flash 为例,关键配置文件 fal_cfg.h 内容如下:
#ifndef _FAL_CFG_H_
#define _FAL_CFG_H_
#include <rtthread.h>
#include <board.h>
extern const struct fal_flash_dev stm32_onchip_flash_128k;
/* flash device table */
#define FAL_FLASH_DEV_TABLE \
{ \
&stm32_onchip_flash_128k, \
}
/* ====================== Partition Configuration ========================== */
#ifdef FAL_PART_HAS_TABLE_CFG
/* partition table */
#define FAL_PART_TABLE \
{ \
{FAL_PART_MAGIC_WROD, "fdb_kvdb", "onchip_flash_128k", 1* 128 * 1024 , 2* 128 * 1024, 0}, \
{FAL_PART_MAGIC_WROD, "fdb_tsdb", "onchip_flash_128k", 3* 128 * 1024 , 2* 128 * 1024, 0}, \
}
#endif /* FAL_PART_HAS_TABLE_CFG */
#endif /* _FAL_CFG_H_ */
此配置定义了两个分区:fdb_kvdb 和 fdb_tsdb,分别用于存放键值数据库和时序数据库的数据。
在 RT-Thread 的 ENV 工具或 rtconfig.h 中启用 FlashDB 软件包:

若 TSDB 需要时间戳功能,还需确保 RTC 设备驱动已正确配置并启用。
编译时若遇到错误,需根据提示调整相关配置,例如确保 gettimeofday 等系统调用已适配:

功能测试
编写测试用例,对 KVDB 和 TSDB 的基本功能进行验证。以下为主函数 main.c 的核心示例代码:
#include <rtthread.h>
#include <flashdb.h>
/* KVDB 对象 */
static struct fdb_kvdb kvdb = { 0 };
/* TSDB 对象 */
struct fdb_tsdb tsdb = { 0 };
/* 模拟时间戳的计数器 */
static int counts = 0;
/* 声明测试函数 */
extern void kvdb_basic_sample(fdb_kvdb_t kvdb);
extern void kvdb_type_string_sample(fdb_kvdb_t kvdb);
extern void kvdb_type_blob_sample(fdb_kvdb_t kvdb);
extern void tsdb_sample(fdb_tsdb_t tsdb);
/* 锁函数,用于保证操作原子性(裸机环境示例) */
static void lock(fdb_db_t db) {
__disable_irq(); // 关中断
}
static void unlock(fdb_db_t db) {
__enable_irq(); // 开中断
}
/* 获取时间函数(此处用计数器模拟,实际项目应替换为RTC时间) */
static fdb_time_t get_time(void) {
return ++counts;
}
int main(void) {
fdb_err_t result;
#ifdef FDB_USING_KVDB
{
/* 初始化 KVDB */
fdb_kvdb_control(&kvdb, FDB_KVDB_CTRL_SET_LOCK, (void *)lock);
fdb_kvdb_control(&kvdb, FDB_KVDB_CTRL_SET_UNLOCK, (void *)unlock);
result = fdb_kvdb_init(&kvdb, "env", "fdb_kvdb", NULL, NULL);
if (result != FDB_NO_ERR) return -1;
/* 执行 KVDB 测试样例 */
kvdb_basic_sample(&kvdb);
kvdb_type_string_sample(&kvdb);
kvdb_type_blob_sample(&kvdb);
}
#endif
#ifdef FDB_USING_TSDB
{
/* 初始化 TSDB */
fdb_tsdb_control(&tsdb, FDB_TSDB_CTRL_SET_LOCK, (void *)lock);
fdb_tsdb_control(&tsdb, FDB_TSDB_CTRL_SET_UNLOCK, (void *)unlock);
result = fdb_tsdb_init(&tsdb, "log", "fdb_tsdb", get_time, 128, NULL);
fdb_tsdb_control(&tsdb, FDB_TSDB_CTRL_GET_LAST_TIME, &counts); // 读取上次保存的时间
if (result != FDB_NO_ERR) return -1;
/* 执行 TSDB 测试样例 */
tsdb_sample(&tsdb);
}
#endif
while (1) {
rt_thread_mdelay(1000);
}
}
通过串口调试工具查看输出,可以验证 FlashDB 是否正常工作:

参考资料