大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家介绍的是 MCUXpresso IDE 开发环境下 i.MXRT 的串行 NOR Flash 下载算法设计。

 

在 i.MXRT 硬件那些事系列之《在串行 NOR Flash XIP 调试原理》一文中,痞子衡简单提了一下串行 NOR Flash 下载算法的概念,并没有介绍具体设计细节,关于 NOR Flash 下载算法每个 IDE 都有自己的一套设计,虽然基本设计理念是一样的,但是细节方面还是有区别。在前面的文章里,痞子衡分别介绍过《J-Link 下算法设计》、《Keil MDK 下算法设计》、《IAR EWARM 下算法设计》,今天痞子衡就来细聊 MCUXpresso IDE 下的 NOR Flash 下载算法:

 

一、MCUXpresso IDE 各版本对 i.MXRT 的支持

MCUXpresso IDE 是飞思卡尔和恩智浦合并之后推出的全新 IDE,这个 IDE 是免费的,可用于新恩智浦全系列 ARM Cortex-M 控制器(Kinetis、LPC、JN、QN、i.MXRT 等)。熟悉这两家公司的人应该知道,其实 MCUXpresso IDE 就是原恩智浦 LPCXpresso IDE 与原飞思卡尔 Kinetis Design Studio IDE 的合体。

 

从恩智浦官网上看,目前最新的 MCUXpresso IDE 版本是 v11.2.1,其能够支持目前所有已量产的 i.MXRT 系列。从 MCUXpresso IDE 历史各版本 Release Note 上看,我们可以看到其各版本对 i.MXRT 支持情况如下:

 

 

各版本下载地址:https://nxp.flexnetoperations.com/control/frse/product?child_plneID=756637&ver=ARC

 

MCUXpresso IDE 对新 MCU 型号的支持虽然并不是与自身版本严格绑定,但通过类似打 patch 的方式比较复杂,且官方不支持这么做,反正这个 IDE 是免费的,升级又不要钱,也不需要申请 license,最好还是通过安装最新版本的方式来实现新型号的支持。

 

二、为当前 MCUXpresso IDE 增加新下载算法支持

痞子衡安装的是最新的 v11.2.1,我们以为 RT600 这颗芯片新增 flash 下载算法为例介绍 MCUXpresso IDE 下的使用。在开始之前要特别强调一下 MCUXpresso IDE 与 MDK/IAR 非常不同的地方,MDK/IAR 自带的 flash 下载算法是跟具体硬件仿真器无关的,它可以在所有支持的仿真器(JLink/DAPLink 等)下正常使用,但是 MCUXpresso IDE 自带的 flash 下载算法只能在 CMSIS-DAP 类型的仿真器下使用。如果你在 MCUXPresso IDE 下使用 JLink,那么下载算法只能用 JLink 的算法。

 

现在我们随便打开一个 i.MXRT600 SDK 工程,右击工程进入 Properties 设置界面,在 MCU Settings 下可以看到 LinkServer Flash Driver 的设置界面,这里就是选择 flash 下载算法。MCUXpresso IDE 默认自带了非常多的 flash 下载算法(文件后缀名是 .cfx,其实就是可执行文件 elf),即使是同一颗芯片 RT600,可以看到其有很多个 .cfg 可选,这分别对应了不同的 flash 种类以及与主芯片连接端口。

 

 

如果默认选择的 Flash 下载算法文件不适用你的板子,那么你需要自己提供合适的算法文件(.cfx),并将其放入 MCUXpresso IDE 安装目录下(\MCUXpressoIDE_11.2.1_4149\ide\binaries\Flash),重新打开工程选项,新增的算法会自动刷新到待选算法列表:

 

 

三、NOR Flash 下载算法设计

MCUXpresso IDE 下 Flash 下载算法是公开的,\MCUXpressoIDE_11.2.1_4149\MCUXpresso_IDE_User_Guide.pdf 文档的 LinkServer Flash Support 章节有一些使用方面的介绍,可以看一下。

 

3.1 下载算法模板工程

虽然下载算法本身是公开的,但设计文档很少,只给了示例工程。但对于工程师来说,还有什么比给代码来得更直接呢。

 

  • 示例算法工程路径:\MCUXpressoIDE_11.2.1_4149\ide\Examples\Flashdrivers\NXP\iMXRT

 

 

我们就以 iMXRT1050_QSPI.zip 示例包里代码来分析其结构设计。这个示例包包含两个工程(LPCXFlashDriverLib 和 iMXRT1050_QSPI),需要先编译 LPCXFlashDriverLib 工程生成 libLPCXFlashDriverLib.a,这个库是 iMXRT1050_QSPI 工程的源文件,然后编译 iMXRT1050_QSPI 工程生成我们需要的算法文件 MIMXRT1050-EVK_IS25WP064A.cfx。

 

MCUXpresso IDE 下载算法这种两级编译的设计,与 IAR/MDK 下载算法结构完全不同,这么设计的主要原因是恩智浦 ARM Cortex-M 内核 MCU 产品线众多,而 MCUXpresso IDE 需要支持所有 MCU,因此将公共设计的部分提取到了 LPCXFlashDriverLib 工程里(为了通用性,工程采用 CM0 指令集来编译)。此外,从工程名你就能看出,还保留着上一代 LPCXpresso IDE 的基因。

 

LPCXFlashDriverLib 工程有很多 build,可以根据 ServiceMessages.c 文件里的条件编译宏了解到它们的差异,其中 Release_SectorHashing 工程是默认选择用于最终生成 .cfx 的,这个 build 主要是利用 32 bit Fowler/Noll/Vo FNV-1a 哈希算法对每个 Sector 的数据下载做了校验。

 

 

再到 iMXRT1050_QSPI 工程,这个工程就是采用具体 MCU 的内核指令集(CM7)来编译,在工程设置里可以看到链接了 LPCXFlashDriverLib 工程的 Release_SectorHashing 生成的 .a 文件,如果 LPCXFlashDriverLib 工程选择了其他 build,这里也要相应改一下。

 

 

3.2 下载算法结构设计

算法本身设计算是几个常用 IDE 里最复杂的一个了。iMXRT1050_QSPI 工程除了一般的 FlexSPI 驱动外,有两个源文件 FlashDev.c 和 FlashPrg.c,对这文件名有没有很熟悉?是的,这就是标准的 CMSIS 开源 flash 算法 API 定义,里面的内容也是类似的,这里就不赘述了,需要特别强调的是这些 Flash 擦写 API 并不是 MCUXpresso IDE 在下载时实际调用入口。

 

 

算法最核心的设计在 LPCXFlashDriverLib 工程,先看 lpcx_flash_memdev.c 里内容,这个文件里定义了一个重要的常量结构体 MemoryDevice,这个 MemoryDevice 会被链接在算法执行区域(前 64KB 的 DTCM)的起始位置(0x20000000),给 MCUXpresso IDE 调试器提供算法全部的信息。

 

// MemoryDevice Instance (fill it in)
EXTERN_MEMORY_DEVICE
MemoryDeviceMsg_t MemoryDevice =
{
  MEM_FLASH_VER2_MAJ+0x0,       // Version of flash interface
                                // Magic number to identify flash driver
                                // interface
  { 0x01, 0x23, 0x45, 0x00, 0x00, 0x54, 0x32, 0x10 },
  (uint32_t)&__load_base,         // Driver load address
  (uint32_t)&__image_size,        // Size of .text and .data
  (uint32_t)&__cache,             // RAM buffer location
  (uint32_t)&__cache_size,        // RAM buffer size
  (uint32_t)&__initial_sp,        // Stack top
  (uint32_t)&__stack_size,        // Stack size
  (uint32_t)&__opmap_val,         // Bitmap of available operations - 0 = everything there
  &FlashDevice,                   // Flash Device configuration
  ServiceMessages,                // Service mailbox flash operation message
  0                               // Reserved
};

 

MemoryDevice 有一个成员是 ServiceMessages()函数,这个函数可以说是算法最灵魂的部分了,它才是 MCUXpresso IDE 调试器调用 Flash 擦写 API 的真正入口,调试器通过传入 msg 参数(所谓 Mailbox 结构)让算法来执行具体 Flash 操作并得到执行结果。这种特殊的设计可能也是 MCXPpresso IDE 算法仅能在 CMSIS-DAP 类型仿真器下使用的原因吧。

 

 

至此,MCUXpresso IDE 开发环境下 i.MXRT 的串行 NOR Flash 下载算法设计痞子衡便介绍完毕了,掌声在哪里~~~