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

阿里云教程12小时前发布
1 0 0

原文链接:https://mp.weixin.qq.com/s/b0opN44xgpauq7DZvfXo9g

一、FlashDB 软件包的介绍

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

FlashDB 提供两种数据库模式:

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

键值数据库 :

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

时序数据库 :

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

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

二、和 EasyFlash 的区别

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

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

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

对比维度 EasyFlash FlashDB
核心定位 轻量级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 ,即可完成整个移植工作。
手把手教 - STM32 单片机 FlashDB 软件包的使用
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>

#ifdef BSP_USING_SPI_FLASH_LITTLEFS
extern struct fal_flash_dev w25q128;
#else
#define FLASH_SIZE_GRANULARITY_16K   (4 * 16 * 1024)
#define FLASH_SIZE_GRANULARITY_64K   (64 * 1024)
#define FLASH_SIZE_GRANULARITY_128K  (7 * 128 * 1024)
#define STM32_FLASH_START_ADRESS_16K  STM32_FLASH_START_ADRESS
#define STM32_FLASH_START_ADRESS_64K  (STM32_FLASH_START_ADRESS_16K + FLASH_SIZE_GRANULARITY_16K)
#define STM32_FLASH_START_ADRESS_128K (STM32_FLASH_START_ADRESS_64K + FLASH_SIZE_GRANULARITY_64K)


extern const struct fal_flash_dev stm32_onchip_flash_128k;
#endif


/* flash device table */
#ifdef BSP_USING_SPI_FLASH_LITTLEFS
#define FAL_FLASH_DEV_TABLE                                          
{                                                                    
    &w25q128,                                                     
}
#else
#define FAL_FLASH_DEV_TABLE                                          
{                                                                    
    &stm32_onchip_flash_128k,                                        
}
#endif

/* ====================== Partition Configuration ========================== */
#ifdef FAL_PART_HAS_TABLE_CFG

/* partition table */
#ifdef BSP_USING_SPI_FLASH_LITTLEFS
#define FAL_PART_TABLE                                                                                                     
{                                                                                                                          
    {FAL_PART_MAGIC_WROD, "spiflash0", "W25Q128", 0 , 16 * 1024 * 1024, 0}, 
}
#else
#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
#endif /* FAL_PART_HAS_TABLE_CFG */
#endif /* _FAL_CFG_H_ */

开启 FlashDB

手把手教 - STM32 单片机 FlashDB 软件包的使用
如果需要时间戳信息,则还需要 开启 RTC

编译报错,解决办法:

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

四、测试

测试用例:
手把手教 - STM32 单片机 FlashDB 软件包的使用

主函数


/*
 * 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>


#define FDB_LOG_TAG "[main]"

static uint32_t boot_count = 0;
static time_t boot_time[10] = {0, 1, 2, 3};
/* default KV nodes */
static struct fdb_default_kv_node default_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 */
static struct fdb_kvdb kvdb = { 0 };
/* TSDB object */
struct fdb_tsdb tsdb = { 0 };
/* counts for simulated timestamp */
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();
}

static fdb_time_t get_time(void)
{
    /* Using the counts instead of timestamp.
     * Please change this function to return RTC time.
     */
    return ++counts;
}

/* defined the LED0 pin: PF9 */
#define LED0_PIN    GET_PIN(C, 3)

int main(void)
{
    /* set LED0 pin mode to output */
    rt_pin_mode(LED0_PIN, PIN_MODE_OUTPUT);
    //fal_init();
    
    fdb_err_t result;

#ifdef FDB_USING_KVDB
    { /* KVDB Sample */
        struct fdb_default_kv default_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 */

#ifdef FDB_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);
    }
}




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

参考

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

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

© 版权声明

相关文章

暂无评论

none
暂无评论...