STM32 利用FlashDB库实现在线扇区数据管理不丢失

STM32 利用FlashDB库实现在线扇区数据管理不丢失


  • 📍FalshDB地址:https://gitee.com/Armink/FlashDB
  • ✨STM32没有片内EEPROM这样的存储区,虽然有备份寄存器,仅可以实现对少量数据的频繁存储,但是依赖备份电源(BAT引脚)为芯片维持供电,才能保持数据的不丢失。FlashDB库利用在线对片内或片外存储扇区进行管理,可以有效的保存数据,掉电不丢失。在不增加像EEPROM外设的情况下,有效利用内部空余的flash空间,进行数据存储,也可以对片外spi flash存储芯片进行数据管理。类似esp32的NVS空间,也有使用键值对,进行数据存储和管理。
  • 🌿FlashDB库,目前包含STM32F1、F4的相关Keil MDK demo现成的工程例程,可以直接测试使用,可以移植到STM32其他型号单片机上使用。目前是支持STM32和esp8266的。
  • 🧨移植指南:https://armink.gitee.io/flashdb/#/zh-cn/porting
  • 🔖个人使用的是STM32F427进行demo测试,测试结果和说明文档内容相符。
    在这里插入图片描述
  • 🥕以下内容是该项目作者的对其的相关内容的介绍:

📘FlashDB使用场景介绍

  • 🎉如今,物联网产品种类越来越多,运行时产生的数据种类及总量及也在不断变大。FlashDB 提供了多样化的数据存储方案,不仅资源占用小,并且存储容量大,非常适合用于物联网产品。下面是主要应用场景:
  • 键值数据库 :
    • 产品参数存储
    • 用户配置信息存储
    • 小文件管理
  • 时序数据库 :
    存储动态产生的结构化数据:如 温湿度传感器采集的环境监测信息,智能手环实时记录的人体健康信息等
    记录运行日志:存储产品历史的运行日志,异常告警的记录等

KVDB 键值数据库介绍

  • 🌿KVDB 的基础功能的使用:

记录开机次数:

void kvdb_basic_sample(fdb_kvdb_t kvdb)
{struct fdb_blob blob;int boot_count = 0;FDB_INFO("==================== kvdb_basic_sample ====================\n");{ /* GET the KV value *//* get the "boot_count" KV value */fdb_kv_get_blob(kvdb, "boot_count", fdb_blob_make(&blob, &boot_count, sizeof(boot_count)));/* the blob.saved.len is more than 0 when get the value successful */if (blob.saved.len > 0) {FDB_INFO("get the 'boot_count' value is %d\n", boot_count);} else {FDB_INFO("get the 'boot_count' failed\n");}}{ /* CHANGE the KV value *//* increase the boot count */boot_count ++;/* change the "boot_count" KV's value */fdb_kv_set_blob(kvdb, "boot_count", fdb_blob_make(&blob, &boot_count, sizeof(boot_count)));FDB_INFO("set the 'boot_count' value to %d\n", boot_count);}FDB_INFO("===========================================================\n");
}
  • 🌿字符串类型 KV

字符串 KV 的相关功能,字符串 KV 作为一个特殊的 KV 类型,其 Key 与 Value 均为字符串,常被用于参数存储、命令存储等可读性要求较高的场景。

void kvdb_type_string_sample(fdb_kvdb_t kvdb)
{FDB_INFO("==================== kvdb_type_string_sample ====================\n");{ /* CREATE new Key-Value */char temp_data[10] = "36C";/* It will create new KV node when "temp" KV not in database. */fdb_kv_set(kvdb, "temp", temp_data);FDB_INFO("create the 'temp' string KV, value is: %s\n", temp_data);}{ /* GET the KV value */char *return_value, temp_data[10] = { 0 };/* Get the "temp" KV value.* NOTE: The return value saved in fdb_kv_get's buffer. Please copy away as soon as possible.*/return_value = fdb_kv_get(kvdb, "temp");/* the return value is NULL when get the value failed */if (return_value != NULL) {strncpy(temp_data, return_value, sizeof(temp_data));FDB_INFO("get the 'temp' value is: %s\n", temp_data);}}{ /* CHANGE the KV value */char temp_data[10] = "38C";/* change the "temp" KV's value to "38C" */fdb_kv_set(kvdb, "temp", temp_data);FDB_INFO("set 'temp' value to %s\n", temp_data);}{ /* DELETE the KV by name */fdb_kv_del(kvdb, "temp");FDB_INFO("delete the 'temp' finish\n");}FDB_INFO("===========================================================\n");
}
  • 遍历所有 KV

遍历 KVDB 中的所有 KV ,用户可以在遍历 KV 时增加自己的处理动作。

  • 首先初始化了 KVDB 的迭代器,然后使用迭代器 API ,将 KVDB 的所有 KV 逐一遍历出来。
    遍历出来的 KV 对象含有 KV 的一些属性,包括:key name, value saved addr, value length 等,用户通过 fdb_blob_read 配合 fdb_kv_to_blob 读取出来,做一些自己的业务处理。
void kvdb_tarversal_sample(fdb_kvdb_t kvdb)
{struct fdb_kv_iterator iterator;fdb_kv_t cur_kv;struct fdb_blob blob;size_t data_size;uint8_t *data_buf;fdb_kv_iterator_init(kvdb, &iterator);while (fdb_kv_iterate(kvdb, &iterator)) {cur_kv = &(iterator.curr_kv);data_size = (size_t) cur_kv->value_len;data_buf = (uint8_t *) malloc(data_size);if (data_buf == NULL) {FDB_INFO("Error: malloc failed.\n");break;}fdb_blob_read((fdb_db_t) kvdb, fdb_kv_to_blob(cur_kv, fdb_blob_make(&blob, data_buf, data_size)));/** balabala do what ever you like with blob...*/free(data_buf);}
}

在这里插入图片描述

  • 二进制大对象 (BLOB)

时序数据库

  • TSDB 基础示例,具体介绍:https://armink.gitee.io/flashdb/#/zh-cn/sample-tsdb-basic
  • 该示例主要演示了 TSDB 的基础功能,包括 TSL(时序记录)的追加、查询及状态修改功能。

samples/tsdb_sample.c ,包含追加、查询及状态修改这几个过程,大致代码如下:

void tsdb_sample(fdb_tsdb_t tsdb)
{struct fdb_blob blob;FDB_INFO("==================== tsdb_sample ====================\n");{ /* APPEND new TSL (time series log) */struct env_status status;/* append new log to TSDB */status.temp = 36;status.humi = 85;fdb_tsl_append(tsdb, fdb_blob_make(&blob, &status, sizeof(status)));FDB_INFO("append the new status.temp (%d) and status.humi (%d)\n", status.temp, status.humi);status.temp = 38;status.humi = 90;fdb_tsl_append(tsdb, fdb_blob_make(&blob, &status, sizeof(status)));FDB_INFO("append the new status.temp (%d) and status.humi (%d)\n", status.temp, status.humi);}{ /* QUERY the TSDB *//* query all TSL in TSDB by iterator */fdb_tsl_iter(tsdb, query_cb, tsdb);}{ /* QUERY the TSDB by time *//* prepare query time (from 1970-01-01 00:00:00 to 2020-05-05 00:00:00) */struct tm tm_from = { .tm_year = 1970 - 1900, .tm_mon = 0, .tm_mday = 1, .tm_hour = 0, .tm_min = 0, .tm_sec = 0 };struct tm tm_to = { .tm_year = 2020 - 1900, .tm_mon = 4, .tm_mday = 5, .tm_hour = 0, .tm_min = 0, .tm_sec = 0 };time_t from_time = mktime(&tm_from), to_time = mktime(&tm_to);size_t count;/* query all TSL in TSDB by time */fdb_tsl_iter_by_time(tsdb, from_time, to_time, query_by_time_cb, tsdb);/* query all FDB_TSL_WRITE status TSL's count in TSDB by time */count = fdb_tsl_query_count(tsdb, from_time, to_time, FDB_TSL_WRITE);FDB_INFO("query count is: %u\n", count);}{ /* SET the TSL status *//* Change the TSL status by iterator or time iterator* set_status_cb: the change operation will in this callback** NOTE: The actions to modify the state must be in orderC.*       like: FDB_TSL_WRITE -> FDB_TSL_USER_STATUS1 -> FDB_TSL_DELETED -> FDB_TSL_USER_STATUS2*       The intermediate states can also be ignored.*       such as: FDB_TSL_WRITE -> FDB_TSL_DELETED*/fdb_tsl_iter(tsdb, set_status_cb, tsdb);}FDB_INFO("===========================================================\n");
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/734815.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

美国签证|附面签相关事项√

小伙伴最近都忙着办签证吧!但是需要注意的是,美国的签证跟其他任何国家的签证不同,并不是办理了就一定拿得到,据说概率是50%左右。所以办理美国签证,不要太着急啦!先来了解一下美国签证的相片该怎么拍叭 ✅…

题目 2073: [STL训练]亲和串

题目描述: 人随着岁数的增长是越大越聪明还是越大越笨,这是一个值得全世界科学家思考的问题,同样的问题Eddy也一直在思考,因为他在很小的时候就知道亲和串如何判断了,但是发现,现在长大了却不知道怎么去判断亲和串了,…

RocketMQ的事务消息流程

什么是事务消息? 事务消息是一种在发送方和接收方之间保证消息传递的一致性和可靠性的消息传递机制。在消息发送过程中,生产者可以将消息发送到消息队列,但不会立即被消费者接收和处理。相反,消息会先进入一种“准备”状态&#x…

用chatgpt写insar地质灾害的论文,重复率只有1.8%,chatgpt4.0写论文不是梦

突发奇想,想用chatgpt写一篇论文,并看看查重率,结果很惊艳,说明是确实可行的,请看下图。 下面是完整的文字内容。 InSAR (Interferometric Synthetic Aperture Radar) 地质灾害监测技术是一种基于合成孔径雷达…

【JavaScript】JavaScript 变量 ① ( JavaScript 变量概念 | 变量声明 | 变量类型 | 变量初始化 | ES6 简介 )

文章目录 一、JavaScript 变量1、变量概念2、变量声明3、ES6 简介4、变量类型5、变量初始化 二、JavaScript 变量示例1、代码示例2、展示效果 一、JavaScript 变量 1、变量概念 JavaScript 变量 是用于 存储数据 的 容器 , 通过 变量名称 , 可以 获取 / 修改 变量 中的数据 ; …

第十五届蓝桥杯模拟赛(第三期)

大家好,我是晴天学长,本次分享,制作不易,本次题解只用于学习用途,如果有考试需要的小伙伴请考完试再来看题解进行学习,需要的小伙伴可以点赞关注评论一波哦!蓝桥杯省赛就要开始了,祝…

【DimPlot】【FeaturePlot】使用小tips

目录 DimPlot函数参数解析 栅格化点图 放大 ggplot2 图例的点,修改图例的标题 FeaturePlot函数参数解析 调整FeaturePlot颜色 分组绘制featureplot 随手笔记,持续更新中。。。 Reference DimPlot函数参数解析 object: 一个Seurat对象,…

工作纪实46-关于微服务的上线发布姿势

蓝绿部署 在部署时,不需要将旧版本的服务停掉,而是将新版本与旧版本同时运行,新版本测试无误之后再将旧版本停掉。这样可以避免再升级的过程中如果失败服务不可用的问题,因为同时部署了两个版本的程序,使得硬件资源是…

【项目笔记】java微服务:黑马头条(day01)

文章目录 环境搭建、SpringCloud微服务(注册发现、服务调用、网关)1)课程对比2)项目概述2.1)能让你收获什么2.2)项目课程大纲2.3)项目概述2.4)项目术语2.5)业务说明 3)技术栈4)nacos环境搭建4.1)虚拟机镜像准备4.2)nacos安装 5)初始工程搭建5.1)环境准备5.2)主体结构 6)登录6.1…

Ubuntu用扩展分区加载home目录步骤

如果你想要将新的磁盘挂载到默认的 /home 目录下,可以按照以下步骤进行操作: 创建挂载点: 首先,确保新磁盘已连接并识别。然后,创建一个临时挂载点,以便将新磁盘挂载到该点。sudo mkdir /mnt/new_home挂载磁…

JavaScript中的Set和Map:理解与使用

🤍 前端开发工程师、技术日更博主、已过CET6 🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 🕠 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 🍚 蓝桥云课签约作者、上架课程《Vue.js 和 E…

C++:类和对象(三)——拷贝构造函数和运算符重载

目录 一、拷贝构造函数 1.概念 2.特性 二、赋值运算符重载 1.运算符重载 2.赋值运算符重载 (1)注意的点: (2)赋值运算符不允许被重载为全局函数,只能重载为类的成员函数 (3)…

代码随想录算法训练营day32

题目:122.买卖股票的最佳时机II、55. 跳跃游戏、45.跳跃游戏II 参考链接:代码随想录 122.买卖股票的最佳时机II 思路:本题我一开始想到的是参考前面的摆动序列,先用坡度图思考,我们要返回最大利润,即要做…

C++ 字符串OJ

目录 1、14. 最长公共前缀 2、 5. 最长回文子串 3、 67. 二进制求和 4、43. 字符串相乘 1、14. 最长公共前缀 思路一:两两字符串进行比较,每次比较过程相同,可以添加一个函数辅助比较,查找最长公共前缀。 class Solution { pu…

【C++】函数模板和类模板

目录 1.泛型编程 2.函数模板 2.1函数模板的定义格式 2.2函数模板的实例化 2.3函数模板参数的匹配原则 3.类模板 3.1类模板的定义格式 3.2类模板的实例化 3.3模板的分离编译 1.泛型编程 泛型编程:编写与类型无关的通用代码,是代码复用的一种手段…

php开发100问?

什么是 PHP?PHP 是一种什么类型的语言?PHP 的优缺点是什么?如何在服务器上配置 PHP?PHP 中的变量是如何声明和使用的?如何在 PHP 中输出文本和变量?什么是 PHP 的数据类型?如何在 PHP 中实现条件…

【前端CSS】CSS的3种基本选择器和5种高级选择器使用方式

目录 前言 基本选择器 1.1 标签选择器 1.2 ID选择器 1.3 类选择器 高级选择器 2.1 并集选择器 2.2 交集选择器 2.3 后代选择器 2.4 子元素选择器 2.5 属性选择器 前言 1W:什么是CSS选择器? CSS选择器由HTML元素的id、class属性或元素名本身以及…

SpringBoot中定时任务、corn表达式

SpringBoot中定时任务、corn表达式 corn表达式网站:https://cron.qqe2.com/ 方法上加上Scheduled(cron表达式) 启动类上加上EnableScheduling 示例 启动类上 启动类加上EnableScheduling开启定时任务。 SpringBootApplication EnableScheduling public class…

vue 在什么情况下在数据发生改变的时候不会触发视图更新

在 Vue 中,通常数据发生变化时,视图会自动更新。但是,有几种情况可能导致数据变化不会触发视图更新: 1.对象属性的添加或删除: Vue 无法检测到对象属性的添加或删除。因为 Vue 在初始化实例时对属性执行了 getter/se…

VUE3 使用axios网络请求

1.新建工程 参考,VUE3 环境搭建:https://blog.csdn.net/LQ_001/article/details/136293795,运行命令 vue create vue-demo 2.引入axios 不管何种引用,都要在工程中安装 axios 包。安装命令:npm install --save axio…