GD32外部SPI Flash下载算法制作

GD32外部SPI Flash下载算法制作

前言

最近做一个项目用到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_v5\ARM\PACK\ARM\CMSIS\5.6.0\Device\_Template_Flash
GD32外部SPI Flash下载算法制作_第1张图片

算法工程创建步骤如下:

  1. 拷贝该模板工程到自己的工作目录下,注意此工程源文件是只读属性,我们需要右键选择文件去掉只读属性;

  2. 我这里将工程名重命名为GD32E230_W25QXX,同时将CMSIS和GD32E23x的驱动库拷贝到工程目录下:
    GD32外部SPI Flash下载算法制作_第2张图片

  3. 实现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
  1. 将源文件添加到工程,组织关系如下:
    GD32外部SPI Flash下载算法制作_第3张图片
  2. 修改工程Device配置,选择为GD32E230C8:
    GD32外部SPI Flash下载算法制作_第4张图片
  3. FLM算法名改为GD32E230_W25QXX:
    GD32外部SPI Flash下载算法制作_第5张图片

算法实现

J-Flash/Keil工具会将FLM load到MCU的RAM中,然后使用其接口来操作Flash设备,FLM的代码必须是位置无关代码,其链接脚本为Target.lin
GD32外部SPI Flash下载算法制作_第6张图片
FLM下载算法,主要有以下几个函数需要实现,
GD32外部SPI Flash下载算法制作_第7张图片
其中,如果不做数据正确性的校验,BlankCheck、Verify可以暂时不实现,其他几个重要的函数实现如下:

Flash操作函数实现

  1. 系统时钟、Flash器件的初始化:
int Init (unsigned long adr, unsigned long clk, unsigned long fnc)
{
    int id = 0;

    SystemInit();            /* 系统出初始化  */
    spi0_init();             /* SPI外设初始化 */
    uart0_init();            /* UART外设初始化 */
    id = spi_flash_read_id();
    if (id != W25Q32) {
        log_printf("[SPI-Flash] ERR:spi flash not exist!\r\n");
    }
    log_printf("[SPI-Flash] spi flash id=0x%x\r\n", id);

    return (0);
}
  1. Flash整片擦除:
int EraseChip (void)
{
    spi_flash_erase_chip();
    return (0);
}

  1. Flash按扇区擦除:
int EraseSector (unsigned long adr)
{
    spi_flash_erase_sector(adr);
    return (0);
}
  1. 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容量,使用时会报如下错误:
GD32外部SPI Flash下载算法制作_第8张图片
将配置工程优化等级为-Oz image size,观察map文件结果,Code size小于8KB:
GD32外部SPI Flash下载算法制作_第9张图片

J-Flash配置

项目需要借助FLM烧写板载的Flash,因此我选用J-Flash作为烧写上位机。

FLM要支持J-Flash,要经过一些配置:

  1. 安装J-Link软件,会在J-Link安装目录下找到:C:\Program Files (x86)\SEGGER\JLink\JLinkDevices.xml,我安装的J-Link版本为V6.98b,如果读者是安装的其他版本J-Link,方法也是类似。

  2. 为了方便,拷贝GD32E230_W25QXX.FLM文件到SEGGER\JLink\Devices\目录下。

  3. 打开JLinkDevices.xml文件,文末添加如下代码段:

  
  
  
  <Device>
    <ChipInfo Vendor="GD" Name="GD32E230_W25Q32"  Core="JLINK_CORE_CORTEX_M23" WorkRAMAddr="0x20000000" WorkRAMSize="0x2000"/>
    <FlashBankInfo Name="SPI FLASH" BaseAddr="0x00000000" MaxSize="0x00400000" Loader="Devices/GD32E230_W25QXX.FLM" LoaderType="FLASH_ALGO_TYPE_CMSIS" />
  Device>

  1. 打开JFlash.exe,按下图找到我们新加入的GD32E230_W25Q32设备:
    GD32外部SPI Flash下载算法制作_第10张图片
  2. [Target]->[Connect]成功连接上设备:
    GD32外部SPI Flash下载算法制作_第11张图片

烧录体验

本章介绍烧录资源bin文件步骤:

  1. [File]->[Open data file]打开资源bin文件:
    GD32外部SPI Flash下载算法制作_第12张图片
  2. [Target]->[Mannua Programming]->[Erase Sectors]擦除扇区:
    GD32外部SPI Flash下载算法制作_第13张图片
  3. [Target]->[Mannua Programming]->[Program]开始烧写:
    GD32外部SPI Flash下载算法制作_第14张图片
    至此,本文介绍如何制作部一个烧写外部Flash的FLM文件完毕,本文虽然是针对GD32E230这款MCU,但是可以类比和搬移到其他MCU,方法都是相通的。

你可能感兴趣的:(GD32,MCU,stm32,单片机,arm开发,arm)