news 2026/7/1 16:37:32

手把手教 - STM32 单片机 FlashDB 软件包的使用

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
手把手教 - STM32 单片机 FlashDB 软件包的使用

一、FlashDB 软件包的介绍

FlashDB 是一款超轻量级的嵌入式数据库,专注于提供嵌入式产品的数据存储方案。FlashDB 不仅支持传统的基于文件系统的数据库模式,而且结合了 Flash 的特性,具有较强的性能及可靠性。并在保证极低的资源占用前提下,尽可能延长 Flash 使用寿命。

FlashDB 提供两种数据库模式:

  1. 键值数据库 :是一种非关系数据库,它将数据存储为键值(Key-Value)对集合,其中键作为唯一标识符。KVDB 操作简洁,可扩展性强。
  2. 时序数据库 :时间序列数据库 (Time Series Database , 简称 TSDB),它将数据按照 时间顺序存储 。TSDB 数据具有时间戳,数据存储量大,插入及查询性能高。

键值数据库 :

  • 产品参数存储
  • 用户配置信息存储
  • 小文件管理

时序数据库 :

  • 存储动态产生的结构化数据:如 温湿度传感器采集的环境监测信息,智能手环实时记录的人体健康信息等
  • 记录运行日志:存储产品历史的运行日志,异常告警的记录等


二、和 EasyFlash 的区别

EasyFlash和FlashDB都是由开发者armink开源、面向嵌入式系统的轻量级存储方案,但它们在设计定位和功能上有所不同。简单来说,FlashDB可以被看作是EasyFlash的功能增强和扩展版本

下面的表格整理了它们的主要区别。

对比维度EasyFlashFlashDB
核心定位轻量级Flash存储器库,侧重参数存储超轻量级嵌入式数据库,提供更结构化的数据管理。
数据模型键值对 (Key-Value),用于存储如“设备名称”、“运行参数”等环境变量。1. 键值对 (KVDB)
2. 时序数据 (TSDB),适合存储带时间戳的传感器数据、日志等。
关键功能ENV(环境变量)、IAP(在线升级)、Log(日志存储)。在KVDB功能基础上,新增时序数据库(TSDB),支持按时间顺序高效存储和查询大量数据。
性能与资源资源占用极低(最低约ROM: 6KB, RAM: 0.1KB)。在提供更多功能的同时保持低资源占用;查询性能经过优化,在某些场景下比EasyFlash更快。
依赖关系可独立使用,或依赖RT-Thread的FAL抽象层进行移植。其底层存储操作依赖于FAL(Flash Abstraction Layer),需先完成FAL移植。
版本关系早期项目。其v5.0.0版本因API变更大而重命名为FlashDB,成为新的独立项目。由EasyFlash发展而来,功能更全面,可视为其后续演进版本
  • 选择 EasyFlash:如果需求非常简单,主要是存储一些设备参数、配置信息(环境变量),并且对资源消耗极其敏感,希望集成尽可能简单,那么EasyFlash是更轻量、直接的选择。
  • 选择 FlashDB:如果项目需要记录大量带时间戳的数据(如传感器历史数据、运行日志),或者未来可能有更复杂的数据管理需求(如按时间范围查询),那么FlashDB的时序数据库(TSDB)功能是EasyFlash无法替代的,它提供了更强的数据管理能力。

三、移植配置

单片机型号是STM32F407ZG。

FlashDB 底层的 Flash 管理及操作依赖于 RT-Thread 的 FAL (Flash Abstraction Layer) Flash 抽象层开源软件包,该开源库也支持运行在 裸机平台 。所以只需要将所用到的 Flash 对接到 FAL ,即可完成整个移植工作。

FAL 配置可参考文章:
https://mp.weixin.qq.com/s/-6FD1FFLsrVtwK3IVi5WDQ

使用的是片上flash,配置文件内容如下:

/* * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2018-12-5 SummerGift first version */#ifndef_FAL_CFG_H_#define_FAL_CFG_H_#include<rtthread.h>#include<board.h>#ifdefBSP_USING_SPI_FLASH_LITTLEFSexternstructfal_flash_devw25q128;#else#defineFLASH_SIZE_GRANULARITY_16K(4*16*1024)#defineFLASH_SIZE_GRANULARITY_64K(64*1024)#defineFLASH_SIZE_GRANULARITY_128K(7*128*1024)#defineSTM32_FLASH_START_ADRESS_16KSTM32_FLASH_START_ADRESS#defineSTM32_FLASH_START_ADRESS_64K(STM32_FLASH_START_ADRESS_16K+FLASH_SIZE_GRANULARITY_16K)#defineSTM32_FLASH_START_ADRESS_128K(STM32_FLASH_START_ADRESS_64K+FLASH_SIZE_GRANULARITY_64K)externconststructfal_flash_devstm32_onchip_flash_128k;#endif/* flash device table */#ifdefBSP_USING_SPI_FLASH_LITTLEFS#defineFAL_FLASH_DEV_TABLE\{\&w25q128,\}#else#defineFAL_FLASH_DEV_TABLE\{\&stm32_onchip_flash_128k,\}#endif/* ====================== Partition Configuration ========================== */#ifdefFAL_PART_HAS_TABLE_CFG/* partition table */#ifdefBSP_USING_SPI_FLASH_LITTLEFS#defineFAL_PART_TABLE\{\{FAL_PART_MAGIC_WROD,"spiflash0","W25Q128",0,16*1024*1024,0},\}#else#defineFAL_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#endif/* FAL_PART_HAS_TABLE_CFG */#endif/* _FAL_CFG_H_ */

开启 FlashDB


如果需要时间戳信息,则还需要 开启 RTC

编译报错,解决办法:

四、测试

测试用例:

主函数

/* * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2018-11-06 SummerGift first version * 2018-11-19 flybreak add stm32f407-atk-explorer bsp */#include<rtthread.h>#include<rtdevice.h>#include<board.h>#include<flashdb.h>//#include <stm32f4xx_hal.h>#defineFDB_LOG_TAG"[main]"staticuint32_tboot_count=0;statictime_tboot_time[10]={0,1,2,3};/* default KV nodes */staticstructfdb_default_kv_nodedefault_kv_table[]={{"username","admin",0},/* string KV */{"password","123456",0},/* string KV */{"boot_count",&boot_count,sizeof(boot_count)},/* int type KV */{"boot_time",&boot_time,sizeof(boot_time)},/* int array type KV */};/* KVDB object */staticstructfdb_kvdbkvdb={0};/* TSDB object */structfdb_tsdbtsdb={0};/* counts for simulated timestamp */staticintcounts=0;externvoidkvdb_basic_sample(fdb_kvdb_tkvdb);externvoidkvdb_type_string_sample(fdb_kvdb_tkvdb);externvoidkvdb_type_blob_sample(fdb_kvdb_tkvdb);externvoidtsdb_sample(fdb_tsdb_ttsdb);staticvoidlock(fdb_db_tdb){__disable_irq();}staticvoidunlock(fdb_db_tdb){__enable_irq();}staticfdb_time_tget_time(void){/* Using the counts instead of timestamp. * Please change this function to return RTC time. */return++counts;}/* defined the LED0 pin: PF9 */#defineLED0_PINGET_PIN(C,3)intmain(void){/* set LED0 pin mode to output */rt_pin_mode(LED0_PIN,PIN_MODE_OUTPUT);//fal_init();fdb_err_tresult;#ifdefFDB_USING_KVDB{/* KVDB Sample */structfdb_default_kvdefault_kv;default_kv.kvs=default_kv_table;default_kv.num=sizeof(default_kv_table)/sizeof(default_kv_table[0]);/* set the lock and unlock function if you want */fdb_kvdb_control(&kvdb,FDB_KVDB_CTRL_SET_LOCK,(void*)lock);fdb_kvdb_control(&kvdb,FDB_KVDB_CTRL_SET_UNLOCK,(void*)unlock);/* Key-Value database initialization * * &kvdb: database object * "env": database name * "fdb_kvdb1": The flash partition name base on FAL. Please make sure it's in FAL partition table. * Please change to YOUR partition name. * &default_kv: The default KV nodes. It will auto add to KVDB when first initialize successfully. * NULL: The user data if you need, now is empty. */result=fdb_kvdb_init(&kvdb,"env","fdb_kvdb",&default_kv,NULL);if(result!=FDB_NO_ERR){return-1;}/* run basic KV samples */kvdb_basic_sample(&kvdb);/* run string KV samples */kvdb_type_string_sample(&kvdb);/* run blob KV samples */kvdb_type_blob_sample(&kvdb);}#endif/* FDB_USING_KVDB */#ifdefFDB_USING_TSDB{/* TSDB Sample *//* set the lock and unlock function if you want */fdb_tsdb_control(&tsdb,FDB_TSDB_CTRL_SET_LOCK,(void*)lock);fdb_tsdb_control(&tsdb,FDB_TSDB_CTRL_SET_UNLOCK,(void*)unlock);/* Time series database initialization * * &tsdb: database object * "log": database name * "fdb_tsdb1": The flash partition name base on FAL. Please make sure it's in FAL partition table. * Please change to YOUR partition name. * get_time: The get current timestamp function. * 128: maximum length of each log * NULL: The user data if you need, now is empty. */result=fdb_tsdb_init(&tsdb,"log","fdb_tsdb",get_time,128,NULL);/* read last saved time for simulated timestamp */fdb_tsdb_control(&tsdb,FDB_TSDB_CTRL_GET_LAST_TIME,&counts);if(result!=FDB_NO_ERR){return-1;}/* run TSDB sample */tsdb_sample(&tsdb);}#endif/* FDB_USING_TSDB */while(1){rt_pin_write(LED0_PIN,PIN_HIGH);rt_thread_mdelay(500);rt_pin_write(LED0_PIN,PIN_LOW);rt_thread_mdelay(500);}}

参考

https://gitee.com/RT-Thread-Mirror/FlashDB

https://armink.gitee.io/flashdb/#/zh-cn/README

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/29 7:19:14

草莓病害智能识别与分类 - 基于YOLO11与多注意力网络的快速检测系统

1. 草莓病害智能识别与分类 - 基于YOLO11与多注意力网络的快速检测系统 &#x1f353;&#x1f4bb; 1.1. 引言 草莓作为一种高价值经济作物&#xff0c;其健康生长对农业生产至关重要。然而&#xff0c;草莓在种植过程中容易受到多种病害侵扰&#xff0c;如灰霉病、白粉病、…

作者头像 李华
网站建设 2026/6/26 2:14:47

warp:GPU执行的基本单位

在 CUDA 的线程层次结构中&#xff0c;我们知道程序由线程块&#xff08;Block&#xff09;中的多个线程&#xff08;Thread&#xff09;组成。然而&#xff0c;在硬件层面&#xff0c;GPU 的流多处理器&#xff08;SM&#xff09;并不是以单个线程为单位来调度和执行指令的&am…

作者头像 李华
网站建设 2026/6/30 6:41:07

RNA碱基配对预测难题破解:R语言实战案例深度剖析(仅限专业人士)

第一章&#xff1a;RNA碱基配对预测的挑战与R语言解决方案RNA分子在生物体内承担着多种关键功能&#xff0c;其二级结构的准确性直接影响基因表达调控、翻译效率以及病毒复制等过程。其中&#xff0c;碱基配对预测是解析RNA二级结构的核心环节&#xff0c;但由于存在非经典配对…

作者头像 李华
网站建设 2026/6/30 20:47:22

Dify工作流条件判断配置全攻略(含JSON规则编写秘籍)

第一章&#xff1a;Dify工作流分支跳转的核心机制Dify作为一款面向AI应用开发的工作流引擎&#xff0c;其核心能力之一在于支持动态、条件驱动的流程控制。在复杂业务场景中&#xff0c;用户常需根据运行时数据决定执行路径&#xff0c;Dify通过“分支跳转”机制实现这一需求&a…

作者头像 李华
网站建设 2026/7/1 9:41:28

效率提升3倍!Dify结合自定义词典优化Tesseract识别的秘密武器

第一章&#xff1a;效率提升3倍&#xff01;Dify结合自定义词典优化Tesseract识别的秘密武器在处理OCR任务时&#xff0c;Tesseract是广泛使用的开源工具&#xff0c;但其默认识别准确率在特定领域&#xff08;如医疗、金融票据&#xff09;常因专业术语缺失而下降。通过集成Di…

作者头像 李华
网站建设 2026/7/1 10:57:52

SQL语言家族入门指南:标准SQL、T-SQL与PL/SQL详解

SQL语言家族入门指南&#xff1a;标准SQL、T-SQL与PL/SQL详解 对于数据库初学者来说&#xff0c;SQL语言的各种变体常常让人困惑。本文将为你详细解析标准SQL、T-SQL和PL-SQL的概念及其应用场景。 标准SQL 概念 标准SQL (Structured Query Language) 是由ANSI和ISO标准化组织制…

作者头像 李华