最近做一个项目用到GD32E230这款MCU,原厂配套有非常全的SDK例程和Datasheet,驱动库与STM32的标准库很类似,只要有STM32的使用经验,很快就可以上手GD32的开发。
项目中外挂一个4MB的W25Q32 SPI-Flash存放字体资源数据,在前期调试功能阶段,需要频繁更改资源数据,改完再重新烧录数据到SPI-Flash,一般使用专用的烧录工具飞线到flash引脚上,用上位机软件烧录资源bin,如果有多台样机需要测试,那么则需要每台样机都要飞线,且要拆掉外壳,显然很麻烦。
本文介绍如何制作一个烧写外部Flash的FLM下载算法,借助J-Link SWD就可以方便地更新Flash资源文件。
本文完整工程下载:GD32E230_W25Q32_FLM
Keil官方指导文档:《Programming External Flash used with STM32 Devices》
创建下载算法工程安装Keil后,可以在其安装目录下找到FLM下载算法的模板工程:
Keil_v5ARMPACKARMCMSIS5.6.0Device_Template_Flash
算法工程创建步骤如下:
-
拷贝该模板工程到自己的工作目录下,注意此工程源文件是只读属性,我们需要右键选择文件去掉只读属性;
-
我这里将工程名重命名为GD32E230_W25QXX,同时将CMSIS和GD32E23x的驱动库拷贝到工程目录下:
-
实现spi驱动,spi_flash驱动,为了调试方便能够使用打印一些调试信息,也实现串口驱动和printf打印,这里存放在Drivers目录下:
.Drivers ├── bsp_spi.c #SPI驱动 ├── bsp_spi.h ├── bsp_uart.c #UART驱动 ├── bsp_uart.h ├── spi_flash.c #FALSH驱动 └── spi_flash.h
- 将源文件添加到工程,组织关系如下:
- 修改工程Device配置,选择为GD32E230C8:
- FLM算法名改为GD32E230_W25QXX:
J-Flash/Keil工具会将FLM load到MCU的RAM中,然后使用其接口来操作Flash设备,FLM的代码必须是位置无关代码,其链接脚本为Target.lin。
FLM下载算法,主要有以下几个函数需要实现,
其中,如果不做数据正确性的校验,BlankCheck、Verify可以暂时不实现,其他几个重要的函数实现如下:
Flash操作函数实现
- 系统时钟、Flash器件的初始化:
int Init (unsigned long adr, unsigned long clk, unsigned long fnc)
{
int id = 0;
SystemInit();
spi0_init();
uart0_init();
id = spi_flash_read_id();
if (id != W25Q32) {
log_printf("[SPI-Flash] ERR:spi flash not exist!rn");
}
log_printf("[SPI-Flash] spi flash id=0x%xrn", id);
return (0);
}
- Flash整片擦除:
int EraseChip (void)
{
spi_flash_erase_chip();
return (0);
}
- Flash按扇区擦除:
int EraseSector (unsigned long adr)
{
spi_flash_erase_sector(adr);
return (0);
}
- Flash编程,将对应长度的数据写到对应的Flash地址上:
int ProgramPage (unsigned long adr, unsigned long sz, unsigned char *buf)
{
spi_flash_write_no_check(adr, buf, (uint16_t)sz);
return (0);
}
FlashDev参数调整
FlashDev.c中,FlashDevice结构体定义了Flash的描述参数,需要根据实际情况调整其参数:
struct FlashDevice const FlashDevice = {
FLASH_DRV_VERS, // Driver Version, do not modify!
"GD32E230_W25QXX", // Device Name
EXTSPI, // Device Type
0x00000000, // Device Start Address
0x00400000, // Device Size in Bytes (重要:需要根据实际器件容量进行调整)
4096, // Programming Page Size
0, // Reserved, must be 0
0xFF, // Initial Content of Erased Memory
1000, // Program Page Timeout 100 mSec
3000, // Erase Sector Timeout 3000 mSec
// Specify Size and Address of Sectors
0x001000, 0x000000, // Sector Size 4kB (8 Sectors)
SECTOR_END
};
编译
完成上述工作后,直接编译,会在工程根目录生成GD32E230_W25QXX.FLM文件。
但是此时的FLM还有问题,因为SPI、UART、Clock驱动底层使用了GD32E23x的标准驱动库,函数层级较多,代码量已超过8KB的RAM容量,使用时会报如下错误:
将配置工程优化等级为-Oz image size,观察map文件结果,Code size小于8KB:
项目需要借助FLM烧写板载的Flash,因此我选用J-Flash作为烧写上位机。
FLM要支持J-Flash,要经过一些配置:
-
安装J-Link软件,会在J-Link安装目录下找到:C:Program Files (x86)SEGGERJLinkJLinkDevices.xml,我安装的J-Link版本为V6.98b,如果读者是安装的其他版本J-Link,方法也是类似。
-
为了方便,拷贝GD32E230_W25QXX.FLM文件到SEGGERJLinkDevices目录下。
-
打开JLinkDevices.xml文件,文末添加如下代码段:
- 打开JFlash.exe,按下图找到我们新加入的GD32E230_W25Q32设备:
- [Target]->[Connect]成功连接上设备:
本章介绍烧录资源bin文件步骤:
- [File]->[Open data file]打开资源bin文件:
- [Target]->[Mannua Programming]->[Erase Sectors]擦除扇区:
- [Target]->[Mannua Programming]->[Program]开始烧写:
至此,本文介绍如何制作部一个烧写外部Flash的FLM文件完毕,本文虽然是针对GD32E230这款MCU,但是可以类比和搬移到其他MCU,方法都是相通的。



