[单片机框架] [kv_sys] 实现一个简易KV键值系统(升级版)

发布者:Enchanted2021最新更新时间:2022-09-15 来源: csdn关键字:升级版 手机看文章 扫描二维码
随时随地手机看文章

Env 小型KV数据库,支持 写平衡(磨损平衡) 及掉电保护模式

让Flash变为NoSQL(非关系型数据库)模型的小型键值(Key-Value)存储数据库。在产品上,能够更加简捷的实现 设定参数 或掉电保存的功能。


功能:

简易设置KEY和VAL,自动垃圾回收。至少需要占用两页FLASH空间。

平衡flash读写,提高flash擦写寿命


资源占用

image.png

RAM 16 字节  ROM 582字节


支持平台

各类单片机


函数简洁


void kv_gc_env(void);

void kv_gc_check(void);

void *kv_get_env(uint8_t key_id);

bool kv_del_env(uint8_t key_id);

bool kv_set_env(uint8_t key_id, void *data, uint8_t len);


```c

/************************************FLASH**************************************/

// FLASH

// =======================

//

//  Page Size

//  Default: 0x800 (2K byte)

#define BS_FLASH_PAGE_SIZE                                         (0x800U)


//  Flash Max Size

//  Default: 0x40000 (256K byte)

#define BS_FLASH_MAX_SIZE                                          (0x40000U)


//  Boot Loader Starting Address

//  Default: 0

#define BS_FLASH_START_ADDR                                        (0x8000000)


//  Boot Loader Size

//  Default: 0x3800 (14K byte)

#define BS_FLASH_BOOT_SIZE                                         (0x3800)


//  Kv Flash Page

//  Default: 2

#define BS_FLASH_KV_PAGE                                           (2)


//  Kv One Page Byte

//  Default: 32

#define BS_FLASH_KV_ONE_PAGE_BYTE                                  (32)


//  FLASH_INFO_TYPE(MCU user Kv_Sys / NRF user FDS)

//      <0=> KV_SYS

//      <1=> FDS

#define BS_FLASH_INFO_TYPE                                         (0)


//

/********************************[FLASH INFO]*********************************/

#define BS_FLASH_APP_ADDR                                          (BS_FLASH_START_ADDR + BS_FLASH_BOOT_SIZE)

#define BS_FLASH_APP_SIZE                                          (BS_FLASH_MAX_SIZE - BS_FLASH_BOOT_SIZE - (BS_FLASH_KV_PAGE * BS_FLASH_PAGE_SIZE))

#define BS_FLASH_OTA_ADDR                                          (BS_FLASH_APP_ADDR + BS_FLASH_APP_SIZE / 2)

#define BS_FLASH_END_ADDR                                          (BS_FLASH_START_ADDR + BS_FLASH_MAX_SIZE)


#define BS_KV_BASE_ADDR                                            (BS_FLASH_START_ADDR + BS_FLASH_APP_SIZE)

#define BS_KV_BACK_ADDR                                            (BS_KV_BASE_ADDR + (BS_FLASH_KV_PAGE - 1) * BS_FLASH_PAGE_SIZE)


/********************************************************************************

* @file    kv_sys.c

* @author  jianqiang.xue

* @version V1.0.0

* @date    2021-11-03

* @brief   KV键值最小系统 https://lisun.blog.csdn.net/article/details/121140849

********************************************************************************/

/* Includes ------------------------------------------------------------------*/

#include

#include

#include

#include


#include "bsp_flash.h"


/* Private Includes ----------------------------------------------------------*/

#include "kv_sys.h"


#include "business_function.h"

/* Private Define ------------------------------------------------------------*/


// KV系统总共可以使用N字节

#define KV_SUM_SIZE             (BS_FLASH_PAGE_SIZE * (BS_FLASH_KV_PAGE - 1))

// KV系统总共使用键值数量

#define KV_SUM_NUM              (KV_SUM_SIZE / BS_FLASH_KV_ONE_PAGE_BYTE)

// KV系统备份区使用键值数量

#define KV_BACK_SUM_NUM         (BS_FLASH_PAGE_SIZE / BS_FLASH_KV_ONE_PAGE_BYTE)

// KV系统中buff最大长度值

#define KV_BUFF_MAX_SIZE        (BS_FLASH_KV_ONE_PAGE_BYTE - 4)


kv_sys_t kv_sys_temp = {0};

bool kv_set_state    = false;  // flash--free   true--bus

/* Private Function Prototypes -----------------------------------------------*/


static uint8_t compute_checksum(uint8_t *data, uint8_t len)

{

    uint16_t sum = 0;

    for (uint8_t i = 0; i < len; i++)

    {

        sum += *(data + i);

    }

    return (uint8_t)(sum & 0x00FF);

}


static void *find_kv_addr(uint8_t key_id)

{

    kv_sys_t *kv;

    uint8_t sum = 0;

    for (uint8_t i = 0; i < KV_SUM_NUM; i++)

    {

        kv = (kv_sys_t *)(BS_KV_BASE_ADDR + BS_FLASH_KV_ONE_PAGE_BYTE * i);

        if (kv->key_id != key_id)

        {

            continue;

        }

        if (kv->is_enabled != 0xFF)

        {

            continue;

        }

        sum = compute_checksum((uint8_t *)kv, sizeof(kv_sys_t) - 1);

        if (kv->sum == sum)

        {

            return (void *)kv;

        }

    }

    return NULL;

}


static void *find_blank_addr(void)

{

    kv_sys_t *kv = NULL;

    for (uint8_t i = 0; i < KV_SUM_NUM; i++)

    {

        kv = (kv_sys_t *)(BS_KV_BASE_ADDR + BS_FLASH_KV_ONE_PAGE_BYTE * i);

        if (kv->key_id == 0xFF && kv->is_enabled == 0xFF)

        {

            return (void *)kv;

        }

    }

    return NULL;

}


/* Public Function Prototypes ------------------------------------------------*/

/**

 * @brief  FLASH垃圾回收

 */

void kv_gc_env(void)

{

    bsp_flash_erase_page(BS_KV_BACK_ADDR, 1);

    while(bsp_flash_is_busy());

    kv_sys_t *kv         = NULL;

    uint8_t sum          = 0;

    uint8_t kv_page_tick = 0;

    uint8_t back_tick    = 0;

    for (uint8_t i = 0; i < KV_SUM_NUM; i++)

    {

        kv = (kv_sys_t *)(BS_KV_BASE_ADDR + BS_FLASH_KV_ONE_PAGE_BYTE * i);

        if (kv->is_enabled != 0xFF)

        {

            continue;

        }

        // 判断数据的完整性

        sum = compute_checksum((uint8_t *)kv, sizeof(kv_sys_t) - 1);

        if (kv->sum != sum)

        {

            continue;

        }

        // 搬运有效数据

        bsp_flash_write_nbyte_s(BS_KV_BACK_ADDR + back_tick * BS_FLASH_KV_ONE_PAGE_BYTE, (uint8_t *)kv, sizeof(kv_sys_t));

        back_tick ++;

        if (back_tick == KV_BACK_SUM_NUM)

        {

            bsp_flash_carry(BS_KV_BASE_ADDR + kv_page_tick * BS_FLASH_PAGE_SIZE, BS_KV_BACK_ADDR, BS_FLASH_PAGE_SIZE);

            kv_page_tick ++;

            back_tick = 0;

        }

    }

    if (back_tick != 0)

    {

        bsp_flash_carry(BS_KV_BASE_ADDR + kv_page_tick * BS_FLASH_PAGE_SIZE, BS_KV_BACK_ADDR, BS_FLASH_PAGE_SIZE);

        kv_page_tick ++;

        back_tick = 0;

    }

    // 清理未使用的空间

    for (uint8_t i = kv_page_tick; i < BS_FLASH_KV_PAGE - 1; i++)

    {

        bsp_flash_erase_page(BS_KV_BASE_ADDR + kv_page_tick * BS_FLASH_PAGE_SIZE, 1);

    }

    while(bsp_flash_is_busy());

}


/**

 * @brief  [上电调用] 检测当前KV键值是否异常 如:掉电导致异常,则进行数据恢复

 */

void kv_gc_check(void)

{

    kv_sys_t *kv = NULL;

    // 得到空白块

    kv = find_blank_addr();

    // 如果数据满了,则进行垃圾回收处理

    if(kv == NULL)

    {

        kv_gc_env();

    }

    else

    {

        // 判断备份区是否有残余

        kv = (kv_sys_t *)BS_KV_BACK_ADDR;

        if (kv->key_id != 0xFF)

        {

            for (uint8_t i = 0; i < KV_BACK_SUM_NUM; i++)

            {

                kv = (kv_sys_t *)(BS_KV_BACK_ADDR + i * BS_FLASH_KV_ONE_PAGE_BYTE);

                kv_set_env(kv->key_id, kv->buff, kv->len);

[1] [2]
关键字:升级版 引用地址:[单片机框架] [kv_sys] 实现一个简易KV键值系统(升级版)

上一篇:[单片机][USB_HID] USB问题汇总
下一篇:C语言中使用 #pragma pack 和 __attribute(aligned(n)) 【非常有用的字节对齐用法说明】

推荐阅读最新更新时间:2024-11-11 11:35

新iPad Pro玻璃膜曝光:一款全面屏 一款普通升级版
        根据此前曝料的消息,苹果将会在今年推出两款尺寸不同的iPad Pro产品,并且不少消息显示,新款iPad Pro将会去掉Home键,增加支持Face ID。   昨天晚上,有微博博主放出了“新iPad玻璃膜的尺寸”,其中,尺寸较大的为211×276(mm),尺寸较小的为174.7×243.5(mm)。对于这两款iPad,该名博主称之为iPad 12.9和iPad 11。   对于上述两个尺寸的玻璃膜,另一名微博博主表示,小尺寸版本的和目前iPad Pro 10.5的尺寸较为接近,可能是iPad Pro保持原来的设计,升级硬件;大尺寸版本的相较于目前iPad Pro 12.9小了不少,可能是打造的全
[手机便携]
单片机---HLK-W801图形框架LVGL下开发(五)
2022年3月24日效果,增加了汉化,APP包括温湿度,计算器,wifi连接,在wifi连接状态下,能够进行NTP时间同步及查询天气。 海凌科w801开发的单片机主机 前面由于转移到w801上,SRAM明显吃紧,连喜欢的背景图都放不下了,感觉很是可惜啊,这次就想着扩展一下图片存储。 本章重点 好几天都没更新了,主要是这几天等SD卡座,然后重新规划了一下这块开发板的引脚,最终重新规划后,只剩下了两个引脚没有用了。 买了SD卡座,就是为了今天的学习,学习一下文件系统和lvgl中使用文件作为多媒体素材的来源,例如图标,背景图片等等,因为总是用c文件来存这些东西,最终会把你的sram给装满,尽管它很容就装满了,一共才两百多kb。
[单片机]
<font color='red'>单片机</font>---HLK-W801图形<font color='red'>框架</font>LVGL下开发(五)
DAF卡车推出升级版AEBS系统 可完全自动避免碰撞事故
据外媒报道,为了进一步提高车辆和道路安全性,欧洲著名商用车制造商DAF卡车公司(DAF Trucks)为LF、CF和XF全系列车型推出了升级版AEBS(自动紧急制动)系统:AEBS-3。该款第三代先进紧急制动系统可以完全实现自动紧急制动,以帮助避免与静止的车辆以及时速达80 km/h的移动车辆相撞,而且该款安全系统结合了自适应巡航控制系统(ACC)和前向碰撞警告(FCW)系统,一起提供。 (图片来源:DAF卡车) 在下一代AEBS系统中,DAF卡车采用了配备16个天线(之前是7个)的高精度双雷达,用于近距离和远距离探测。而且该系统配备了业内最好的远程传感器,探测距离最长可达250米(之前是200米),因而能够更早地识别潜
[汽车电子]
DAF卡车推出<font color='red'>升级版</font>AEBS<font color='red'>系统</font> 可完全自动避免碰撞事故
软证实6月推Win8升级版:或恢复开始按钮
    微软Windows部门副总裁茱莉·拉尔森·格林   新浪科技讯 北京时间5月8日早间消息,微软Windows部门副总裁茱莉·拉尔森·格林(Julie Larson-Green)周二宣布,将于6月下旬升级Windows 8操作系统,升级版代号是Windows Blue。Win8升级后或将恢复“开始”按钮。   格林今天在《连线》杂志商业大会上证实,6月下旬微软在举办全球开发者大会期间,将会向开发者提供Windows Blue预览版的下载。一个多月以前,就已有报道对Windows Blue的特性功能和发布时间进行了预测。但目前关于Windows Blue的许多细节还尚未公布,甚至还不清楚其最终名称。   微软CFO塔米•雷
[手机便携]
PIC单片机程序结构框架
TI TLE“This is……”;程序标题 ;程序说明 LIST P=16F84,F=1NHX8M include p16F84.inc -config_RC_Qsc &_WDT_0FF… ;资源定义和变量定义 STATUS EQU 03 FSR EQU 04 PORTA EQU 05 PORTB EQU 06 J EQU 01F K EQU 01E ;………………… ORG 0000 ; goto MAIN ;跳过中断矢量 ORG 0004 goto INTSRV;子程序入口地址 ;…………………………………… MAIN       ;从0005H开始放主程序 call Initports ;端口初始化 call Init
[单片机]
[单片机框架] [queue] 实现一个简易的消息队列
使用方法如下: #define USB_RECV_Q_ITEM_CNT 8 #define USB_RECV_Q_ITEM_SIZE (64 + 1) // 用于usb消息队列总缓存区 static uint8_t m_usb_recv_q_buff = {0}; queue_t m_usb_recv_q = { .pbuff = m_usb_recv_q_buff, .front = 0, .rear = 0, .item_cnt = USB_RECV_Q_ITEM_CNT, .item_size = USB_RECV_Q_ITEM_SI
[单片机]
小米12 Pro升级版曝光:处理器换成天玑9000了
6月8日消息,博主@数码闲聊站爆料,今年下半年小米将会推出小米12 Pro的迭代款,共有两种版本,一种版本搭载骁龙8+旗舰处理器,另一版本则搭载联发科天玑9000旗舰处理器。   据爆料,小米12 Pro天玑版支持67W快充,配备的充电器型号为MDY-12-EF,这是小米数字系列第一次在高端旗舰上使用联发科5G芯片。   该机搭载的天玑9000采用台积电4nm工艺,由1个Cortex-X2超大核、3个Cortex-A710大核以及4个Cortex-A510小核组成,GPU为ARM Mali-G710,安兔兔综合成绩突破了100万分。   此外,小米12 Pro天玑版预计会延续12 Pro上的2K LTPO 2.0显示屏,这块屏
[手机便携]
基于51框架的高性能单片机软核设计
1 引言 在如今的快速嵌入式系统设计中,目前比较流行的方案是在FPGA内集成应用软件或是软IP平台,以简化工序、加速产品面市日程。为此,很多公司推出了自己的开发平台以及相关CPU的IP核,常见的为两种:一种是通用型CPU,如xilinx和altera公司的32位以及64位通用CPU核;还有就是专用型的,常见的为51系列单片机的CPU核,但是目前关于单片机的软核基本上都是8051的,其他的品种很少。而且8051的速度不是很快,在有些快速的控制场合(如利用单片机来作为usb2.0的控制部件)显得速度不足,比较著名的actel公司推出的Core8051,运行频率也只在40 MHz左右。本文介绍了一个非常高速DS80C320单片机软核的设
[单片机]
基于51<font color='red'>框架</font>的高性能<font color='red'>单片机</font>软核设计
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved