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.hqwc.cn/news/527918.html

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

相关文章

【数据分享】2013-2022年全国范围逐年CO栅格数据(免费获取)

空气质量数据是在我们日常研究中经常使用的数据!之前我们给大家分享了2000-2022年全国范围逐年的PM2.5栅格数据和2013-2022年全国范围逐年SO2栅格数据(可查看之前的文章获悉详情)。 本次我们给大家带来的是2013-2022年全国范围的逐年的CO栅格…

人民网(人民号)如何发布文章新闻,人民网怎么投稿,附人民日报价格多少钱

最近有很多朋友问到一个问题,就是人民网如何发布文章新闻,以及人民网怎么投稿。作为一个专业的媒体发稿平台,媒介多多网为大家提供了一个非常好的解决方案。 首先,人民网作为我国权威媒体之一,其新闻发布渠道非常严谨…

详解前端登录流程:实现原理与最佳实践

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

Unity使用Addressable热更新

先看热更新的gif: Addressable是Unity推出的打ab包方案。不需要手动写AB打包脚手架了,不需要关心依赖,这也简化了ab热更新的流程。Addressable打包需要先将资源放入group中,按group来打包,每个group对应一个ScriptableObject的配置…

VLAN FAQ

如何快速查看所有接口的接口类型和缺省VLAN&#xff1f; 可通过命令display port vlan查看到设备上所有接口的接口类型和缺省VLAN。例如&#xff1a; V200R005及后续版本<HUAWEI> display port vlan Port Link Type PVID Trunk VLAN List --…

虚拟机实验环境配置与使用(计算机系统2)

一、 实验目标&#xff1a; 熟悉Linux上C程序的编译和调试工具&#xff0c;包括以下内容&#xff1a; 1. 了解Linux操作系统及其常用命令 2. 掌握编译工具gcc的基本用法 3. 掌握使用gdb进行程序调试 二、实验环境与工件 1.个人电脑 2. Fedora 13 Linux 操作系统 3. gcc…

【C语言】【LeetCode】循环队列

目录 &#xff08;一&#xff09;题目描述 &#xff08;二&#xff09;数据结构的选择 &#xff08;三&#xff09;函数接口的分析实现 正文开始&#xff1a; &#xff08;一&#xff09;题目描述 题目链接&#xff1a;622. 设计循环队列 设计你的循环队列实现。 循环队列是…

【设计模式】(四)设计模式之工厂模式

1. 工厂模式介绍 工厂模式&#xff08;Factory Pattern&#xff09;是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式&#xff0c;它提供了一种创建对象的最佳方式。 工厂模式有三种实现方式&#xff1a; 简单工厂模式工厂方法模式抽象工厂模式 2. 工厂方…

【MATLAB第100期】基于MATLAB的多种改进拉丁超立方LHS数据抽样方法

【MATLAB第100期】基于MATLAB的多种改进拉丁超立方LHS数据抽样方法 一、LHS种类 1、LHS 使用随机搜索生成拉丁超立方体样本。LHS函数特别适用于非常大的设计&#xff0c;当本机MATLAB函数内存不足时。这可能取决于MATLAB版本和所用机器的配置。当尝试运行“lhsdesign”但未成…

ThreadLocal使用,配合拦截器HandlerInterceptor使用

ThreadLocal使用&#xff0c;配合拦截器HandlerInterceptor使用 ThreadLocal的使用场景通常涉及多线程环境下需要为每个线程保留独立状态的情况。它提供了一种简单的方式来管理线程本地变量&#xff0c;使得每个线程都可以独立地访问和修改自己的变量副本&#xff0c;而不会影…

线程的魔法:揭开现代操作系统并发执行的面纱

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢&#xff0c;在这里我会分享我的知识和经验。&am…

算法第二十六天-删除有序数组中的重复项Ⅱ

删除有序数组中的重复项 题目要求 解题思路 题目要求中提到原地修改&#xff0c;那么肯定需要一个指针指向当前即将放置元素的位置&#xff0c;需要另外一个指针向后遍历所有元素&#xff0c;所以[双指针]解法呼之欲出。 慢指针slow&#xff1a;指向当前元素放置的位置&…