前往下载
#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_ */
更名为:fal_flash_gd32f2_port.c(这个操作依据自己芯片平台非必须)
主要完善以下接口:
GD32的FLASH操作接口已改为HAL方式,HAL的移植方式参考我的博客https://editor.csdn.net/md/?articleId=106135522
#include
#include
#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 cur_erase_sector;
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(cur_erase_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
};
由于操作flash的接口是由sfud万能驱动接口做的,所以参考sfud的移植,当然不移植就需要自己实现外部SPI Flash的读取/写入/擦除驱动。
fal_flash_sfud_port.c
修改如下:
#include
#include
#define FAL_USING_SFUD_PORT
#ifdef FAL_USING_SFUD_PORT
#ifdef RT_USING_SFUD
#include
#endif
#ifndef FAL_USING_NOR_FLASH_DEV_NAME
#define FAL_USING_NOR_FLASH_DEV_NAME "norflash0"
#endif
static 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);
#endif
if (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 V5.X
或者最新更名的FlashDB
底层调用接口都是FAL,所以实现了FAL移植,Easyflash和FlashDB都无需较大更改,直接加入源码到工程目录即可使用。
需要注意的是:easyflash首先执行初始化sfud,之后是fal初始化,否则flash容量大小会被篡改为0!
当使用操作系统时,注意线程分配的堆栈大小,应>512Byte否则易出现Hardfault错误,坑已踩过!
主要增加宏定义:#define FDB_USING_KVDB
与设置FDB_WRITE_GRAN
大小
/*
* Copyright (c) 2020, Armink,
*
* 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 ///