RT_Thread GD32F303 片上flash使用fal组件
片上flash加载fal的文章很多,就不多做赘述,我参考的链接
https://www.cnblogs.com/Monarch-T/p/12557936.html
唯一不一样的是,没有drv_flash_f7.c,要自己写。
drv_flash_f4.c
#include "board.h"
#include <rtthread.h>
#include "gd32f30x.h"
#include <fal.h>
#define GD32_FLASH_START_ADRESS ((uint32_t)0x08080000) //我的是1M,自己看芯片ROM大小
#define FLASH_SIZE_GRANULARITY_512K (512 * 1024)
#define GD32_FLASH_END_ADDRESS ((uint32_t)0x08100000)
int fal_flash_write(long offset, const rt_uint8_t *buf, size_t size)
{
size_t i;
rt_uint16_t buf16;
rt_uint32_t addr = GD32_FLASH_START_ADRESS + offset;
if ((addr + size) > GD32_FLASH_END_ADDRESS)
{
//LOG_E("ERROR: erase outrange flash size! addr is (0x%p)\n", (void*)(addr + size));
return -1;
}
/* unlock the flash program/erase controller */
fmc_unlock();
fmc_flag_clear(FMC_FLAG_BANK0_END | FMC_FLAG_BANK1_WPERR | FMC_FLAG_BANK1_PGERR );
i = (size_t)addr;
if(i % 2 == 1) //这么写了单字节还是会存不进去,只能保证没存错
{
buf16 = *((rt_uint16_t*)buf)<<8 | 0xff;
fmc_halfword_program(addr-1, buf16);
buf++;
addr++;
size--;
}
for(i=0;i<size;i+=2)
{
buf16 = *((rt_uint16_t*)buf);
if(size-1 == i)
{
buf16 |= 0xff00;
}
fmc_halfword_program(addr+i, buf16);
buf += 2;
}
/* lock the main FMC after the erase operation */
fmc_lock();
return size;
}
static int fal_flash_erase(long offset, size_t size)
{
size_t i;
rt_uint32_t addr = GD32_FLASH_START_ADRESS + offset;
if ((addr + size) > GD32_FLASH_END_ADDRESS)
{
//LOG_E("ERROR: erase outrange flash size! addr is (0x%p)\n", (void*)(addr + size));
return -1;
}
/* unlock the flash program/erase controller */
fmc_unlock();
fmc_flag_clear(FMC_FLAG_BANK0_END | FMC_FLAG_BANK0_WPERR | FMC_FLAG_BANK0_PGERR | FMC_FLAG_BANK1_WPERR | FMC_FLAG_BANK1_PGERR );
for(i=0;i<size;i+=0x400)
{
fmc_page_erase(addr);
addr += 0x400;
fmc_flag_clear(FMC_FLAG_BANK0_END | FMC_FLAG_BANK0_WPERR | FMC_FLAG_BANK0_PGERR | FMC_FLAG_BANK1_WPERR | FMC_FLAG_BANK1_PGERR );
}
/* lock the main FMC after the erase operation */
fmc_lock();
return size;
}
static int fal_flash_read(long offset, rt_uint8_t *buf, size_t size)
{
size_t i;
rt_uint32_t addr = GD32_FLASH_START_ADRESS + offset;
if ((addr + size) > GD32_FLASH_END_ADDRESS)
{
//LOG_E("read outrange flash size! addr is (0x%p)", (void*)(addr + size));
return -1;
}
for (i = 0; i < size; i++, buf++, addr++)
{
*buf = (*(__IO uint8_t*) addr);
}
return size;
}
const struct fal_flash_dev onchip_flash_512k = { "onchip_flash_512k", GD32_FLASH_START_ADRESS, FLASH_SIZE_GRANULARITY_512K, (1024), {NULL, fal_flash_read, fal_flash_write, fal_flash_erase} };
fal_cfg.h 修改
#ifndef _FAL_CFG_H_
#define _FAL_CFG_H_
#include <rtconfig.h>
#include <board.h>
#define NOR_FLASH_DEV_NAME "onchip_flash_512k"
/* ===================== Flash device Configuration ========================= */
extern const struct fal_flash_dev onchip_flash_512k;
/* flash device table */
#define FAL_FLASH_DEV_TABLE \
{ \
&onchip_flash_512k, \
}
/* ====================== Partition Configuration ========================== */
#ifdef FAL_PART_HAS_TABLE_CFG
/* partition table */
#define FAL_PART_TABLE \
{ \
{FAL_PART_MAGIC_WORD, "easyflash", NOR_FLASH_DEV_NAME, 0, 510*1024, 0}, \
{FAL_PART_MAGIC_WORD, "download", NOR_FLASH_DEV_NAME, 510*1024, 2*1024, 0}, \
}
#endif /* FAL_PART_HAS_TABLE_CFG */
#endif /* _FAL_CFG_H_ */
注意
最小粒度是2byte,要用easyflash时需要注意选择!
elf文件系统尝试过,搞不起来,littlefs文件系统倒是可以!