基于IAR的外部Flash烧录算法

一、简介

当内部的Flash不够使用时可以通过拓展外部Flash来存储更多代码和数据。上章讲了W25N04的Flash驱动,这次来将如何讲如何讲代码烧录到W25N04上。

二、系统框架

首先了解一下代码是如何通过编译器烧录到硬件上的。
1、IAR将读取xx.board文件获取PCB的flash描述和每个flash对应的烧录算法(flashloader)。
2、IAR通过烧录器将烧录算法加载到MCU的RAM中。
3、IAR通过flashloader将代码烧录到对应的flash中。
(xx.board文件:描述了PCB上的flash资源和对应的.flash文件地址)
(xx.out文件:flashloader的工程输出,也就是烧录算法本体)
(xx.max文件:.mac 文件(宏文件)是一个关键的配置和脚本文件,主要用于 调试阶段的硬件初始化和自动化操作。它的核心作用是通过脚本语言(类似 C 语言)控制调试器(C-SPY)与目标硬件的交互,从而实现调试前的硬件准备、调试过程的自动化,以及烧录程序时的外设配置。)
(xx.flash:描述flash的基本参数和对应的算法文件xx.out)

在这里插入图片描述

三、flashloader基础工程构建

在IAR的软件安装路径下有许多写好的flashloader工程,如下图所示。我们找到对应芯片的型号复制一份就好了。
在这里插入图片描述
我以STM32F4XX NOR的为例,复制一份工程做当模板进行开发。
在这里插入图片描述
这里最重要的是要实现图中标记的文件。Framework,flash_loader.c定义的是一些被调用的Flash接口。而用户实现则放在了
FlashSTM32F10x_NOR.c中。实现用户自己的Flash驱动并适配flash_loader的接口。

四、实现Flashloader

创建一个工程添加模板中必要的文件,如下图所示。添加的Flash_Loader 等同于模板中的Framework,其他的是Flash驱动的本体和依赖文件。
在这里插入图片描述

1、配置链接文件

前面说了,flashloader是加载到RAM中运行的,这里我们也是将链接地址修改成RAM的地址。
在这里插入图片描述
在这里插入图片描述

2、实现Flash驱动

这里就不细说了,本章重点讲解Flashloader的内容。关于W25N04xx的驱动在这里

3、适配Flashloader对应的接口

1)FlashInit

该函数主要实现系统和Flash的初始化功,如果Debug的需要可以添加UART功能。另外需要存储函数参数中的base_of_flash,后面会有用到。代码如下,

uint32_t FlashInit(void *base_of_flash, uint32_t image_size,
                   uint32_t link_address, uint32_t flags,
                   int argc, char const *argv[])
{
  
  sys_stm32_clock_init(360, 25, 2, 8); /* 设置时钟,180Mhz */
  delay_init(180);                     /* 延时初始化 */
  usart_init(90, 115200);              /* 初始化USART */
  
  w25n04k_init(); /* 初始化W25N04K闪存 */

  base_addr = (uint32_t)base_of_flash;
  printf("base addr = 0x%x\r\n", base_addr);
//	main(); // init system
	// w25n04k_test(); // Test W25N04K flash memory
  
  //  sfud_demo(0, sizeof(sfud_demo_test_buf), sfud_demo_test_buf);
  return RESULT_OK;
}

2)FlashWrite

这里是先的是写Flash的内容,需要将参数转化成相对于Flash的绝对地址。

uint32_t FlashWrite(void *block_start,
                    uint32_t offset_into_block,
                    uint32_t count,
                    char const *buffer)
{
  uint32_t dest = (uint32_t)block_start + offset_into_block - base_addr;
  // W25QXX_Write((uint8_t *)buffer, dest, count);
  printf("flash write addr:0x%x , size:%d\r\n", dest, count);
  //  const sfud_flash *flash = sfud_get_device(SFUD_W25Q256_DEVICE_INDEX);
  //  sfud_write(flash, dest, count, buffer);
  w25n04k_write(dest, (uint8_t *)buffer, count);
  printfArrayHex(buffer, 100);
  return 0;
}

3) FlashErase

uint32_t FlashErase(void *block_start,
                    uint32_t block_size)
{
  // W25QXX_EraseSector((uint32_t)block_start - base_addr);
  //  const sfud_flash *flash = sfud_get_device(SFUD_W25Q256_DEVICE_INDEX);
   uint32_t addr = (uint32_t)block_start - base_addr;
   printf("flash erase addr:0x%x , size:%d\r\n", addr, block_size);
  //  sfud_erase(flash, addr, block_size);
  w25n04k_earse(addr, block_size);
  return 0;
}

至此已完成了Flashloader的接口适配了

五、添加Flashloader到项目中

1、主项目中添加.board文件

这里添加外部flash的声明。
range范围是MCU中的绝对地址。后续链接文件中需要声明内容链接到改地址。
loader声明了Flashloader.flash对应的文件。
rel_offset是烧录的时候flash的偏移地址,0x90000000 - 0x90000000 = 0。
创建.board文件并放置在.eww文件(工程文件)下。

<?xml version="1.0" encoding="UTF-8"?>
<flash_board>
    <pass>
        <loader>$TOOLKIT_DIR$/config/flashloader/ST/FlashSTM32F427xG.flash</loader>
        <range>CODE 0x8000000 0x81fffff</range>
    </pass>
    <pass>
        <loader>$PROJ_DIR$\FlashLoader\STM32F4xx_SPI.flash</loader>
        <range>CODE 0x90000000 0x91ffffff</range>
        <rel_offset>-0x90000000</rel_offset>
    </pass>
</flash_board>

2、主项目中添加Flashloader相关文件

将Flashloader文件输出的.out文件、.mac和.flash文件添加到工程目录下。
在这里插入图片描述
.mac文件使用IAR的模板中的文件。
.flash文件需要参考模板进行修改。
以下可供参考。
flash_base将被作为参数传入到前面提及的FlashInit函数中。
page参数是页大小。
block描述了flash块的数量和大小。

<?xml version="1.0" encoding="iso-8859-1"?>
<flash_device>
  <exe>$PROJ_DIR$\FlashLoader\SPIFlashLoader.out</exe>
  <page>2048</page>
  <block>1024 0x20000</block>
  <flash_base>0x00000000</flash_base>
  <aggregate>1</aggregate>
</flash_device>

至此已经完成将Flashloader添加到主项目中了。
但是想要代码或数据存储在外部flash还需要修改链接脚本。
另外值得一提的是SPI驱动的Flash不支持XIP(在存储本地运行),所以需要将代码和数据加载到RAM或者MCU的ROM中。
这将会在下一期讲。

### IAR烧录教程 IAR 是一款广泛应用于嵌入式开发的集成开发环境 (IDE),支持多种微控制器架构。以下是有关 IAR 烧录程序的关键知识点: #### 基础操作流程 在初次使用 IAR 进行程序烧录时,开发者通常会遇到一些困惑。基本的操作步骤如下[^1]: - 打开 IAR Embedded Workbench 并创建一个新的项目。 - 配置目标设备参数,包括芯片型号、工作频率等。 - 编写源代码并通过编译生成可执行文件 (.out 或 .hex 文件)。 - 使用内置工具或外部仿真器将生成的目标文件下载至目标硬件。 #### 自动化处理技巧 为了提高效率,在某些情况下可以通过 Python 脚本来实现自动化任务管理。例如设置初始目录有助于确保脚本能够找到必要的资源文件;如果忽略此选项,默认路径将是当前工程所在位置[^2]。 #### 解决常见错误提示 当尝试通过串口进行调试或者烧录过程中出现问题时,可能涉及以下几个方面的原因分析与解决方案[^3]: - **初始化通讯失败**: 检查物理连线是否牢固以及所选端口号是否匹配实际使用的USB转TTL模块; - 如果更换不同主板继续操作前需先终止现有进程以免冲突影响新加载过程; - 对于无法检测到预期中的 COM 号码情况,则重新插拔驱动装置确认系统已正确安装对应版本驱动程序后再测试一次连接状态。 ### 示例代码片段展示如何配置简单的LED闪烁实验 ```c #include "ioCC2530.h" void delay(void){ unsigned int i,j; for(i=0;i<500;i++) for(j=0;j<1275;j++); } int main(){ P1DIR |= 0x01; // Set Port 1.0 as output pin while(1){ P1OUT ^= 0x01; // Toggle LED connected at port P1.0 delay(); // Call custom made function to create time lag between toggles. } } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值