一、Onchip Flash 特性
- 在STM32G070 的片内 Flash写入数据之前必须先对目标地址进行擦除后才能写入数据
- 数据写入:G070 Flash 写入数据必须保证8字节对齐,一次写入双字数据64bit 8Byte
- 数据读取:使用地址直接读取
二、移植FAL
1. 添加以下文件到工程
2. 修改fal_cfg.h 中分区表
片上Flash需要注意 分区地址避开程序的存储地址否则将导致程序不能正常运行
#define FAL_PART_TABLE \
{ \
{FAL_PART_MAGIC_WORD, "fdb_tsdb", "stm32_onchip", 100*1024, 4*1024, 0}, \
{FAL_PART_MAGIC_WORD, "fdb_kvdb", "stm32_onchip", 104*1024, 4*1024, 0}, \
}
3. 添加fal_flash_stm32g0_port.c
由于STM32G070 片上Flash 目标地址 只要写入过一次数据()就不可以再次写入数据,必须先擦除在写入,也许与FLASH的校验、纠错机制有关系
#define PAGE_SIZE 2048
static int init(void)
{
return 1;
}
static int read(long offset, uint8_t *buf, size_t size)
{
size_t i;
uint32_t addr = stm32_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 addr = stm32_onchip_flash.addr + offset;
__ALIGN_BEGIN uint64_t write_data __ALIGN_END;
__ALIGN_BEGIN uint64_t read_data __ALIGN_END;
HAL_FLASH_Unlock();
for (i = 0; i < size; i+=8)
{
read_data = *(uint64_t *)(addr+i);
if (read_data != (uint64_t)(*((uint64_t *)((uint32_t)buf + i))))
{
HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, (uint32_t)(uint64_t*)(addr+i),(uint64_t)(*((uint64_t *)((uint32_t)buf + i))));
read_data = *(uint64_t *)(addr+i);
if (read_data != (uint64_t)(*((uint64_t *)((uint32_t)buf + i))))
{
HAL_FLASH_Lock();
return -1;
}
else
{
feed_dog();//FLash操作可能非常耗时,如果有看门狗需要喂狗,以下代码由用户实现
}
}
}
HAL_FLASH_Lock();
return size;
}
static int erase(long offset, size_t size)
{
HAL_StatusTypeDef flash_status;
FLASH_EraseInitTypeDef EraseInitStruct;
uint32_t HeadErasePage = offset/FLASH_PAGE_SIZE,PAGEError = 0;
size_t erase_pages = size / FLASH_PAGE_SIZE;
if(size % FLASH_PAGE_SIZE != 0) erase_pages++;
EraseInitStruct.Banks = FLASH_BANK_1;
EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
EraseInitStruct.NbPages = 1; //一次擦出一个扇区, 以执行一次喂狗,防止超时
HAL_FLASH_Unlock();
for (size_t i = 0; i < erase_pages; i++)
{
EraseInitStruct.Page = HeadErasePage + i;
flash_status = HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError);
if (flash_status != HAL_OK)
{
HAL_FLASH_Lock();
return -1;
}
else
{
feed_dog();
}
}
HAL_FLASH_Lock();
return size;
}
const struct fal_flash_dev stm32_onchip_flash =
{
.name = "stm32_onchip",//Flash名称
.addr = 0x08000000,//Flash起始地址
.len = 128*1024,//Flash的大小
.blk_size = 2*1024,//一次性可擦除的Flash大小
.ops = {init, read, write, erase},//Flash访问驱动
.write_gran = 64 //最小写入粒度64位按照8字节对齐
};
三、移植FlashDB
1. 添加FlashDB文件到工程
2. 修改fdb_cfg.h头文件中关于写入粒度的定义
/* the flash write granularity, unit: bit
* only support 1(nor flash)/ 8(stm32f2/f4)/ 32(stm32f1) */
#define FDB_WRITE_GRAN 64
3.参考sample案列使用
以下地址包含API说明
FlashDB仓库