FlashDB移植到STM32F103内部flash,FatFs、FlashDB 、EasyFlash的不同

文章目录

  • 一、前言
  • 二、FatFs、FlashDB 、EasyFlash 区别
    • 2.1 FlashDB
    • 2.2 EasyFlash
    • 2.3 FATFS
  • 三、FatFs、FlashDB、EasyFlash 区使用环境
    • 3.1 FlashDB:
    • 3.2 FATFS:
    • 3.3 EasyFlash:
  • 四、FlashDB移植
    • 4.1 项目 GITEE 地址
    • 4.2 项目目录
    • 4.3 移植的目录树
    • 4.4 MDK keil 添加文件
    • 4.5 添加头文件
    • 4.6 编写测试函数
    • 4.7 根据自己的芯片修改参数
  • 五、下载程序看一下

一、前言

最近项目用到了,Flash 的存储,早就听过 armink 大神 开源的 EsayFlash ,于是乎就决定移植到新的项目上,发现 EasyFlash 升级到了 5.0.0 版本后因 API 接口与之前不完全兼容,故重新命名为 FlashDB,有很多种框架,FatFsFlashDB, EasyFlash 等等。最终这个项目选择了 FLASHDB,因为 FlashDB的查询比EasyFlash快FatFs 是针对大文件系统的那种项目。下面简单说一下 FlashDB 的移植。还有这三个的区别和使用环境

二、FatFs、FlashDB 、EasyFlash 区别

2.1 FlashDB

  • FlashDB 是一个轻量级的嵌入式数据库系统,专门设计用于嵌入式系统中的数据存储和管理。
  • 它允许在嵌入式系统中进行数据库风格的数据存储、检索和管理,例如表、索引、查询等。
  • FlashDB 更适用于需要对数据进行结构化管理、复杂查询和事务处理的应用场景。

2.2 EasyFlash

  • EasyFlash 是一个用于嵌入式系统的存储解决方案,旨在简化嵌入式系统中的 Flash 存储管理。
  • 它提供了易于使用的 API,使开发人员能够轻松地在嵌入式系统中进行 Flash 存储的读写操作。
  • EasyFlash 的主要功能是提供了一种简单的接口来管理 Flash 存储,而不涉及复杂的数据库功能。

2.3 FATFS

  • FATFS 是一个用于嵌入式系统的文件系统,实现了 FAT 文件系统标准,用于管理嵌入式系统中的文件存储。
  • 它允许嵌入式系统像操作硬盘或闪存设备一样操作文件系统,包括读写文件、创建目录等。
  • FATFS 提供了一种通用的文件存储解决方案,适用于需要在嵌入式系统中进行文件级别的存储和管理的应用场景。

三、FatFs、FlashDB、EasyFlash 区使用环境

选择使用 FlashDB、FATFS 和 EasyFlash 取决于您的嵌入式系统的特定需求和应用场景

3.1 FlashDB:

  • 适用环境:FlashDB 适用于需要对数据进行结构化存储、复杂查询和事务处理的嵌入式应用环境。
  • 示例应用:例如,当您的嵌入式系统需要存储大量结构化数据,并且需要执行复杂的查询操作时,比如 IoT 设备中的传感器数据存储和分析,或者嵌入式控制器中的配置参数管理,FlashDB 可能是一个合适的选择。

3.2 FATFS:

  • 适用环境:FATFS 适用于需要简单的文件存储和管理的嵌入式应用环境。
  • 示例应用:如果您的嵌入式系统主要需要存储和管理文件,比如日志文件、配置文件、固件升级文件等,FATFS 是一个常见的选择。例如,嵌入式设备中的 SD 卡存储、USB 存储、固态硬盘等可以使用 FATFS 进行文件系统管理。

3.3 EasyFlash:

  • 适用环境:EasyFlash 适用于需要轻量级、易于集成的嵌入式 Flash 存储管理的环境。
  • 示例应用:如果您的嵌入式系统需要直接在 Flash 存储中读写数据,但不需要数据库的复杂功能,EasyFlash 可能是一个更适合的选择。例如,嵌入式设备中的配置参数存储、日志记录、用户数据存储等可以使用 EasyFlash。

总的来说,FlashDB 适用于需要数据库功能的应用,FATFS 适用于需要文件系统管理的应用,而 EasyFlash 则适用于需要直接 Flash 存储管理的应用。选择合适的解决方案需要综合考虑系统的存储需求、性能要求、复杂度和资源限制等因素。

四、FlashDB移植

4.1 项目 GITEE 地址

https://gitee.com/Armink/FlashDB?_from=gitee_search

4.2 项目目录

在这里插入图片描述

demos : 一些常用的开发实例工程

docs : 相关文档

inc : fdb 相关的头文件

port : fal 相关的文件(.c和.h都在里面)

samples : 开发实例工程用到的实例函数

src : fdb相关的 .c 文件

tests : 这个是一些高治疗的模板,可以参考

4.3 移植的目录树

在这里插入图片描述

├─FAL                                               #FAL相关文件
│  ├─inc											#FAL相关的头文件
│  │      fal.h
│  │      fal_cfg.h
│  │      fal_def.h
│  │      
│  └─src											#FAL相关的.C文件
│          fal.c
│          fal_flash.c
│          fal_flash_stm32f1_port.c
│          fal_partition.c
│          fal_rtt.c
│          
└─FlashDB											#FLASHDB相关的文件
│  ├─inc											#FLASHDB相关的头文件
│  │      fdb_cfg.h
│  │      fdb_def.h
│  │      fdb_low_lvl.h
│  │      flashdb.h
│  │      
│  └─src											#FLASH相关的.C文件
│          fdb.c
│          fdb_file.c
│          fdb_kvdb.c
│          fdb_tsdb.c
│          fdb_utils.c
│          
└─samples											# 这个是一些实例程序
        kvdb_basic_sample.c
        kvdb_type_blob_sample.c
        kvdb_type_string_sample.c
        tsdb_sample.c
            

把相关的文件 移植到工程里面

4.4 MDK keil 添加文件

在这里插入图片描述

4.5 添加头文件

在这里插入图片描述

4.6 编写测试函数

#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", "armink", 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;
}

int FlashdbDemo()
{
	 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_kvdb1", &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_tsdb1", 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 */

    return 0;
}

mian 函数

int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_TIM1_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
	FlashdbDemo();
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

4.7 根据自己的芯片修改参数

  • fal_flash_stm32f1_port.c 文件修改

    扇区大小 使用的是**STM32VET6** ,所以是 2048

    #if defined(STM32F103xE)
    #define PAGE_SIZE     2048
    #else
    #define PAGE_SIZE     2048
    #endif
    
    /*
    STM32F1会因容量不同而不同
        小容量和中容量产品主存储块128KB以下,  每页1KB。
        大容量和互联型产品主存储块256KB以上,  每页2KB。
    
    GD32   会因容量不同而不同
        1. Low-density Products     Flash容量从 16KB到  32KB的产品
        2. Medium-density Products  Flash容量从 64KB到 128KB的产品
              全是1K
        3. High-density Products    Flash容量从256KB到 512KB的产品
              全是2K
        4. XL-density Products      Flash容量从768KB到3072KB的产品
              <512K 是2K
              >512K 是4K
    
    雅特力
        全是2K
    
    STM32F4
        STM32F4的flash页尺寸不一样,低地址16KB,高地址32KB或128KB.
    */
    
    

    设备的信息

    STM32F103VET6:是512k的flash ,blk_size 这个是擦除扇区的大小,ops这里是flash操作的,初始化、获取、写入、擦除的回调函数

    /*
      "stm32_onchip" : Flash 设备的名字。
      0x08000000: 对 Flash 操作的起始地址。
      1024*1024:Flash 的总大小(1MB)。
      128*1024:Flash 块/扇区大小(因为 STM32F2 各块大小不均匀,所以擦除粒度为最大块的大小:128K)。
      {init, read, write, erase} :Flash 的操作函数。 如果没有 init 初始化过程,第一个操作函数位置可以置空。
      8 : 设置写粒度,单位 bit, 0 表示未生效(默认值为 0 ),该成员是 fal 版本大于 0.4.0 的新增成员。各个 flash 写入粒度不尽相同,可通过该成员进行设置,以下列举几种常见 Flash 写粒度:
      nor flash:  1 bit
      stm32f2/f4: 8 bit
      stm32f1:    32 bit
      stm32l4:    64 bit
     */
    
    //1.定义 flash 设备
    
    const struct fal_flash_dev stm32_onchip_flash =
    {
        .name       = "stm32_onchip",
        .addr       = 0x08000000,
        .len        = 512*1024,
        .blk_size   = 2*1024,
        .ops        = {init, read, write, erase},
        .write_gran = 32
    };
    
    
  • fal_cfg.h 的配置

    /*
     * Copyright (c) 2006-2018, RT-Thread Development Team
     *
     * SPDX-License-Identifier: Apache-2.0
     *
     * Change Logs:
     * Date           Author       Notes
     * 2018-05-17     armink       the first version
     */
    
    #ifndef _FAL_CFG_H_
    #define _FAL_CFG_H_
    
    #define FAL_DEBUG 1
    #define FAL_PART_HAS_TABLE_CFG
    
    /* ===================== Flash device Configuration ========================= */
    extern const struct fal_flash_dev stm32_onchip_flash;
    /* flash device table */
    #define FAL_FLASH_DEV_TABLE                                          \
    {                                                                    \
        &stm32_onchip_flash,                                             \
    }
    /* ====================== Partition Configuration ========================== */
    #ifdef FAL_PART_HAS_TABLE_CFG
    /* partition table */
    #define FAL_PART_TABLE                                                                \
    {                                                                                     \
        {FAL_PART_MAGIC_WORD,  "fdb_tsdb1",    "stm32_onchip",   104*1024,  8*1024, 0},  \
        {FAL_PART_MAGIC_WORD,  "fdb_kvdb1",    "stm32_onchip",   112*1024, 16*1024, 0},  \
    }
    #endif /* FAL_PART_HAS_TABLE_CFG */
    
    #endif /* _FAL_CFG_H_ */
    
    

    这里需要定义 FAL_PART_HAS_TABLE_CFG 不然这个列表会出错

    FAL_DEBUG : 需要打印log信息就是 1, 不需要改成0

    **fdb_kvdb1 : **这个是扇区名字,在上面的测试程序中,所使用的扇区名字就是这个

    **stm32_onchip : **这个是设备的名字

    104*1024 :这个是扇区的起始地址

    **8*1024 : **这个是扇区的大小

    FAL_PART_MAGIC_WORD 属性,末尾增加 0 (目前用于保留功能)

    注意!!! 这里的起始地址和扇区大小要严格计算一下,不要和程序地址重合,也不要超过FLASH的大小,不然会导致 死机

  • fdb_cfg.h 配置

     * only support 1(nor flash)/ 8(stm32f2/f4)/ 32(stm32f1)/ 64(stm32f7)/ 128(stm32h5) */
    #define FDB_WRITE_GRAN                32/* @note you must define it for a value */
    

    原来的程序FDB_WRITE_GRAN 是空的,填写自己芯片的类型

五、下载程序看一下

在这里插入图片描述

  • 分区表已经初始化成功

在这里插入图片描述

  • 测试程序也运行了。
  • 资源下载地址
    Stm32FlashDb 工程

文章是自己总结而记录,有些知识点没说明白的,请各位看官多多提意见,多多交流,欢迎大家留言
如果技术交流可以加以下群,方便沟通
QQ群:370278903
点击链接加入群聊【蜡笔小芯的嵌入式交流群】
![])

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python---Numpy学习

首先&#xff0c;先来认识一下Numpy数组对象&#xff0c;以及如何创建它 import numpy as np# 1.认识数组对象 # 指定取值范围和跨度创建数组对象 # 创建一个3行4列的数组 data np.arange(12).reshape(3, 4)print(data)print(type(data))# 维度 print(data.shape)# 维度的个数…

架构师之路--docker命令实践整理

安装docker sudo yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine sudo yum install -y yum-utils sudo yum-config-manager --add-repo http://mirrors.aliyun.com/…

谭浩强第五版C语言课后习题(编程题)+答案

谭浩强第五版作为初学C语言必读的一本教材&#xff0c;课后习题具有非常大的参考价值&#xff0c;也是很多高校期末考试或者考研的重要参考。在这里我整理了一部分个人认为比较重要的编程题&#xff0c;供大家作参考 1.输入两个数&#xff0c;求他们的最大公约数和最小公倍数&…

Vector授权狗驱动安装方法

安装好主体软件后&#xff0c;建议先安装最新官方正版驱动&#xff1a;Vector Driver Setup。然后再复制补丁到C盘指定位置&#xff0c;替换原文件。如果你之前已安装老版本的驱动&#xff0c;则建议先卸载老版本的驱动&#xff0c;主体软件不需要卸载。卸载建议用原来安装时用…

关于柔性阵列(/三维阵列)波束形成的仿真实践以及稳健波束形成的思考(1)

说明 关于波束形成&#xff0c;我之前写过几篇相关的博文&#xff0c;如参考资料[1]、[2]、[3]。除去在博文[2]中有讨论过阵元相对位置关系对波束形成的影响&#xff1a;“如何基于遗传算法优化阵元相对位置关系以压低旁瓣峰值”以外&#xff0c;似乎我认知里的天线阵列&#x…

【Linux实验室】测试ext4文件系统的最大inode数量

【Linux实验室】测试ext4文件系统的最大inode数量 实验目的 1、熟悉inode的定义与作用 2、熟悉Linux文件系统类型 3、测试ext4文件系统的最大inode数量 实验环境 centos7.10 64-bit 实验原理 inode定义 安装操作系统或格式化磁盘分区的时候&#xff0c;操作系统会自动把…

教你如何快速批量删除文件名中相同的文字

在现代计算机系统中&#xff0c;文件夹是一种重要的组织和管理文件的方式。文件夹名称可以反映其内部文件的内容或属性&#xff0c;有助于用户快速识别和定位所需的文件。然而&#xff0c;有时我们会遇到需要统一删除文件夹名称的部分的情况。统一删除文件夹名称的部分可能是为…

PHiSeg:捕捉医学图像分割中的不确定性

PHiSeg&#xff1a;捕捉医学图像分割中的不确定性 摘要引言方法 PHiSeg Capturing Uncertainty in Medical Image Segmentation 摘要 解剖结构和病理的分割本质上是模糊的。例如&#xff0c;结构边界可能不清晰可见&#xff0c;或者不同的专家可能具有不同的注释风格。大多数当…

80个Python数据分析必备实战案例.pdf(附代码),完全开放下载

大家好&#xff0c;我是彭涛。 随着数据时代的来临&#xff0c;Python数据分析技能现在愈加重要&#xff0c;无论是从事数据科学、商业分析还是决策支持&#xff0c;掌握 Python 数据分析的技能都将成为你事半功倍的利器。 之前为大家陆续梳理了基础资料&#xff0c;爬虫资料…

Navicat 干货 | 通过检查约束确保 PostgreSQL 的数据完整性

数据完整性对于任何数据库系统来说都是很重要的一方面&#xff0c;它确保存储的数据保持准确、一致且有意义的。在 PostgreSQL 中&#xff0c;维护数据完整性的一个强大工具是使用检查约束。这些约束允许你定义数据必须遵守的规则&#xff0c;以防止无效数据的插入或修改。本文…

什么是根据人类反馈的强化学习Reinforcement Learning with Human Feedback(RLHF)?

基于人类反馈的强化学习&#xff08;Reinforcement learning with human feedback&#xff09;是近年来越来越受欢迎的一种前沿技术&#xff0c;用于提高大型语言模型的性能。这是种使用人类反馈训练这些模型的有效方法&#xff0c;而该方法的输入组件与搜索评估也有诸多相似之…

企业指标体系的落地与推广:让指标体系真正发挥作用

一、精心策划实施计划&#xff0c;确保项目有序进行 为确保指标体系的顺利落地与推广&#xff0c;我们精心策划了实施计划。首先&#xff0c;我们制定了详细的时间表&#xff0c;明确了项目启动、关键节点和结束时间&#xff0c;确保项目能够按期推进。同时&#xff0c;我们还将…

面试题(四)

目录 61.简述MyISAM和InnoDB的区别 62.Explain语句结果中各个字段分表表示什么 63.索引覆盖是什么 64.最左前缀原则是什么 65.Innodb是如何实现事务的 66.B树和B树的区别&#xff0c;为什么Mysql使⽤B树 67.Mysql锁有哪些&#xff0c;如何理解 68.Mysql慢查询该如何优化…

【JavaWeb】Day18.Vue组件库Element

什么是Element Element&#xff1a;是饿了么团队研发的&#xff0c;一套为开发者、设计师和产品经理准备的基于 Vue 2.0 的桌面端组件库。组件&#xff1a;组成网页的部件&#xff0c;例如 超链接、按钮、图片、表格、表单、分页条等等。官网&#xff1a;Element - The worlds…

每日汇评:复活节假期前,欧元保持在关键技术位之间

周四欧洲早盘&#xff0c;欧元兑美元小幅下跌至1.0800&#xff1b; 谨慎的市场情绪帮助美元在数据发布前守住了阵地&#xff1b; 美联储理事沃勒表示&#xff0c;他们并不急于降低政策利率&#xff1b; 周四欧洲早盘&#xff0c;欧元兑美元受到温和的看跌压力&#xff0c;并跌向…

Python算法100例-4.6 歌星大奖赛

完整源代码项目地址&#xff0c;关注博主私信源代码后可获取 1.问题描述2.问题分析3.算法设计4.确定程序框架5.完整的程序6.问题拓展7.知识点补充 1&#xff0e;问题描述 在歌星大奖赛中&#xff0c;有10个评委为参赛的选手打分&#xff0c;分数为1&#xff5e;100分。选手最…

【Vue3之computed属性(四)】

文章目录 前言一、computed属性有缓存二、使用方法三、修改全名 前言 理解computed属性&#xff0c;实现输入姓和名得出全名并双向绑定&#xff0c;区分单向绑定和双向绑定。测试computed属性和方法的区别 一、computed属性有缓存 先引入computed&#xff0c;写箭头函数定义并…

Windows安装Odoo结合内网穿透实现公网访问本地企业管理系统

文章目录 前言1. 下载安装Odoo&#xff1a;2. 实现公网访问Odoo本地系统&#xff1a;3. 固定域名访问Odoo本地系统 前言 Odoo是全球流行的开源企业管理套件&#xff0c;是一个一站式全功能ERP及电商平台。 开源性质&#xff1a;Odoo是一个开源的ERP软件&#xff0c;这意味着企…

springboot实战---5.最简单最高效的后台管理系统开发

&#x1f388;个人主页&#xff1a;靓仔很忙i &#x1f4bb;B 站主页&#xff1a;&#x1f449;B站&#x1f448; &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 &#x1f917;收录专栏&#xff1a;SpringBoot &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&…

网络编程之流式套接字

流式套接字&#xff08;SOCK_STREAM&#xff09;是一种网络编程接口&#xff0c;它提供了一种面向连接的、可靠的、无差错和无重复的数据传输服务。这种服务保证了数据按照发送的顺序被接收&#xff0c;使得数据传输具有高度的稳定性和正确性。通常用于那些对数据的顺序和完整性…