你们好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给你们介绍的是IAR开发环境下i.MXRT的串行NOR Flash下载算法设计。html
在i.MXRT硬件那些事系列之《在串行NOR Flash XIP调试原理》一文中,痞子衡简单提了一下串行NOR Flash下载算法的概念,并无介绍具体设计细节,关于NOR Flash下载算法每一个IDE都有本身的一套设计,虽然基本设计理念是同样的,可是细节方面仍是有区别。在前面的文章里,痞子衡分别介绍过《J-Link下算法设计》、《Keil MDK下算法设计》,今天痞子衡就来细聊IAR下的NOR Flash下载算法:算法
IAR跟Keil同样都是很是经典的MCU开发IDE,能够说是难分伯仲,痞子衡求学期间就用IAR开发过MSP430单片机,可是只是浅尝辄止,由于搞ARM Cortex-M就切换到更熟悉的Keil下了,直到毕业后加入恩智浦才一直在用IAR。这么多年过去了,IAR仍是当初那个独立小公司,没有被收购,并且依然保持竞争力,这一波RISC-V浪潮估计会让它超越被ARM束缚的Keil。api
从IAR官网上看,目前最新的IAR EWARM版本是v8.50.6,其可以支持目前全部已量产的i.MXRT系列。若是你安装的不是最新版本,好比安装了v8.40,从 IAR历史各版本Release Note 上看,v8.40版本不支持RT500和RT600,那么若是想要支持新芯片(好比RT600),是否是必定要从新安装最新IAR呢?其实未必!微信
IAR对新MCU型号的支持并非与自身版本严格绑定的,其增长新芯片的方式很灵活,只须要按要求打上相应芯片的patch包便可。session
在 IAR历史各版本Release Note 页面点击 8.50 进入这个版本的专属页面,往下翻你会找到专门的i.MXRT600 patch包,直接下载这个包(ewarm850-nxp-imxrt5xx-6xx-patch4.zip文件)。app
有了patch包以后,打patch就至关简单了,直接将ewarm850-nxp-imxrt5xx-6xx-patch4.zip包解压放到IAR安装目录下便可,patch包的文件目录结构与IAR下安装目录结构是同样的。框架
patch包里的文件不少,其中跟下载算法相关的一共以下四个文件:.board和.flash是xml文件,其功能相似JLink下的JLinkDevices.xml文件。.mac是预加载文件,功能相似JLink下的.JLinkScript文件,.out文件就是真正的下载算法可执行文件。ide
\arm\config\flashloader\NXP\FlashIMXRT600_EVK_FLEXSPI.board \arm\config\flashloader\NXP\FlashIMXRT600_EVK_FLEXSPI.flash \arm\config\flashloader\NXP\FlashIMXRT600_EVK_FLEXSPI.mac \arm\config\flashloader\NXP\FlashIMXRT600_EVK_FLEXSPI.out
两个xml文件里的代码含义在 \IAR Systems\Embedded Workbench 8.50.6\arm\doc\FlashLoaderGuide.ENU.pdf 文档的 The flash memory configuration file 和 The flash memory system configuration file 两小节里有详细解释。函数
.board顾名思义就是板级描述文件,每一个.board文件能够指向多个.flash文件(若是这块板子存在多块flash)。让咱们试着分析 FlashIMXRT600_EVK_FLEXSPI.board 文件中那些模板代码的含义:.board文件里能够有多个<pass>块,每一个pass对应一种flash类型。在每一个<pass>里最多有以下6个参数(其中loader参数是必须的,其余是可选):性能
loader -- 指示.flash文件路径。 range -- Flash在芯片内存中的映射空间范围。 abs_offset -- 当被下载的app连接地址与往Flash中下载的映射地址不一样时,指示Flash下载地址。 rel_offset -- 做用与abs_offset相似,可是指示连接地址与下载地址间的偏移,可正可负。 flash_base -- Flash在芯片内存中的映射基地址,会覆盖.flash文件中同名参数。 args -- 传入下载算法FlashInit()函数,类argc/argv格式。
.flash就是flash描述文件了,这些信息最终会提供给调试器。让咱们继续分析 FlashIMXRT600_EVK_FLEXSPI.flash 文件中那些模板代码的含义:.flash文件里最多有以下12个参数(其中前四个参数是必须的,其余是可选):
exe -- 指示下载算法文件(.out)路径。 flash_base -- Flash在芯片内存中的映射基地址。 page -- Flash的页大小。 block -- Flash的块数量及大小。 gap -- 标示Flash中块的无效区间,C-SPY会检查并返回错误。 macro -- 指示预加载文件(.mac)路径。 online -- 指示下载算法是否支持Flash断点。 filler -- 下载时的padding内容,默认255(0xFF). checks -- 设为0则强制检查下载算法中函数(好比FlashWrite)的返回值,不启用这些检查能提高下载性能。 aggregate -- 若是Flash块大小明显小于RAM缓冲区,该参数设为1,可指示C-SPY高效使用RAM缓冲区去下载(好比将多个block数据放到RAM缓冲区)。 args -- 传入下载算法FlashInit()函数,类argc/argv格式。 args_doc -- args参数的描述字段(IDE里会显示)。
随便打开一个i.MXRT600 SDK工程,在工程Option里找到Debugger,而后进入Flashloader配置,在界面里你能够看到前面介绍的.board和.flash文件,以及能够直接设置这些xml文件里的部分参数。若是安装的Flash下载算法文件不适用你的板子,那么你须要本身提供合适的算法文件(.out),并修改.flash文件里相应路径以及参数便可。
IAR下Flash下载算法是开源的,\IAR Systems\Embedded Workbench 8.50.6\arm\doc\FlashLoaderGuide.ENU.pdf 文档有很是详细的介绍,篇幅不长,只有47页,建议所有读一遍。
IAR提供了一个Flash下载算法的基础模板,可从官网下载,也能够在IAR安装目录下找到,这个模板只是通用的算法源文件,没有相应模板工程,而且源文件只是算法框架,没有具体芯片相关的Flash驱动实现。
- 模板官网下载:https://files.iar.com/public/cmsis/IAR_flashloader_framework_200.zip
- IAR下模板路径:\IAR Systems\Embedded Workbench 8.50.6\arm\src\flashloader\framework2
该算法基础模板包含四个文件,咱们须要根据模板源文件建立具体目标芯片的算法工程,而后将flash_loader.h里声明的算法API函数根据芯片去具体实现。
\IAR\arm\src\flashloader\framework2\flash_loader.c \IAR\arm\src\flashloader\framework2\flash_loader.h \IAR\arm\src\flashloader\framework2\flash_loader_asm.s \IAR\arm\src\flashloader\framework2\flash_loader_extra.h
算法总共定义了以下5个API函数,其中关于初始化以及擦写的API函数(FlashInit、FlashWrite、FlashErase)是必需要实现的,另外两个是可选的。
其实在IAR安装目录下也提供了生成最终算法文件的IAR工程,咱们能够直接在这个工程基础上修改生成新算法文件。i.MXRT系列有四个算法源工程。
算法自己结构相比MDK下算法设计相对来讲稍微复杂一点,仅以FlashInit相关的代码来介绍。flash_loader_asm.s文件中定义了FlashInitEntry()入口,这个入口是直接由调试器来调用的。
;--------------------------------- ; FlashInitEntry() ;--------------------------------- SECTION .text:CODE:ROOT(2) THUMB FlashInitEntry: BL Fl2FlashInitEntry BL FlashBreak
FlashInitEntry()函数功能很是简单,主要就是跳转到Fl2FlashInitEntry()函数中,这个Fl2FlashInitEntry()函数原型在flash_loader.c文件中。Fl2FlashInitEntry()仍是只是个架子,其主要是将theFlashParams全局变量的一些Flash属性相关内容传入最关键的也是由用户来实现的FlashInit()函数。theFlashParams内容由调试器根据xml文件中设置来初始化。
FlashInit()函数有两个版本,__argc和__argv参数可带也可不带,实际上这个可选参数就是为i.MXRT系列单独加的,主要用于传递外接Flash的信息(好比2.3节图片里的 --MxicOct )。其他两个重要函数FlashWrite、FlashErase与FlashInit代码结构相似,不予赘述。
// parameter passing structure typedef struct { uint32_t base_ptr; uint32_t count; uint32_t offset_into_block; void *buffer; uint32_t block_size; } FlashParamsHolder; __root __no_init FlashParamsHolder theFlashParams; __no_init int __argc; __no_init char __argvbuf[MAX_ARG_SIZE]; #pragma required=__argvbuf __no_init const char* __argv[MAX_ARGS]; void Fl2FlashInitEntry() { #if USE_ARGC_ARGV theFlashParams.count = FlashInit((CODE_REF)theFlashParams.base_ptr, theFlashParams.block_size, // Image size theFlashParams.offset_into_block,// link adr theFlashParams.count, // flags __argc, __argv); #else theFlashParams.count = FlashInit((CODE_REF)theFlashParams.base_ptr, theFlashParams.block_size, // Image size theFlashParams.offset_into_block,// link adr theFlashParams.count); // flags #endif }
让咱们再打开FlashIMXRT1060_FlexSPI示例算法工程,能够看到这个工程既包含了算法基础模板源文件,也包含了用户实现的i.MXRT1060的FlexSPI驱动。关于这个工程,有一个跟MDK下算法工程比较大的区别就是,IAR算法工程并无启用位置无关的编译,它更接近标准的嵌入式应用程序工程。
\IAR Systems\Embedded Workbench 8.50.6\arm\doc\FlashLoaderGuide.ENU.pdf 文档的 The IAR Flash Loader process 小节里对于下载算法调用过程有详细解释。痞子衡将其简要整理在了下面这张图里:
至此,IAR开发环境下i.MXRT的串行NOR Flash下载算法设计痞子衡便介绍完毕了,掌声在哪里~~~
文章会同时发布到个人 博客园主页、CSDN主页、知乎主页、微信公众号 平台上。
微信搜索"痞子衡嵌入式"或者扫描下面二维码,就能够在手机上第一时间看了哦。