SFDB-专为记录型数据存储而生

Simple and Fast ⚡


SFDB 即 Simple File Database, 一个 简单 的文件型数据库,使用 简单,移植 简单,功能 简单,原理 简单,一切都很 简单,一切都很 快。适用于 固定长度 的 记录型 数据存储,类似于时序数据库,可用于存储历史记录、报警记录、日志等。

如果你的项目需要记录数据,且数据的长度或最大长度是固定的,已存入的数据不需要修改,同时需要快速清空和基于 记录条数 (从第几条开始,查多少条数据)的查询,而你的项目恰好有个文件系统,那么 SFDB 可能适合你。

特性

  • 使用文件进行存储

  • 简单的数据写入接口

  • 到达上限时自动从头覆盖

  • 支持顺序与倒序查询

  • 支持从任意条数开始查询

  • 支持清空(重置)数据库


使用篇


本篇基于 HMI-Board 来演示 SFDB 的使用。

创建工程

1. 使用 RT-Thread Studio 基于 HMI-Board 开发板创建一个项目。选项都保持默认即可。

2. 创建完成后打开 RT-Thread Settings,选中 Enable SDCARD filesystem 打开文件系统。

3. 在组件配置中打开 RTC 设备驱动,并使能 使用软件模拟RTC设备选项(提供给文件系统使用)。

4. 添加 SFDB 软件包。

5. 勾选 SFDB 配置项的 Use sfdb example 打开示例代码。

6. 全部配置完进行保存,当前软件包会就被应用到项目中。

编译及下载

在编译之前,我们需要修改一下例程的配置,来适配我们的文件系统目录。打开 packages/sfdb-v0.0.2/examples/rtthread/example.c,找到宏定义 TEST_FILE_PATH,将其修改为 /test.sdb

此处需要注意,sfdb 在不存在当前文件时会自动创建,但如果路径中包含有多层目录,则这些文件夹必须存在,即 sfdb 不会自动创建文件夹。

修改完路径配置后即可编译代码。

控制台看到上图的信息即编译成功,此时进行程序烧录。

运行示例

程序下载完成后连接并打开终端,按下 TAB 键可以看到命令行中出现了两条 SFDB 的命令:

此时说明 SFDB 已经成功运行起来了。而这两条命令作用如下:

  • sfdb_test:启动 SFDB 写入测试,系统会持续写入到设定的上限值

  • sfdb_read:读取测试数据库内的数据。

写入测试

例程中设定的数据库存储上限为10000条,同时会写入10100条数据。接下来我们使用 sfdb_test 来启动写入测试:

可以看到日志中完整写入了10100条数据,而且每条数据的写入时间也都维持在 5-10 ms,并没有随着写入数量的增多而增大。

读取测试

sfdb_read命令的形式有两种:

  • sfdb_read 读取数据库基本信息

  • sfdb_read [offset] [number] [order(0:asc 1:dsc)] 根据orderoffset中读取number条数据

1. 基本信息读取

基本信息不需要输入参数,直接 sfdb_read 即可:

可以看到,数据库的基本信息包括:

  1. 当前最新数据的索引(容量10000,写入10100,多出来的将会从最老的数据开始覆盖)

  2. 数据库中的总有效数据

  3. 每条数据的长度

这些数据与我们的配置和写入也是完全一致的,说明我们刚才数据库的创建及写入操作是成功的。

2. 数据读取

读取的 order 为读取顺序,其中0为从最老的数据开始读,1为从最新的数据开始读:

- 1. 正序读取(从旧到新)


- 2. 倒序读取(从新到旧)

- 3. 注意

在倒序读取模式下,由于保留了读取性能, buf 的数据仍然是顺序的,使用者需要手动处理 buf 中的数据顺序。当数据 1-100 依次存入时,若以倒序从 offset 为 0 的位置读取 10 条数据,存入 buf 中,buf 中的数据顺序为 91 92 93 94 95 96 97 98 99 100 ,而非 100 99 98 97 96 95 94 93 92 91。使用者可以在应用层可以参考例程通过索引倒转的形式实现数据顺序的倒转,如下:

1ret = sfdb_read(&sfdb, data_buf, data_sz, offset, number, order);
2 for (int i = 0; i < ret; i++) {
3     if (order == SFDB_READ_ASC) {
4         print_index = i;
5     } else {
6         print_index = ret - i - 1;
7     }
8     SF_LOG("%-5d:%s", offset + i + 1, (char *)&data_buf[print_index * sfdb.hdr.record_len]);
9 }

移植篇


如果需要在别的平台使用SFDB,移植起来也是非常方便。仅需参考 sfdb_port.c 实现 sfdb_fs_t 里面的文件操作接口,以及在 sfdb_port.h 中包含当前平台所需要的头文件并实现 SF_MEMCPYSF_MEMSETSF_LOG 宏定义即可。

接口结构如下:

1typedef struct _db_fs {
2    int (*op)(struct _sfdb *db, const char *path, int flags);  // Open file
3    int (*cl)(void *fd);                                       // Close file
4    int (*sy)(void *fd);                                       // Sync file
5    size_t (*rd)(void *fd, void *buf, size_t len);             // Read file
6    size_t (*wr)(void *fd, const void *buf, size_t len);       // Write file
7    size_t (*sk)(void *fd, size_t offset);                     // Set file position
8    int (*rm)(const char *path);                               // Delete file
9sfdb_fs_t;

RT-Thread 下的移植示例:

1// sfdb_port.c
2static int fs_open(sfdb_t *db, const char *path, int flags) {
3    int oflags = O_RDWR;
4    if (flags & SFDB_O_CREATE) oflags |= O_CREAT;
5    db->fd = (void *)open(path, oflags);
6    if ((int)db->fd < 0) {
7        return -1;
8    } else {
9        return 0;
10    }
11}
12static int fs_close(void *fd) {
13    if (fd >= 0) {
14        close((int)fd);
15        return 0;
16    } else {
17        SF_LOG("invalid fd %d, close failed", (int)fd);
18        return -1;
19    }
20}
21static int fs_sync(void *fd) return fsync((int)fd); }
22static size_t fs_read(void *fd, void *buf, size_t len) return read((int)fd, buf, len); }
23static size_t fs_write(void *fd, const void *buf, size_t len) return write((int)fd, buf, len); }
24static size_t fs_seek(void *fd, size_t offset) {
25    int ret = 0;
26    ret = lseek((int)fd, offset, SEEK_SET);
27    if (ret < 0return 0;
28    return ret;
29}
30static int fs_remove(const char *path) return unlink(path); }
31sfdb_fs_t sfdb_fs = {
32    .op = fs_open,
33    .cl = fs_close,
34    .sy = fs_sync,
35    .rd = fs_read,
36    .wr = fs_write,
37    .sk = fs_seek,
38    .rm = fs_remove,
39};

1// sfdb_port.h
2#include 
3#include 
4#include 
5#include 
6#include 
7#include 
8#define SF_MEMCPY rt_memcpy
9#define SF_MEMSET rt_memset
10#define SF_LOG(format, ...) rt_kprintf("[SFDB]:" format "\r\n", ##__VA_ARGS__)


源码仓库


详细的API说明可以到源码的仓库查看:

Github: https://github.com/WKJay/sfdb

Gitee: https://gitee.com/wangjunjie997


———————End——————



👇 点击阅读原文进入官网

RTThread物联网操作系统 帮助您了解RT-Thread相关的资讯.
评论
  • 嘿,咱来聊聊RISC-V MCU技术哈。 这RISC-V MCU技术呢,简单来说就是基于一个叫RISC-V的指令集架构做出的微控制器技术。RISC-V这个啊,2010年的时候,是加州大学伯克利分校的研究团队弄出来的,目的就是想搞个新的、开放的指令集架构,能跟上现代计算的需要。到了2015年,专门成立了个RISC-V基金会,让这个架构更标准,也更好地推广开了。这几年啊,这个RISC-V的生态系统发展得可快了,好多公司和机构都加入了RISC-V International,还推出了不少RISC-V
    丙丁先生 2025-01-21 12:10 1229浏览
  • 随着AI大模型训练和推理对计算能力的需求呈指数级增长,AI数据中心的网络带宽需求大幅提升,推动了高速光模块的发展。光模块作为数据中心和高性能计算系统中的关键器件,主要用于提供高速和大容量的数据传输服务。 光模块提升带宽的方法有两种:1)提高每个通道的比特速率,如直接提升波特率,或者保持波特率不变,使用复杂的调制解调方式(如PAM4);2)增加通道数,如提升并行光纤数量,或采用波分复用(CWDM、LWDM)。按照传输模式,光模块可分为并行和波分两种类型,其中并行方案主要应用在中短距传输场景中成本
    hycsystembella 2025-01-25 17:24 473浏览
  • 高速先生成员--黄刚这不马上就要过年了嘛,高速先生就不打算给大家上难度了,整一篇简单但很实用的文章给大伙瞧瞧好了。相信这个标题一出来,尤其对于PCB设计工程师来说,心就立马凉了半截。他们辛辛苦苦进行PCB的过孔设计,高速先生居然说设计多大的过孔他们不关心!另外估计这时候就跳出很多“挑刺”的粉丝了哈,因为翻看很多以往的文章,高速先生都表达了过孔孔径对高速性能的影响是很大的哦!咋滴,今天居然说孔径不关心了?别,别急哈,听高速先生在这篇文章中娓娓道来。首先还是要对各位设计工程师的设计表示肯定,毕竟像我
    一博科技 2025-01-21 16:17 241浏览
  • 飞凌嵌入式基于瑞芯微RK3562系列处理器打造的FET3562J-C全国产核心板,是一款专为工业自动化及消费类电子设备设计的产品,凭借其强大的功能和灵活性,自上市以来得到了各行业客户的广泛关注。本文将详细介绍如何启动并测试RK3562J处理器的MCU,通过实际操作步骤,帮助各位工程师朋友更好地了解这款芯片。1、RK3562J处理器概述RK3562J处理器采用了4*Cortex-A53@1.8GHz+Cortex-M0@200MHz架构。其中,4个Cortex-A53核心作为主要核心,负责处理复杂
    飞凌嵌入式 2025-01-24 11:21 293浏览
  • 故障现象 一辆2007款日产天籁车,搭载VQ23发动机(气缸编号如图1所示,点火顺序为1-2-3-4-5-6),累计行驶里程约为21万km。车主反映,该车起步加速时偶尔抖动,且行驶中加速无力。 图1 VQ23发动机的气缸编号 故障诊断接车后试车,发动机怠速运转平稳,但只要换挡起步,稍微踩下一点加速踏板,就能感觉到车身明显抖动。用故障检测仪检测,发动机控制模块(ECM)无故障代码存储,且无失火数据流。用虹科Pico汽车示波器测量气缸1点火信号(COP点火信号)和曲轴位置传感器信
    虹科Pico汽车示波器 2025-01-23 10:46 321浏览
  • 前篇文章中『服务器散热效能不佳有解吗?』提到气冷式的服务器其散热效能对于系统稳定度是非常重要的关键因素,同时也说明了百佳泰对于散热效能能提供的协助与服务。本篇将为您延伸说明我们如何进行评估,同时也会举例在测试过程中发现的问题及改善后的数据。AI服务器的散热架构三大重点:GPU导风罩:尝试不同的GPU导风罩架构,用以集中服务器进风量,加强对GPU的降温效果。GPU托盘:改动GPU托盘架构,验证出风面积大小对GPU散热的影想程度。CPU导风罩:尝试封闭CPU导风罩间隙,集中风流,验证CPU降温效果。
    百佳泰测试实验室 2025-01-24 16:58 189浏览
  •     IPC-2581是基于ODB++标准、结合PCB行业特点而指定的PCB加工文件规范。    IPC-2581旨在替代CAM350格式,成为PCB加工行业的新的工业规范。    有一些免费软件,可以查看(不可修改)IPC-2581数据文件。这些软件典型用途是工艺校核。    1. Vu2581        出品:Downstream     
    电子知识打边炉 2025-01-22 11:12 465浏览
  • 不让汽车专美于前,近年来哈雷(Harley-Davidson)和本田(Honda)等大型重型机车大厂的旗下车款皆已陆续配备车载娱乐系统与语音助理,在路上也有越来越多的普通机车车主开始使用安全帽麦克风,在骑车时透过蓝牙连线执行语音搜寻地点导航、音乐播放控制或免持拨打接听电话等各种「机车语音助理」功能。客户背景与面临的挑战以本次分享的客户个案为例,该客户是一个跨国车用语音软件供货商,过往是与车厂合作开发前装车机为主,且有着多年的「汽车语音助理」产品经验。由于客户这次是首度跨足「机车语音助理」产品,因
    百佳泰测试实验室 2025-01-24 17:00 194浏览
  • 临近春节,各方社交及应酬也变得多起来了,甚至一月份就排满了各式约见。有的是关系好的专业朋友的周末“恳谈会”,基本是关于2025年经济预判的话题,以及如何稳定工作等话题;但更多的预约是来自几个客户老板及副总裁们的见面,他们为今年的经济预判与企业发展焦虑而来。在聊天过程中,我发现今年的聊天有个很有意思的“点”,挺多人尤其关心我到底是怎么成长成现在的多领域风格的,还能掌握一些经济趋势的分析能力,到底学过哪些专业、在企业管过哪些具体事情?单单就这个一个月内,我就重复了数次“为什么”,再辅以我上次写的:《
    牛言喵语 2025-01-22 17:10 494浏览
  • 书接上回:【2022年终总结】阳光总在风雨后,启航2023-面包板社区  https://mbb.eet-china.com/blog/468701-438244.html 总结2019,松山湖有个欧洲小镇-面包板社区  https://mbb.eet-china.com/blog/468701-413397.html        2025年该是总结下2024年的喜怒哀乐,有个好的开始,才能更好的面对2025年即将
    liweicheng 2025-01-24 23:18 350浏览
  • 项目展示①正面、反面②左侧、右侧项目源码:https://mbb.eet-china.com/download/316656.html前言为什么想到要做这个小玩意呢,作为一个死宅,懒得看手机,但又想要抬头就能看见时间和天气信息,于是就做个这么个小东西,放在示波器上面正好(示波器外壳有个小槽,刚好可以卡住)功能主要有,获取国家气象局的天气信息,还有实时的温湿度,主控采用ESP32,所以后续还可以开放更多奇奇怪怪的功能,比如油价信息、股票信息之类的,反正能联网可操作性就大多了原理图、PCB、面板设计
    小恶魔owo 2025-01-25 22:09 615浏览
我要评论
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦