GD32上FAL Flash分区驱动移植及Easyflash与FlashDB移植说明

  • 效果
  • 移植前提
    • 下载源码
  • 移植过程
    • 加入以下文件及文件夹到工程目录和工程
    • 将demo目录下的接口文件做下修改
    • 修改配置文件fal_cfg.h
    • 复制demo中文件修改内部flash驱动接口
    • 外部SPI Flash的接口配置
  • 测试代码
    • 建议调试打开打印功能
    • 必须的初始化
    • 读写擦除
  • Easyflash的移植
    • 修改fdb的cfg文件
    • 测试代码

效果


移植前提

下载源码

前往下载

移植过程

加入以下文件及文件夹到工程目录和工程


  • Easyflash工程目录文件添加参考

将demo目录下的接口文件做下修改

修改配置文件fal_cfg.h

#ifndef _FAL_CFG_H_
#define _FAL_CFG_H_#define FAL_PART_HAS_TABLE_CFG#define NOR_FLASH_DEV_NAME             "norflash0"
#define FAL_PART_TABLE_FLASH_DEV_NAME  NOR_FLASH_DEV_NAME
#define FAL_USING_NOR_FLASH_DEV_NAME   "norflash0"
#define FAL_PART_TABLE_END_OFFSET      (2*1024*1024L)/* ===================== Flash device Configuration ========================= */
extern const struct fal_flash_dev gd32f4_onchip_flash;
extern struct fal_flash_dev nor_flash0;/* flash device table */
#define FAL_FLASH_DEV_TABLE                                          \
{                                                                    \&gd32f4_onchip_flash,                                           \&nor_flash0,                                                     \
}
/* ====================== Partition Configuration ========================== */
#ifdef FAL_PART_HAS_TABLE_CFG
/* partition table */
#define FAL_PART_TABLE                                                               \
{                                                                                    \{FAL_PART_MAGIC_WORD,        "app",     "gd32_onchip",         0,   704*1024, 0}, \{FAL_PART_MAGIC_WORD,       "param",     "gd32_onchip",   704*1024,  64*1024, 0}, \{FAL_PART_MAGIC_WORD, "easyflash", NOR_FLASH_DEV_NAME,         0, 1024*1024, 0}, \{FAL_PART_MAGIC_WORD,  "download", NOR_FLASH_DEV_NAME, 1024*1024, 1024*1024, 0}, \
}
#endif /* FAL_PART_HAS_TABLE_CFG */#endif /* _FAL_CFG_H_ */

复制demo中文件修改内部flash驱动接口

更名为:fal_flash_gd32f2_port.c(这个操作依据自己芯片平台非必须)

主要完善以下接口:

  • 内部FLASH的读取,写入,擦除操作
  • 内部FLASH的属性配置

GD32的FLASH操作接口已改为HAL方式,HAL的移植方式参考我的博客https://blog.csdn.net/weixin_42892101/article/details/106135522

#include <fal.h>#include <gd32f4xx.h>
#include "flash.h"
/* base address of the flash sectors */
/*bank1*/
#define ADDR_FLASH_SECTOR_0      ((uint32_t)0x08000000)                                     /* Base address of Sector 0, 16 K bytes   */
#define ADDR_FLASH_SECTOR_1      ((uint32_t)16*1024+ADDR_FLASH_SECTOR_0)   /* Base address of Sector 1, 16 K bytes   */
#define ADDR_FLASH_SECTOR_2      ((uint32_t)16*1024+ADDR_FLASH_SECTOR_1)   /* Base address of Sector 2, 16 K bytes   */
#define ADDR_FLASH_SECTOR_3      ((uint32_t)16*1024+ADDR_FLASH_SECTOR_2)   /* Base address of Sector 3, 16 K bytes   */
#define ADDR_FLASH_SECTOR_4      ((uint32_t)16*1024+ADDR_FLASH_SECTOR_3)   /* Base address of Sector 4, 64 K bytes   */
#define ADDR_FLASH_SECTOR_5      ((uint32_t)64*1024+ADDR_FLASH_SECTOR_4)   /* Base address of Sector 5, 128 K bytes  */
#define ADDR_FLASH_SECTOR_6      ((uint32_t)128*1024+ADDR_FLASH_SECTOR_5) /* Base address of Sector 6, 128 K bytes  */
#define ADDR_FLASH_SECTOR_7      ((uint32_t)128*1024+ADDR_FLASH_SECTOR_6) /* Base address of Sector 7, 128 K bytes  */
#define ADDR_FLASH_SECTOR_8      ((uint32_t)128*1024+ADDR_FLASH_SECTOR_7) /* Base address of Sector 8, 128 K bytes  */
#define ADDR_FLASH_SECTOR_9      ((uint32_t)128*1024+ADDR_FLASH_SECTOR_8) /* Base address of Sector 9, 128 K bytes  */
#define ADDR_FLASH_SECTOR_10     ((uint32_t)128*1024+ADDR_FLASH_SECTOR_9) /* Base address of Sector 10, 128 K bytes */
#define ADDR_FLASH_SECTOR_11     ((uint32_t)128*1024+ADDR_FLASH_SECTOR_10)/* Base address of Sector 11, 128 K bytes */
/*bank2*/
#define ADDR_FLASH_SECTOR_12     ((uint32_t)128*1024+ADDR_FLASH_SECTOR_11)/* Base address of Sector 12, 16 K bytes  */
#define ADDR_FLASH_SECTOR_13     ((uint32_t)16*1024+ADDR_FLASH_SECTOR_12) /* Base address of Sector 13, 16 K bytes  */
#define ADDR_FLASH_SECTOR_14     ((uint32_t)16*1024+ADDR_FLASH_SECTOR_13) /* Base address of Sector 14, 16 K bytes  */
#define ADDR_FLASH_SECTOR_15     ((uint32_t)16*1024+ADDR_FLASH_SECTOR_14) /* Base address of Sector 15, 16 K bytes  */
#define ADDR_FLASH_SECTOR_16     ((uint32_t)16*1024+ADDR_FLASH_SECTOR_15) /* Base address of Sector 16, 64 K bytes  */
#define ADDR_FLASH_SECTOR_17     ((uint32_t)64*1024+ADDR_FLASH_SECTOR_16) /* Base address of Sector 17, 128 K bytes */
#define ADDR_FLASH_SECTOR_18     ((uint32_t)128*1024+ADDR_FLASH_SECTOR_17)/* Base address of Sector 18, 128 K bytes */
#define ADDR_FLASH_SECTOR_19     ((uint32_t)128*1024+ADDR_FLASH_SECTOR_18)/* Base address of Sector 19, 128 K bytes */
#define ADDR_FLASH_SECTOR_20     ((uint32_t)128*1024+ADDR_FLASH_SECTOR_19)/* Base address of Sector 20, 128 K bytes */
#define ADDR_FLASH_SECTOR_21     ((uint32_t)128*1024+ADDR_FLASH_SECTOR_20)/* Base address of Sector 21, 128 K bytes */
#define ADDR_FLASH_SECTOR_22     ((uint32_t)128*1024+ADDR_FLASH_SECTOR_21)/* Base address of Sector 22, 128 K bytes */
#define ADDR_FLASH_SECTOR_23     ((uint32_t)128*1024+ADDR_FLASH_SECTOR_22)/* Base address of Sector 23, 128 K bytes */
#define ADDR_FLASH_SECTOR_24     ((uint32_t)128*1024+ADDR_FLASH_SECTOR_23)/* Base address of Sector 24, 256 K bytes */
#define ADDR_FLASH_SECTOR_25     ((uint32_t)256*1024+ADDR_FLASH_SECTOR_24)/* Base address of Sector 25, 256 K bytes */
#define ADDR_FLASH_SECTOR_26     ((uint32_t)256*1024+ADDR_FLASH_SECTOR_15)/* Base address of Sector 26, 256 K bytes */
#define ADDR_FLASH_SECTOR_27     ((uint32_t)256*1024+ADDR_FLASH_SECTOR_16)/* Base address of Sector 27, 256 K bytes */
#define ADDR_FLASH_ECTOR_MAX         ((uint32_t)256*1024+ADDR_FLASH_SECTOR_17)/*flash最大地址*//*** Get the sector of a given address** @param address flash address** @return The sector of a given address*/
static uint32_t gd32_get_sector(uint32_t address)
{uint32_t sector = 0;if ((address < ADDR_FLASH_SECTOR_1) && (address >= ADDR_FLASH_SECTOR_0)){sector = FLASH_SECTOR_0;}else if ((address < ADDR_FLASH_SECTOR_2) && (address >= ADDR_FLASH_SECTOR_1)){sector = FLASH_SECTOR_1;}else if ((address < ADDR_FLASH_SECTOR_3) && (address >= ADDR_FLASH_SECTOR_2)){sector = FLASH_SECTOR_2;}else if ((address < ADDR_FLASH_SECTOR_4) && (address >= ADDR_FLASH_SECTOR_3)){sector = FLASH_SECTOR_3;}else if ((address < ADDR_FLASH_SECTOR_5) && (address >= ADDR_FLASH_SECTOR_4)){sector = FLASH_SECTOR_4;}else if ((address < ADDR_FLASH_SECTOR_6) && (address >= ADDR_FLASH_SECTOR_5)){sector = FLASH_SECTOR_5;}else if ((address < ADDR_FLASH_SECTOR_7) && (address >= ADDR_FLASH_SECTOR_6)){sector = FLASH_SECTOR_6;}else if ((address < ADDR_FLASH_SECTOR_8) && (address >= ADDR_FLASH_SECTOR_7)){sector = FLASH_SECTOR_7;}else if ((address < ADDR_FLASH_SECTOR_9) && (address >= ADDR_FLASH_SECTOR_8)){sector = FLASH_SECTOR_8;}else if ((address < ADDR_FLASH_SECTOR_10) && (address >= ADDR_FLASH_SECTOR_9)){sector = FLASH_SECTOR_9;}else if ((address < ADDR_FLASH_SECTOR_11) && (address >= ADDR_FLASH_SECTOR_10)){sector = FLASH_SECTOR_10;}else if ((address < ADDR_FLASH_SECTOR_12) && (address >= ADDR_FLASH_SECTOR_11)){sector = FLASH_SECTOR_11;}else if ((address < ADDR_FLASH_SECTOR_13) && (address >= ADDR_FLASH_SECTOR_12)){sector = FLASH_SECTOR_12;}else if ((address < ADDR_FLASH_SECTOR_14) && (address >= ADDR_FLASH_SECTOR_13)){sector = FLASH_SECTOR_13;}else if ((address < ADDR_FLASH_SECTOR_15) && (address >= ADDR_FLASH_SECTOR_14)){sector = FLASH_SECTOR_14;}else if ((address < ADDR_FLASH_SECTOR_16) && (address >= ADDR_FLASH_SECTOR_15)){sector = FLASH_SECTOR_15;}else if ((address < ADDR_FLASH_SECTOR_17) && (address >= ADDR_FLASH_SECTOR_16)){sector = FLASH_SECTOR_16;}else if ((address < ADDR_FLASH_SECTOR_18) && (address >= ADDR_FLASH_SECTOR_17)){sector = FLASH_SECTOR_17;}else if ((address < ADDR_FLASH_SECTOR_19) && (address >= ADDR_FLASH_SECTOR_18)){sector = FLASH_SECTOR_18;}else if ((address < ADDR_FLASH_SECTOR_20) && (address >= ADDR_FLASH_SECTOR_19)){sector = FLASH_SECTOR_19;}else if ((address < ADDR_FLASH_SECTOR_21) && (address >= ADDR_FLASH_SECTOR_20)){sector = FLASH_SECTOR_20;}else if ((address < ADDR_FLASH_SECTOR_22) && (address >= ADDR_FLASH_SECTOR_21)){sector = FLASH_SECTOR_21;}else if ((address < ADDR_FLASH_SECTOR_23) && (address >= ADDR_FLASH_SECTOR_22)){sector = FLASH_SECTOR_22;}else if ((address < ADDR_FLASH_SECTOR_24) && (address >= ADDR_FLASH_SECTOR_23)){sector = FLASH_SECTOR_23;}else if ((address < ADDR_FLASH_SECTOR_25) && (address >= ADDR_FLASH_SECTOR_24)){sector = FLASH_SECTOR_24;}else if ((address < ADDR_FLASH_SECTOR_26) && (address >= ADDR_FLASH_SECTOR_25)){sector = FLASH_SECTOR_25;}else if ((address < ADDR_FLASH_SECTOR_27) && (address >= ADDR_FLASH_SECTOR_26)){sector = FLASH_SECTOR_26;}else{sector = FLASH_SECTOR_27;}return sector;
}/*** Get the sector size** @param sector sector** @return sector size*/
static uint32_t gd32_get_sector_size(uint32_t sector) {assert(IS_FLASH_SECTOR(sector));switch (sector) {case FLASH_SECTOR_0:case FLASH_SECTOR_1:case FLASH_SECTOR_2:case FLASH_SECTOR_3: return 16 * 1024;case FLASH_SECTOR_4: return 64 * 1024;case FLASH_SECTOR_5: case FLASH_SECTOR_6: case FLASH_SECTOR_7: case FLASH_SECTOR_8: case FLASH_SECTOR_9: case FLASH_SECTOR_10:case FLASH_SECTOR_11: return 128 * 1024;case FLASH_SECTOR_12:case FLASH_SECTOR_13:case FLASH_SECTOR_14:case FLASH_SECTOR_15: return 16 * 1024;case FLASH_SECTOR_16: return 64 * 1024;case FLASH_SECTOR_17: case FLASH_SECTOR_18: case FLASH_SECTOR_19: case FLASH_SECTOR_20:case FLASH_SECTOR_21: case FLASH_SECTOR_22: case FLASH_SECTOR_23: return 128 * 1024;case FLASH_SECTOR_24:case FLASH_SECTOR_25: case FLASH_SECTOR_26:case FLASH_SECTOR_27: return 256 * 1024;default : return 256 * 1024;}
}
static int init(void)
{/* do nothing now */
}static int read(long offset, uint8_t *buf, size_t size)
{size_t i;uint32_t addr = gd32f4_onchip_flash.addr + offset;for (i = 0; i < size; i++, addr++, buf++){*buf = *(uint8_t *) addr;}return size;
}static int write(long offset, const uint8_t *buf, size_t size)
{size_t i;uint32_t read_data;uint32_t addr = gd32f4_onchip_flash.addr + offset;HAL_FLASH_Unlock();for (i = 0; i < size; i++, buf++, addr++){/* write data */FLASH_ProgramByte(addr, *buf);read_data = *(uint8_t *) addr;/* check data */if (read_data != *buf){return -1;}}HAL_FLASH_Lock();return size;
}/********************************************************************* @brief   获取当前扇区所属bank* @param   [in]扇区号* @retval  flash bank号* @author  aron566* @version V1.0* @date    2020-6-3*******************************************************************/
static uint32_t Get_SectorBank(uint32_t Sector)
{if(Sector < ADDR_FLASH_SECTOR_12){return FLASH_BANK_1;}else{return FLASH_BANK_2;}
}static int erase(long offset, size_t size)
{HAL_StatusTypeDef flash_status;size_t erased_size = 0;uint32_t addr = gd32f4_onchip_flash.addr + offset;FLASH_EraseInitTypeDef config;uint32_t ERROR = 0;config.NbSectors = 1;config.TypeErase = FLASH_TYPEERASE_SECTORS;config.VoltageRange = FLASH_VOLTAGE_RANGE_4;/* start erase */HAL_FLASH_Unlock();/* it will stop when erased size is greater than setting size */while (erased_size < size){config.Sector = gd32_get_sector(addr + erased_size);config.Banks = Get_SectorBank(config.Sector);flash_status = HAL_FLASHEx_Erase(&config, &ERROR);if (flash_status != HAL_OK){return -1;}erased_size += gd32_get_sector_size(config.Sector);}HAL_FLASH_Lock();return size;
}const struct fal_flash_dev gd32f4_onchip_flash =
{.name       = "gd32_onchip",.addr       = ADDR_FLASH_SECTOR_0,.len        = ADDR_FLASH_ECTOR_MAX - ADDR_FLASH_SECTOR_0,.blk_size   = 256*1024,.ops        = {init, read, write, erase},.write_gran = 8
};

外部SPI Flash的接口配置

由于操作flash的接口是由sfud万能驱动接口做的,所以参考sfud的移植,当然不移植就需要自己实现外部SPI Flash的读取/写入/擦除驱动。
fal_flash_sfud_port.c修改如下:

#include <fal.h>
#include <sfud.h>#define FAL_USING_SFUD_PORT
#ifdef FAL_USING_SFUD_PORT
#ifdef RT_USING_SFUD
#include <spi_flash_sfud.h>
#endif#ifndef FAL_USING_NOR_FLASH_DEV_NAME
#define FAL_USING_NOR_FLASH_DEV_NAME             "norflash0"
#endifstatic int init(void);
static int read(long offset, uint8_t *buf, size_t size);
static int write(long offset, const uint8_t *buf, size_t size);
static int erase(long offset, size_t size);static sfud_flash_t sfud_dev = NULL;
struct fal_flash_dev nor_flash0 =
{.name       = FAL_USING_NOR_FLASH_DEV_NAME,.addr       = 0,.len        = 8 * 1024 * 1024,.blk_size   = 4096,.ops        = {init, read, write, erase},.write_gran = 1
};static int init(void)
{#ifdef RT_USING_SFUD/* RT-Thread RTOS platform */sfud_dev = rt_sfud_flash_find_by_dev_name(FAL_USING_NOR_FLASH_DEV_NAME);
#else/* bare metal platform */sfud_dev = sfud_get_device(SFUD_GD25Q16B_DEVICE_INDEX);
#endifif (NULL == sfud_dev){return -1;}/* update the flash chip information */nor_flash0.blk_size = sfud_dev->chip.erase_gran;nor_flash0.len = sfud_dev->chip.capacity;return 0;
}static int read(long offset, uint8_t *buf, size_t size)
{assert(sfud_dev);assert(sfud_dev->init_ok);sfud_read(sfud_dev, nor_flash0.addr + offset, size, buf);return size;
}static int write(long offset, const uint8_t *buf, size_t size)
{assert(sfud_dev);assert(sfud_dev->init_ok);if (sfud_write(sfud_dev, nor_flash0.addr + offset, size, buf) != SFUD_SUCCESS){return -1;}return size;
}static int erase(long offset, size_t size)
{assert(sfud_dev);assert(sfud_dev->init_ok);if (sfud_erase(sfud_dev, nor_flash0.addr + offset, size) != SFUD_SUCCESS){return -1;}return size;
}
#endif /* FAL_USING_SFUD_PORT */

测试代码

建议调试打开打印功能

在文件fal_def.h中,#define FAL_DEBUG 1

必须的初始化

#include "fal.h"
int main(void)
{fal_init();
}

读写擦除

接口都在fal.h中
懒得写了。。。。。。

Easyflash的移植

目前最新版本的Easyflash V5.X或者最新更名的FlashDB 底层调用接口都是FAL,所以实现了FAL移植,Easyflash和FlashDB都无需较大更改,直接加入源码到工程目录即可使用。

需要注意的是:easyflash首先执行初始化sfud,之后是fal初始化,否则flash容量大小会被篡改为0!
当使用操作系统时,注意线程分配的堆栈大小,应>512Byte否则易出现Hardfault错误,坑已踩过!

修改fdb的cfg文件

主要增加宏定义:#define FDB_USING_KVDB与设置FDB_WRITE_GRAN大小

/** Copyright (c) 2020, Armink, <armink.ztl@gmail.com>** SPDX-License-Identifier: Apache-2.0*//*** @file* @brief configuration file*/#ifndef _FDB_CFG_H_
#define _FDB_CFG_H_/* using KVDB feature */
#define FDB_USING_KVDB#ifdef FDB_USING_KVDB
/* Auto update KV to latest default when current KVDB version number is changed. @see fdb_kvdb.ver_num */
/* #define FDB_KV_AUTO_UPDATE */
#endif/* using TSDB (Time series database) feature */
#define FDB_USING_TSDB/* the flash write granularity, unit: bit* only support 1(nor flash)/ 8(stm32f2/f4)/ 32(stm32f1) */
#define FDB_WRITE_GRAN                1/* @note you must define it for a value *//* MCU Endian Configuration, default is Little Endian Order. */
/* #define FDB_BIG_ENDIAN  */ /* log print macro. default EF_PRINT macro is printf() */
/* #define FDB_PRINT(...)              my_printf(__VA_ARGS__) *//* print debug information */
#define FDB_DEBUG_ENABLE#endif /* _FDB_CFG_H_ */

测试代码

/***  @file database.c**  @date 2020/6/9**  @author aron566**  @copyright None**  @brief FlashDB操作**  @details 使用该模块有哪些细节注意等**  @version v1.0*/
#ifdef __cplusplus ///<use C compiler
extern "C" {#endif
/** Includes -----------------------------------------------------------------*/
/* Private includes ----------------------------------------------------------*/
#include "database.h"
#include "flashdb.h"
#include "gd32f4xx.h"
/** Private typedef ----------------------------------------------------------*/
/** Private macros -----------------------------------------------------------*//** Private constants --------------------------------------------------------*/
/** Public variables ---------------------------------------------------------*/
/** Private variables --------------------------------------------------------*/
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 };
/** Private function prototypes ----------------------------------------------*/
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);
/** Private user code --------------------------------------------------------*//** Private application code -------------------------------------------------*/
/*******************************************************************************
*
*       Static code
*
********************************************************************************
*/
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)
{static int counts = 0;/* Using the counts instead of timestamp.* Please change this function to return RTC time.*/return counts++;
}/** Public application code --------------------------------------------------*/
/*******************************************************************************
*
*       Public code
*
********************************************************************************
*/
/*** @file* @brief basic KV samples.** basic Key-Value Database KV feature samples* get and show currnet boot counts*/#include <flashdb.h>#ifdef FDB_USING_KVDB#define FDB_LOG_TAG "[sample][kvdb][basic]"void kvdb_basic_sample(fdb_kvdb_t kvdb)
{struct fdb_blob blob;int boot_count = 0;{ /* 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\r\n", boot_count);} else {FDB_INFO("get the 'boot_count' failed\r\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\r\n", boot_count);}
}#endif /* FDB_USING_KVDB */
/*** @file* @brief blob KV samples.** Key-Value Database blob type KV feature samples*/#include <flashdb.h>#ifdef FDB_USING_KVDB
#ifdef FDB_LOG_TAG
#undef FDB_LOG_TAG
#define FDB_LOG_TAG "[sample][kvdb][blob]"
#endif
void kvdb_type_blob_sample(fdb_kvdb_t kvdb)
{struct fdb_blob blob;{ /* CREATE new Key-Value */int temp_data = 36;/* It will create new KV node when "temp" KV not in database.* fdb_blob_make: It's a blob make function, and it will return the blob when make finish.*/fdb_kv_set_blob(kvdb, "temp", fdb_blob_make(&blob, &temp_data, sizeof(temp_data)));FDB_INFO("create the 'temp' blob KV, value is: %d\r\n", temp_data);}{ /* GET the KV value */int temp_data = 0;/* get the "temp" KV value */fdb_kv_get_blob(kvdb, "temp", fdb_blob_make(&blob, &temp_data, sizeof(temp_data)));/* the blob.saved.len is more than 0 when get the value successful */if (blob.saved.len > 0) {FDB_INFO("get the 'temp' value is: %d\r\n", temp_data);}}{ /* CHANGE the KV value */int temp_data = 38;/* change the "temp" KV's value to 38.1 */fdb_kv_set_blob(kvdb, "temp", fdb_blob_make(&blob, &temp_data, sizeof(temp_data)));FDB_INFO("set 'temp' value to %d\r\n", temp_data);}{ /* DELETE the KV by name */fdb_kv_del(kvdb, "temp");FDB_INFO("delete the 'temp' finish\r\n");}
}#endif /* FDB_USING_KVDB */
/*** @file* @brief string KV samples.** Key-Value Database string type KV feature samples source file.*/#include <flashdb.h>
#include <string.h>#ifdef FDB_USING_KVDB
#ifdef FDB_LOG_TAG
#undef FDB_LOG_TAG
#define FDB_LOG_TAG "[sample][kvdb][string]"
#endif
void kvdb_type_string_sample(fdb_kvdb_t kvdb)
{{ /* 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\r\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\r\n", temp_data);}}{ /* CHANGE the KV value */char temp_data[10] = "38C";/* change the "temp" KV's value to "38.1" */fdb_kv_set(kvdb, "temp", temp_data);FDB_INFO("set 'temp' value to %s\r\n", temp_data);}{ /* DELETE the KV by name */fdb_kv_del(kvdb, "temp");FDB_INFO("delete the 'temp' finish\r\n");}
}#endif /* FDB_USING_KVDB */
/*** @file* @brief TSDB samples.** Time series log (like TSDB) feature samples source file.** TSL is time series log, the TSDB saved many TSLs.*/#include <flashdb.h>
#include <string.h>#ifdef FDB_USING_TSDB
#ifdef FDB_LOG_TAG
#undef FDB_LOG_TAG
#define FDB_LOG_TAG "[sample][tsdb]"
#endif
struct env_status {int temp;int humi;
};static bool query_cb(fdb_tsl_t tsl, void *arg);
static bool set_status_cb(fdb_tsl_t tsl, void *arg);void tsdb_sample(fdb_tsdb_t tsdb)
{struct fdb_blob blob;{ /* 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)\r\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)\r\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_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\r\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 order.*       FDB_TSL_WRITE -> FDB_TSL_USER_STATUS1 -> FDB_TSL_DELETED -> FDB_TSL_USER_STATUS2*/fdb_tsl_iter(tsdb, set_status_cb, tsdb);}
}static bool query_cb(fdb_tsl_t tsl, void *arg)
{struct fdb_blob blob;struct env_status status;fdb_tsdb_t db = arg;fdb_blob_read((fdb_db_t) db, fdb_tsl_to_blob(tsl, fdb_blob_make(&blob, &status, sizeof(status))));FDB_INFO("queried a TSL: time: %ld, temp: %d, humi: %d\r\n", tsl->time, status.temp, status.humi);return false;
}static bool set_status_cb(fdb_tsl_t tsl, void *arg)
{fdb_tsdb_t db = arg;FDB_INFO("set the TSL (time %ld) status from %d to %d\r\n", tsl->time, tsl->status, FDB_TSL_USER_STATUS1);fdb_tsl_set_status(db, tsl, FDB_TSL_USER_STATUS1);return false;
}#endif /* FDB_USING_TSDB */int databaseInit(void)
{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_lock_set((fdb_db_t)&kvdb, lock, 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_lock_set((fdb_db_t)&tsdb, lock, 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);if (result != FDB_NO_ERR) {return -1;}/* run TSDB sample */tsdb_sample(&tsdb);}
#endif /* FDB_USING_TSDB */return 0;
}
#ifdef __cplusplus ///<end extern c
}
#endif
/******************************** End of file *********************************/

GD32上FAL Flash分区驱动移植及Easyflash与FlashDB移植说明相关推荐

  1. Linux nor flash分区,Linux驱动开发笔记:NOR FLASH编写实例

    1. 背景介绍 板子上的zynq通过emc外接一块nor flash,地址分配如下: Nor flash的起始地址为0x80000000.当zynq上运行Linux后可以通过对该地址起始的区域进行擦除 ...

  2. 【FlashDB】第二步 FlashDB 移植 STM32L475 使用QSPI驱动外部 flash W25Q64之 SFUD 移植

    第一步写好了FAL移植,那么进行第二步 SFUD 移植 [FlashDB]第一步 FlashDB 移植到 STM32L475 使用QSPI驱动外部 flash W25Q64之FAL移植 准备工作 1. ...

  3. flash软件_FAL软件包的使用:FLASH分区管理

    什么是分区管理 FLASH分区管理是怎么一回事呢?我们可以以个人电脑来做类比,我们的电脑通常都分有很多个盘符: 这些都是我们硬盘的分区,我这里装了两块硬盘,512GB的机械硬盘+128GB的固态硬盘, ...

  4. 基于RT-Thread Studio的FAL,EasyFlash,文件系统移植

    一.新建工程 ​ 1.2.配置时钟 1.3.修改main文件 #include <rtthread.h> #include <rtdevice.h> #include < ...

  5. flash挂载到系统 spi_jffs2根文件系统挂载不上spi flash

    这几天一直在弄jffs2,让jffs2挂载到spi flash上,所以在内核中对spi flash进行了分区,给uboot了1M的空间,给kernel 4M的空间,给jffs2了11M的空间,因为我们 ...

  6. RT-thread应用讲解——FLASH分区

    RT-thread应用讲解--FLASH分区 目录 RT-thread应用讲解--FLASH分区 前言 一.挂载FLASH 二.ENV配置 1.打开on-chip flash 2.打开FAL软件包 3 ...

  7. Android Nand Flash 分区

    一般的嵌入式Linux开发人员是要清晰区分不同器材的作用和名称的.比如系统,内核所有保存在Nand Flash之上,断电后仍然存在,而运行后程序是装入SDRAM或Mobile DDR之类的内存设备运行 ...

  8. LoRa 之一 旧版驱动(sx12xxDrivers-V2.1.0)移植及驱动架构详解

      在之前的项目中,一直使用 LoRa 通信.很早之前就想写写文章记录一下学习过程.怎奈一直是一知半解的状态,想写不敢写!LoRa 这个东西在国内用的貌似不是太多.   对于无线通信,各个国家或者地区 ...

  9. 启明云端分享|sigmastar SSD201 \ SSD202D内存大小问题及flash分区问题解答

    提示:作为Espressif(乐鑫科技)大中华区合作伙伴及sigmastar(厦门星宸)VAD合作伙伴,我们不仅用心整理了你在开发过程中可能会遇到的问题以及快速上手的简明教程供开发小伙伴参考.同时也用 ...

最新文章

  1. golang 生成 指定大小 空白文件
  2. 内核模式下的注册表操作
  3. 【微信小程序】java中类和对象的区别
  4. 关于bat中使用rar压缩命令
  5. 无符号数的减法_C++核心准则ES.107:不要使用无符号数下标,使用gsl::index更好
  6. C/S,B/S的应用的区别
  7. live555 源码分析:MediaSever
  8. leetcode 84. Largest Rectangle in Histogram | 84. 柱状图中最大的矩形(单调栈)
  9. asterisk 支持 VP8 video编码 实现安卓的视频通话
  10. 浏览器下载文件时一共发送2次请求,如何把“下载次数”只记录为1次?
  11. 设置内核的运行环境之隔离的应用程序
  12. 基于拥挤距离与变异支配的多目标PSO算法
  13. setuna截图怎么放大缩小_实用的高清截图系列小窍门详解,一章带你“真正学会”截图!...
  14. 计算机病毒有熊猫病毒,世界最厉害的电脑病毒排名 熊猫烧香病毒最使人讨厌...
  15. SQL语句集锦 [转]
  16. 共享停车位的市场现状,共享车位盘活城市闲置车位!
  17. 图的计算(1):图的矩阵表示
  18. Mysql数据恢复---闪回恢复
  19. ApplePay 支付的简单使用
  20. 绕线机算法模型(Simulink仿真验证+PLC代码实现)

热门文章

  1. EOJ #3452 唐纳德先生和假骰子【暴力】
  2. 离线信号与连续信号伸缩变换的不同
  3. 手把手教你学51单片机-变量进阶与点阵LED
  4. 多媒体视频开发_(27)ffmpeg格式转换bsf的使用
  5. 韩松手机摄影笔记第五课--后期利器Snapseed
  6. css鼠标滑过按钮出现flash闪光效果
  7. 解决IDEA创建Maven工程没有src目录还很慢的问题
  8. android 各别控件缩放,[翻译]Android单手指缩放-第二部分(Android one finger zoom tutorial – Part 2)...
  9. win10 游戏全屏闪退桌面解决方法
  10. 陆虞候道 瑞星杀毒软件升级包