[单片机芯片] 【沁恒CH32V307 RISC-V开发板测评】基于外部FLASH移植嵌入式数据库--FlashDB

[复制链接]
608|0
星享社 发表于 2025-9-24 20:13 | 显示全部楼层 |阅读模式
本帖最后由 星享社 于 2025-9-24 20:15 编辑

       嵌入式系统开发中,高效、可靠的数据存储管理一直是开发者面临的核心挑战之一。尤其是在使用CH32V307VCT6这类基于RISC-V内核的高性能MCU时,如何充分发挥其硬件优势,实现数据的快速读写、断电保护与高效管理,直接关系到产品的稳定性和用户体验。传统的直接读写Flash方式不仅繁琐,还容易因磨损均衡处理不当或意外断电导致数据丢失或文件系统损坏。因此,为CH32V307VCT6移植一个轻量级、高可靠性的嵌入式数据库(Embedded Database)显得至关重要
本次测评将聚焦于​​FLASH-DB​​的移植与实践。FLASH-DB正是一款为解决上述痛点而生的轻量级嵌入式数据库,它专为资源受限的MCU环境设计,无需复杂的文件系统支持,可直接在Flash上运行,为CH32V307VCT6的存储管理提供了优雅而高效的解决方案。
一、为什么选择Flash-DB
     1、规避传统存储弊端​​:直接读写Flash需手动管理扇区擦除、写入地址,易出错且难以保证数据一致性。FLASH-DB提供了类似键值对(Key-Value)的存储接口,极大简化了开发流程。
​​     2、增强数据可靠性​​:内置磨损均衡(Wear Leveling)算法,自动均衡Flash块的使用,延长芯片寿命;支持断电保护,确保数据在意外情况下不会丢失或损坏。
​​     3、提升开发效率​​:提供简洁的API接口,让开发者无需关注底层存储细节,可专注于业务逻辑开发,缩短项目周期。
二、FLASH-DDB简介与核心特点​
​​        FLASH-DB是一款开源的轻量级嵌入式数据库,它借鉴了Linux内核的MTD(Memory Technology Device)架构思想,实现了高度模块化和可移植性。其核心特点包括:
​​    1、极致的轻量级​​:代码体积极小,对RAM和ROM的资源占用极低,非常适合CH32V307VCT6这类MCU的运行环境。
    2、​​强大的磨损均衡​​:采用高效算法动态管理Flash扇区,显著提升Flash存储芯片的使用寿命。
​​    3、可靠的数据管理​​:支持掉电保护,通过精巧的设计确保写操作过程中发生断电时,数据不会丢失,数据库完整性得以保障。
​​    4、简洁的KV存储模型​​:提供类似NoSQL的键值对存储方式,支持多种数据类型,接口简单易用,学习成本低。
    5、​​良好的可移植性​​:数据库底层与硬件平台解耦,只需实现简单的驱动接口(如读、写、擦除)即可快速移植到新的硬件平台,如本次的RISC-V内核CH32V307VCT6
三、移植过程
1、在gitee官网上下载Flash-DB源码FlashDB: 一款支持 KV 数据和时序数据的超轻量级数据库和支持外部FLASH通用驱动源码SFUD: 一款使用 JEDEC SFDP 标准的串行 (SPI) Flash 通用驱动库下载之后解压如下:
7303768d3df0f6fa42.png
5182968d3df22bfc0c.png
2、新建工程
3、在工程目录下新建Flash-Db、FAL、SFUD文件夹,复制相关文件到该目录,如下
Flash-Db目录文件
5544068d3df2f7ce65.png
FAL文件
946968d3df3b365b1.png
并复制fal_cfg.h、fal_flash_sfud_port.c到FAL的INC和SRC目录
2592468d3df452a673.png
复制FLASH-DB源码目录下的samples文件夹到工程目录下
9576168d3df52e9ec6.png
复制SFUD源码库中inc/src以及port中得sfud_port.c到工程目录下的SFUD目录下
1762368d3df633daa5.png
4、添加相关头文件
4669968d3df84afaaf.png
5、修改外部FLASH通用驱动相关文件
1)主要修改发送与接收数据的函数,修改之后的如下
sfud_port.c文件
  1. /*
  2. * This file is part of the Serial Flash Universal Driver Library.
  3. *
  4. * Copyright (c) 2016-2018, Armink, <armink.ztl@gmail.com>
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining
  7. * a copy of this software and associated documentation files (the
  8. * 'Software'), to deal in the Software without restriction, including
  9. * without limitation the rights to use, copy, modify, merge, publish,
  10. * distribute, sublicense, and/or sell copies of the Software, and to
  11. * permit persons to whom the Software is furnished to do so, subject to
  12. * the following conditions:
  13. *
  14. * The above copyright notice and this permission notice shall be
  15. * included in all copies or substantial portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
  18. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  19. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  20. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  21. * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  22. * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  23. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  24. *
  25. * Function: Portable interface for each platform.
  26. * Created on: 2016-04-23
  27. */

  28. #include <sfud.h>
  29. #include <stdarg.h>
  30. #include "debug.h"

  31. typedef struct {
  32.     SPI_TypeDef *spix;
  33.     GPIO_TypeDef *cs_gpiox;
  34.     uint16_t cs_gpio_pin;
  35. } spi_user_data, *spi_user_data_t;

  36. static char log_buf[32];

  37. void sfud_log_debug(const char *file, const long line, const char *format, ...);

  38. static void spi_lock(const sfud_spi *spi) {
  39.     //__disable_irq();
  40. }

  41. static void spi_unlock(const sfud_spi *spi) {
  42.     //__enable_irq();
  43. }

  44. /**
  45. * SPI write data then read data
  46. */
  47. static sfud_err spi_write_read(const sfud_spi *spi,const uint8_t *write_buf, size_t write_size, uint8_t *read_buf,
  48.         size_t read_size) {
  49.     sfud_err result = SFUD_SUCCESS;
  50.     uint8_t send_data, read_data;
  51.     spi_user_data_t spi_dev = (spi_user_data_t) spi->user_data;

  52.     if (write_size) {
  53.         SFUD_ASSERT(write_buf);
  54.     }
  55.     if (read_size) {
  56.         SFUD_ASSERT(read_buf);
  57.     }
  58.     /**
  59.      * add your spi write and read code
  60.      */
  61.     GPIO_WriteBit(spi_dev->cs_gpiox,spi_dev->cs_gpio_pin, Bit_RESET);//片选

  62.     /* 开始读写数据 */
  63.     for (size_t i = 0, retry_times; i < write_size + read_size; i++) {
  64.         /* 先写缓冲区中的数据到 SPI 总线,数据写完后,再写 dummy(0xFF) 到 SPI 总线 */
  65.         if (i < write_size) {
  66.             send_data = *write_buf++;
  67.         } else {
  68.             send_data = SFUD_DUMMY_DATA;
  69.         }
  70.         /* 发送数据 */
  71.         retry_times = 1000;

  72.         while (SPI_I2S_GetFlagStatus(spi_dev->spix,SPI_I2S_FLAG_TXE) == RESET) {
  73.             SFUD_RETRY_PROCESS(NULL, retry_times, result);
  74.         }
  75.         if (result != SFUD_SUCCESS) {
  76.             goto exit;
  77.         }
  78.         SPI_I2S_SendData(spi_dev->spix,send_data);

  79.         retry_times = 1000;
  80.         while (SPI_I2S_GetFlagStatus(spi_dev->spix, SPI_I2S_FLAG_RXNE) == RESET) {
  81.             SFUD_RETRY_PROCESS(NULL, retry_times, result);
  82.         }
  83.         if (result != SFUD_SUCCESS) {
  84.             goto exit;
  85.         }
  86.         read_data = SPI_I2S_ReceiveData(spi_dev->spix);
  87.         /* 写缓冲区中的数据发完后,再读取 SPI 总线中的数据到读缓冲区 */
  88.         if (i >= write_size) {
  89.             *read_buf++ = read_data;
  90.         }
  91.     }

  92. exit:
  93.     GPIO_WriteBit(spi_dev->cs_gpiox,spi_dev->cs_gpio_pin, Bit_SET);//片选

  94.     return result;
  95. }

  96. /* about 100 us delay */
  97. static void retry_delay_100us(void) {
  98.     uint32_t delay = 100;
  99.     while(delay--);
  100. }

  101. #ifdef SFUD_USING_QSPI
  102. /**
  103. * read flash data by QSPI
  104. */
  105. static sfud_err qspi_read(const struct __sfud_spi *spi, uint32_t addr, sfud_qspi_read_cmd_format *qspi_read_cmd_format,
  106.         uint8_t *read_buf, size_t read_size) {
  107.     sfud_err result = SFUD_SUCCESS;

  108.     /**
  109.      * add your qspi read flash data code
  110.      */

  111.     return result;
  112. }
  113. #endif /* SFUD_USING_QSPI */
  114. static spi_user_data spi1 = { .spix = FLASH_SPI, .cs_gpiox = FLASH_CS_GPIO_Port, .cs_gpio_pin = FLASH_CS_Pin };
  115. sfud_err sfud_spi_port_init(sfud_flash *flash) {
  116.     sfud_err result = SFUD_SUCCESS;

  117.     /**
  118.      * add your port spi bus and device object initialize code like this:
  119.      * 1. rcc initialize
  120.      * 2. gpio initialize
  121.      * 3. spi device initialize
  122.      * 4. flash->spi and flash->retry item initialize
  123.      *    flash->spi.wr = spi_write_read; //Required
  124.      *    flash->spi.qspi_read = qspi_read; //Required when QSPI mode enable
  125.      *    flash->spi.lock = spi_lock;
  126.      *    flash->spi.unlock = spi_unlock;
  127.      *    flash->spi.user_data = &spix;
  128.      *    flash->retry.delay = null;
  129.      *    flash->retry.times = 10000; //Required
  130.      */

  131.     flash->spi.wr = spi_write_read;
  132.     flash->spi.lock = spi_lock;
  133.     flash->spi.unlock = spi_unlock;
  134.     flash->spi.user_data = &spi1;
  135.     flash->retry.delay = retry_delay_100us;
  136.     flash->retry.times = 60 * 10000;

  137.     return result;
  138. }

  139. /**
  140. * This function is print debug info.
  141. *
  142. * @param file the file which has call this function
  143. * @param line the line number which has call this function
  144. * @param format output format
  145. * @param ... args
  146. */
  147. void sfud_log_debug(const char *file, const long line, const char *format, ...) {
  148.     va_list args;

  149.     /* args point to the first variable parameter */
  150.     va_start(args, format);
  151.     printf("[SFUD](%s:%ld) ", file, line);
  152.     /* must use vprintf to print */
  153.     vsnprintf(log_buf, sizeof(log_buf), format, args);
  154.     printf("%s\n", log_buf);
  155.     va_end(args);
  156. }

  157. /**
  158. * This function is print routine info.
  159. *
  160. * @param format output format
  161. * @param ... args
  162. */
  163. void sfud_log_info(const char *format, ...) {
  164.     va_list args;

  165.     /* args point to the first variable parameter */
  166.     va_start(args, format);
  167.     printf("[SFUD]");
  168.     /* must use vprintf to print */
  169.     vsnprintf(log_buf, sizeof(log_buf), format, args);
  170.     printf("%s\n", log_buf);
  171.     va_end(args);
  172. }
2)修改sfud_cfg.h,主要配置设备表
  1. /*
  2. * @Author: liuxingguo 1017041908@qq.com
  3. * @Date: 2024-05-16 17:33:32
  4. * @LastEditors: liuxingguo 1017041908@qq.com
  5. * @LastEditTime: 2024-06-11 17:24:01
  6. * @FilePath: \BG9801PG-02H-MCU-MB-AA1X0\User\SFUD\Inc\sfud_cfg.h
  7. * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
  8. */
  9. /*
  10. * This file is part of the Serial Flash Universal Driver Library.
  11. *
  12. * Copyright (c) 2016-2018, Armink, <armink.ztl@gmail.com>
  13. *
  14. * Permission is hereby granted, free of charge, to any person obtaining
  15. * a copy of this software and associated documentation files (the
  16. * 'Software'), to deal in the Software without restriction, including
  17. * without limitation the rights to use, copy, modify, merge, publish,
  18. * distribute, sublicense, and/or sell copies of the Software, and to
  19. * permit persons to whom the Software is furnished to do so, subject to
  20. * the following conditions:
  21. *
  22. * The above copyright notice and this permission notice shall be
  23. * included in all copies or substantial portions of the Software.
  24. *
  25. * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
  26. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  27. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  28. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  29. * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  30. * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  31. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  32. *
  33. * Function: It is the configure head file for this library.
  34. * Created on: 2016-04-23
  35. */

  36. #ifndef _SFUD_CFG_H_
  37. #define _SFUD_CFG_H_

  38. #include "debug.h"
  39. //#define SFUD_DEBUG_MODE
  40. //#define SFUD_INFO
  41. #define FLASH_SPI SPI3   //这里定义SPI
  42. //使能SFDP:JEDEC标准(JESD216)标准接口
  43. //注意:关闭后只会查询该库在 /sfud/inc/sfud_flash_def.h 中提供的Flash 信息表
  44. //这样虽然会降低软件的适配性,但减少代码量
  45. #define SFUD_USING_SFDP

  46. //#define SFUD_USING_FAST_READ  只有在QSPI下有用

  47. //是否使用该库自带的 Flash 参数信息表注意:关闭后该库只驱动支持 SFDP 规范的 Flash,也会适当的降低部分代码量。
  48. //另外 2.3.2 及 2.3.3 这两个宏定义至少定义一种,也可以两种方式都选择
  49. #define SFUD_USING_FLASH_INFO_TABLE

  50. enum {
  51.     SFUD_W25Q_DEVICE_INDEX = 0,
  52. };
  53. //定义设备表
  54. #define SFUD_FLASH_DEVICE_TABLE                                                \
  55. {                                                                              \
  56.     [SFUD_W25Q_DEVICE_INDEX] = {.name = "W25Q32JV", .spi.name = "SPI3"},           \
  57. }

  58. //#define SFUD_USING_QSPI

  59. #endif /* _SFUD_CFG_H_ */
3)修改fal_cfg.h
主要根据需要修改定义fal_flash_dev设备结构体
  1. /*
  2. * Copyright (c) 2020, Armink, <armink.ztl@gmail.com>
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #ifndef _FAL_CFG_H_
  7. #define _FAL_CFG_H_

  8. #define FAL_DEBUG 1
  9. #define FAL_PART_HAS_TABLE_CFG
  10. #define FAL_USING_SFUD_PORT

  11. /* ===================== Flash device Configuration ========================= */
  12. extern struct fal_flash_dev nor_flash0;

  13. /* flash device table */
  14. #define FAL_FLASH_DEV_TABLE                                          \
  15. {                                                                    \
  16.     &nor_flash0,                                                     \
  17. }

  18. /* ====================== Partition Configuration ========================== */
  19. #ifdef FAL_PART_HAS_TABLE_CFG
  20. /* partition table */
  21. #define FAL_PART_TABLE                                                                 \
  22. {                                                                                      \
  23.     {FAL_PART_MAGIC_WORD,  "fdb_tsdb1",       "norflash0",           0, 1024*1024, 0}, \
  24.     {FAL_PART_MAGIC_WORD,  "fdb_kvdb1",       "norflash0",   1024*1024, 1024*1024, 0}, \
  25. }
  26. #endif /* FAL_PART_HAS_TABLE_CFG */

  27. #endif /* _FAL_CFG_H_ */
4)修改sfud.c中flash相关参数配置,如下


  1. sfud_flash sfud_norflash0 = {
  2.         .name = "norflash0",
  3.         .spi.name = "SPI3",
  4.         .chip = { "W25Q32JV", SFUD_MF_ID_WINBOND, 0x40, 0x17, 4L * 1024L * 1024L, SFUD_WM_PAGE_256B, 4096, 0x20 } };
同时封装一下初始化SFUD的函数
  1. int spi_sfud_init(void)
  2. {
  3.     /* SFUD initialize */
  4.     if (sfud_device_init(&sfud_norflash0) == SFUD_SUCCESS) {
  5.         return 0;
  6.     } else {
  7.         return -1;
  8.     }
  9. }
5)在fdb_cfg.h中定义FDB_WRITE_GRAN的写入粒度的值否则会报错
  1. define FDB_WRITE_GRAN 1        /* @NOTE you must define it for a value */
6、在主函数中添加初始化,代码如下
  1. /********************************** (C) COPYRIGHT *******************************
  2. * File Name          : main.c
  3. * Author             : WCH
  4. * Version            : V1.0.0
  5. * Date               : 2021/06/06
  6. * Description        : Main program body.
  7. *********************************************************************************
  8. * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
  9. * Attention: This software (modified or not) and binary are used for
  10. * microcontroller manufactured by Nanjing Qinheng Microelectronics.
  11. *******************************************************************************/

  12. /*
  13. *@Note
  14. USART Print debugging routine:
  15. USART1_Tx(PA9).
  16. This example demonstrates using USART1(PA9) as a print debug port output.

  17. */

  18. #include "debug.h"
  19. #include <flashdb.h>
  20. #include <sfud.h>
  21. /* Global typedef */

  22. /* Global define */

  23. /* Global Variable */

  24. #define FDB_LOG_TAG "[main]"

  25. static uint32_t boot_count = 0;
  26. static time_t boot_time[10] = {0, 1, 2, 3};
  27. /* default KV nodes */
  28. static struct fdb_default_kv_node default_kv_table[] = {
  29.         {"username", "armink", 0}, /* string KV */
  30.         {"password", "123456", 0}, /* string KV */
  31.         {"boot_count", &boot_count, sizeof(boot_count)}, /* int type KV */
  32.         {"boot_time", &boot_time, sizeof(boot_time)},    /* int array type KV */
  33. };
  34. /* KVDB object */
  35. static struct fdb_kvdb kvdb = { 0 };
  36. /* TSDB object */
  37. struct fdb_tsdb tsdb = { 0 };
  38. /* counts for simulated timestamp */
  39. static int counts = 0;

  40. extern void kvdb_basic_sample(fdb_kvdb_t kvdb);
  41. extern void kvdb_type_string_sample(fdb_kvdb_t kvdb);
  42. extern void kvdb_type_blob_sample(fdb_kvdb_t kvdb);
  43. extern void tsdb_sample(fdb_tsdb_t tsdb);

  44. void SPI_Flash_Init(void);
  45. int8_t Flash_DbTest(void);

  46. static void lock(fdb_db_t db)
  47. {
  48.     __disable_irq();
  49. }

  50. static void unlock(fdb_db_t db)
  51. {
  52.     __enable_irq();
  53. }

  54. static fdb_time_t get_time(void)
  55. {
  56.     /* Using the counts instead of timestamp.
  57.      * Please change this function to return RTC time.
  58.      */
  59.     return ++counts;
  60. }

  61. /*********************************************************************
  62. * @fn      main
  63. *
  64. * @brief   Main program.
  65. *
  66. * @return  none
  67. */
  68. int main(void)
  69. {
  70.     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  71.     SystemCoreClockUpdate();
  72.     Delay_Init();
  73.     USART_Printf_Init(115200);  
  74.     printf("SystemClk:%d\r\n",SystemCoreClock);
  75.     printf( "ChipID:%08x\r\n", DBGMCU_GetCHIPID() );
  76.     printf("This is printf example\r\n");
  77.     SPI_Flash_Init();//初始化SPI内部函数
  78.     spi_sfud_init();//初始化SFUD 驱动
  79.     Flash_DbTest();//运行测试例子
  80.     while(1)
  81.     {

  82.     }
  83. }

  84. /*********************************************************************
  85. * @fn      SPI_Flash_Init
  86. *
  87. * @brief   Configuring the SPI for operation flash.
  88. *
  89. * @return  none
  90. */
  91. void SPI_Flash_Init(void)
  92. {
  93.     GPIO_InitTypeDef GPIO_InitStructure = {0};
  94.     SPI_InitTypeDef  SPI_InitStructure = {0};

  95.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB |RCC_APB2Periph_GPIOE, ENABLE);
  96.     RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3, ENABLE);

  97.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
  98.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  99.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  100.     GPIO_Init(GPIOE, &GPIO_InitStructure);
  101.     GPIO_SetBits(GPIOE, GPIO_Pin_6);

  102.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
  103.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  104.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  105.     GPIO_Init(GPIOB, &GPIO_InitStructure);

  106.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
  107.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  108.     GPIO_Init(GPIOB, &GPIO_InitStructure);

  109.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
  110.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  111.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  112.     GPIO_Init(GPIOB, &GPIO_InitStructure);

  113.     SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
  114.     SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
  115.     SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
  116.     SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
  117.     SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
  118.     SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
  119.     SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
  120.     SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
  121.     SPI_InitStructure.SPI_CRCPolynomial = 7;
  122.     SPI_Init(SPI3, &SPI_InitStructure);

  123.     SPI_Cmd(SPI3, ENABLE);
  124. }

  125. int8_t Flash_DbTest(void) {
  126.         fdb_err_t result;

  127. #ifdef FDB_USING_KVDB
  128.     { /* KVDB Sample */
  129.         struct fdb_default_kv default_kv;

  130.         default_kv.kvs = default_kv_table;
  131.         default_kv.num = sizeof(default_kv_table) / sizeof(default_kv_table[0]);
  132.         /* set the lock and unlock function if you want */
  133.         fdb_kvdb_control(&kvdb, FDB_KVDB_CTRL_SET_LOCK, (void *)lock);
  134.         fdb_kvdb_control(&kvdb, FDB_KVDB_CTRL_SET_UNLOCK, (void *)unlock);
  135.         /* Key-Value database initialization
  136.          *
  137.          *       &kvdb: database object
  138.          *       "env": database name
  139.          * "fdb_kvdb1": The flash partition name base on FAL. Please make sure it's in FAL partition table.
  140.          *              Please change to YOUR partition name.
  141.          * &default_kv: The default KV nodes. It will auto add to KVDB when first initialize successfully.
  142.          *        NULL: The user data if you need, now is empty.
  143.          */
  144.         result = fdb_kvdb_init(&kvdb, "env", "fdb_kvdb1", &default_kv, NULL);

  145.         if (result != FDB_NO_ERR) {
  146.             return -1;
  147.         }

  148.         /* run basic KV samples */
  149.         kvdb_basic_sample(&kvdb);
  150.         /* run string KV samples */
  151.         kvdb_type_string_sample(&kvdb);
  152.         /* run blob KV samples */
  153.         kvdb_type_blob_sample(&kvdb);
  154.     }
  155. #endif /* FDB_USING_KVDB */

  156.     #ifdef FDB_USING_TSDB
  157.     { /* TSDB Sample */
  158.         /* set the lock and unlock function if you want */
  159.         fdb_tsdb_control(&tsdb, FDB_TSDB_CTRL_SET_LOCK, (void *)lock);
  160.         fdb_tsdb_control(&tsdb, FDB_TSDB_CTRL_SET_UNLOCK, (void *)unlock);
  161.         /* Time series database initialization
  162.          *
  163.          *       &tsdb: database object
  164.          *       "log": database name
  165.          * "fdb_tsdb1": The flash partition name base on FAL. Please make sure it's in FAL partition table.
  166.          *              Please change to YOUR partition name.
  167.          *    get_time: The get current timestamp function.
  168.          *         128: maximum length of each log
  169.          *        NULL: The user data if you need, now is empty.
  170.          */
  171.         result = fdb_tsdb_init(&tsdb, "log", "fdb_tsdb1", get_time, 128, NULL);
  172.         /* read last saved time for simulated timestamp */
  173.         fdb_tsdb_control(&tsdb, FDB_TSDB_CTRL_GET_LAST_TIME, &counts);

  174.         if (result != FDB_NO_ERR) {
  175.             return -1;
  176.         }

  177.         /* run TSDB sample */
  178.         tsdb_sample(&tsdb);
  179.     }
  180.     #endif
  181. }
7、编译下后运行成功,可以看到FlashDB初始化成功,并且可以看到重启次数、假设的温度值
9611868d3e051d0537.png
综上,可以看到FlashDB可以设置相关参数、以及记录重启次数等功能,将FlashDB作为嵌入式数据库是非常方便地。

最后附上FlashDB的教程入门 - 快速开始 - 《FlashDB v2.1 使用教程》 - 书栈网 · BookStack

















您需要登录后才可以回帖 登录 | 注册

本版积分规则

11

主题

30

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部