这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » MCU » 【IAR】 Flash Loader 下载过程解析

共2条 1/1 1 跳转至

【IAR】 Flash Loader 下载过程解析

工程师
2025-02-18 18:33:03     打赏

简介       

       IAR 在MCU 开发中是个经常使用的IDE,在IAR 环境下如何将编译器编译好的程序下载到MCU 中运行。整个下载过程主要有以下四个步骤。

准备:连接目标硬件与计算机,C-SPY 读取.flash 和.board 文件信息获取flash参数及flashloader信息。

启动:进入调试模式,C-SPY 初始化通信并建立连接,读取.board 文件选定 Flash Loader,将其下载到目标设备 RAM。

下载:C - SPY 划分应用程序映像数据到 RAM 缓冲区,执行 FlashErase 函数擦除目标 Flash 区域,再用 FlashWrite 函数将数据逐页写入 Flash,每写一页检查一次。

完成:校验 Flash 数据,若无误可退出调试,程序存于 Flash 可独立运行,也可继续调试分析。

我们基于上述四个步骤使用GD32F427开发板环境来解析flash 的下载过程。

准备及启动过程

以本地的GD32F427 的工程为示例,在deubug菜单的Download选项下可以配置对应的。board 配置文件。“$TOOLKIT_DIR$\config\flashloader\GD\FlashGD32F427xK.board”

image.png

默认情况下,使用的.board  文件为IAR 安装目录下的\config\flashloader\GD\FlashGD32F427xK.board 文件,对应的文件内容如下。

<?xml version="1.0" encoding="iso-8859-1"?>
<flash_board>
  <pass>
    <loader>$TOOLKIT_DIR$/config/flashloader/GD/FlashGD32F4xxxK.flash</loader>
    <range>CODE 0x08000000 0x082FFFFF</range>
  </pass>
  <pass>
    <loader>$TOOLKIT_DIR$/config/flashloader/GD/FlashGD32F4xxx_OTP.flash</loader>
    <range>CODE 0x1FFF7800 0x1FFF7A0F</range>
  </pass>
</flash_board>

上述xml 文件描述了芯片内部的有两块flah,分别为FlashGD32F4xxxK.flash 和 FlashGD32F4xxx_OTP.flash 和两块flash 的大小信息。

每块flash 有各自的配置的xml 文件来描述,对应的FlashGD32F4xxxK.flash 文件信息如下。

<?xml version="1.0" encoding="iso-8859-1"?>
<flash_device>
  <exe>$TOOLKIT_DIR$/config/flashloader/GD/FlashGD32F4xxx.out</exe>
  <page>4</page>
  <block>4 0x4000</block>
  <block>1 0x10000</block>
  <block>7 0x20000</block>
  <block>4 0x4000</block>
  <block>1 0x10000</block>
  <block>7 0x20000</block>
  <block>4 0x40000</block>
  <flash_base>0x08000000</flash_base>
  <macro>$TOOLKIT_DIR$/config/flashloader/GD/FlashGD32F4xx.mac</macro>
  <online>1</online>
  <aggregate>1</aggregate>
</flash_device>

FlashGD32F4xxx_OTP.flash 文件信息如下。

<?xml version="1.0" encoding="iso-8859-1"?>
<flash_device>
  <exe>$TOOLKIT_DIR$/config/flashloader/GD/FlashGD32F4xxx_OTP.out</exe>
  <page>1</page>
  <block>1 0x210</block>
  <flash_base>0x1FFF7800</flash_base>
  <macro>$TOOLKIT_DIR$/config/flashloader/GD/FlashGD32F4xx.mac</macro>
  <aggregate>1</aggregate>
</flash_device>

上述配置文件描述了flash 最小编程page 大小,块信息以及要使用的flash 下载程序,FlashGD32F4xxx.out/FlashGD32F4xxx_OTP.out 以及C-SPY调用的flashloader初始化配置宏函数。

FlashGD32F4xx.mac文件内容如下:

__var RCU_CFG0;
__var RCU_CTL;
__var RCU_INT;
__var FWDGT_PSC;
__var FWDGT_RLD;
__var FMC_WS;
__var FMC_CTL;

execUserFlashInit()
{
  RCU_CTL  = __readMemory32(0x40023800, "Memory");
  RCU_CFG0 = __readMemory32(0x40023808, "Memory");
  RCU_INT  = __readMemory32(0x4002380C, "Memory");

  __writeMemory32(0x00000000, 0x4002380C, "Memory");    // Disable interrupts
  __writeMemory32(RCU_CTL | 0x1, 0x40023800, "Memory"); // Enable IRC16M
  __writeMemory32(0x00000000, 0x40023808, "Memory");    // Switch system clock to IRC16M

  // Check if hardware watchdog is enabled
  if(!(0x20 & __readMemory32(0x40023C14,"Memory")))
  {
    FWDGT_PSC = __readMemory32(0x40003004, "Memory");
    FWDGT_RLD = __readMemory32(0x40003008, "Memory");
    // Unlock FWDGT registers
    __writeMemory32(0x5555, 0x40003000,"Memory");
    // Prescaler
    if (FWDGT_PSC != 0x7)
    {
      __writeMemory32(0x7, 0x40003004, "Memory");
    }
    // Reload
    if (FWDGT_RLD != 0xFFF)
    {
      __writeMemory32(0xFFF, 0x40003008, "Memory");
    }
    // Reload FWDGT
    __writeMemory32(0xAAAA, 0x40003000,"Memory");
  }

  // Keep FMC register values
  FMC_WS  = __readMemory32(0x40023C00,"Memory");
  FMC_CTL = __readMemory32(0x40023C10,"Memory") & 0xFFFF0000;

  // Unlock FMC_CTL register
  if(FMC_CTL & (1<<31))
  {
    __writeMemory32(0x45670123, 0x40023C04, "Memory"); // FMC_KEY = FMC_KEY1;
    __writeMemory32(0xCDEF89AB, 0x40023C04, "Memory"); // FMC_KEY = FMC_KEY2;
  }
  __writeMemory32(0x00000000, 0x40023C00, "Memory"); // Flash 0 wait state
  __writeMemory32(0x00000000, 0x40023C10, "Memory"); // Clear Interrupt Enable
  __writeMemory32(0x000001D3, 0x40023C0C, "Memory"); // Clear Status Flags
}

execUserFlashExit()
{
  // Restore registers modified earlier

  __writeMemory32(FMC_WS, 0x40023C00, "Memory");
  __writeMemory32(FMC_CTL, 0x40023C10, "Memory");

  if(!(0x20 & __readMemory32(0x40023C14, "Memory")))
  {
    __writeMemory32(0x5555, 0x40003000, "Memory");
    if (FWDGT_PSC != 0x7)
    {
      __writeMemory32(IWDG_PR, 0x40003004, "Memory");
    }
    if (FWDGT_RLD != 0xFFF)
    {
      __writeMemory32(FWDGT_RLD, 0x40003008, "Memory");
    }
    __writeMemory32(0xAAAA, 0x40003000, "Memory");
  }

  __writeMemory32(RCU_CFG0, 0x40023808, "Memory");
  __writeMemory32(RCU_CTL, 0x40023800, "Memory");
  __writeMemory32(RCU_INT, 0x4002380C, "Memory");
}

上述宏函数会完成flashloader 程序FlashGD32F4xxx.out 运行前的初始化工作,关闭中断,配置时钟为内部的RC16M时钟,并解锁flash 编程,为flashloader程序的装载运行提供运行时环境。

下载过程

初始化flashloader 运行时环境后,C-SPY 会将FlashGD32F4xxx.out 加载到内存中运行,并调用其中的erase/write接口完成flash 的下载更新。

image.png

完成阶段

下载完成后会校验flash,并设置PC指针至Reset 地址运行更新后的程序。

IAR 开启如下配置校验下载的flash 镜像

image.png

对应的debug 窗口log 信息如下:

image.png

如果不开启上述的校验配置,只会有下载完成的日志信息。

image.png



院士
2025-02-18 23:25:21     打赏
2楼

很多年不使用IAR了。

当年使用atmel128的时候认识的IAR。


共2条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]