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)
", (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)
", (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文件系统倒是可以!

原文地址:https://www.cnblogs.com/yywBlogW/p/14380910.html