i.MXRT11xx上的串行NOR Flash双程序可交替启动是指i.MXRT11xx芯片集成了两个独立的程序存储区域,存储在串行NOR Flash中。在启动时,可通过选择其中一个程序启动,保证系统可靠性。

一、什么是i.MXRT11xx上的串行NOR Flash双程序可交替启动
i.MXRT11xx上的串行NOR Flash双程序可交替启动指的是,在i.MXRT11xx芯片中集成了两个独立的程序存储区域,分别存储两份相同的程序代码。在系统启动时,可以通过设置引脚信号或者软件控制来选择其中一个程序进行启动,从而实现程序的高可靠性启动。当其中一个程序出现问题时,可以通过切换到另一个程序进行启动,以保证设备的正常运行。而这些程序代码存储在串行NOR Flash中,该存储器类型具有读取速度快、可靠性高、使用寿命长等优点,非常适合于嵌入式系统的应用场景。
与 i.MXRT10xx 一样,在一片挂载在 FlexSPI 上的串行 NOR Flash 里做冗余/双程序设计就是下图中的 image L 和 image H,不涉及 LPSPI 接口 Flash B 里的 image 2。

跟 i.MXRT10xx 上一样的冗余程序启动流程,i.MXRT1170 上电先启动物理地址靠前的 image L,如果 image L 被破坏了,则继续启动 image H。什么是双程序可交替启动呢?简单说就是物理地址靠前的 image L 并不总是上电首先启动的 image,在 i.MXRT1170 上新增了如下原型的 image version 启动头(在固定偏移 0x600 处),芯片上电 BootROM 会尝试判断两个 image L/H 里的 version 头版本,高版本的 image 优先被启动。这种设计方便了 OTA 升级。
Note: 当 image L/H 中均不含有效 version 启动头时(img_ver 等于 0xFFFFFFFF,或者高低16bit不符合取反关系),双程序可交替启动特性就不生效,此时等效于冗余程序启动,image L 永远被优先启动。
typedef struct
{
uint16_t version; // 版本值
uint16_t inversion; // version值的取反(~version)
} img_ver_t;

二、i.MXRT11xx上的串行NOR Flash双程序可交替启动与 i.MXRT11xx 系列双程序启动的差异
1、复启动的接口外设不同
名列前茅点不同其实与本文要讨论的 FlexSPI 双程序启动特性无关,因为还是在一片挂载在 FlexSPI 上的串行 NOR Flash 里做双程序设计,就是下图中的 image 0 和 image 1,不涉及 Flexcomm SPI 接口 Flash B 里的 image 2(在 i.MXRT1170 上这个外设是 LPSPI)。
在介绍 i.MXRT1170 双程序启动一文里我们用了 image L/H 来表示 image 0/1,这里还是恢复使用 image 0/1 来表示,因为后面我们要看的 i.MXRT500/600 参考手册启动流程图里就是用 image 0/1 来表达的,避免表达混乱。

2、可启动 image 结构不同
i.MXRT1170 上最简易可启动 image 结构比较复杂(包含 FDCB、img_ver、IVT、BD、App),而 i.MXRTxxx 上就比较简单了(仅需 FDCB、img_ver、App),但是好在两者关于 image version 头结构定义以及偏移位置是完全一致的(0x600)。
typedef struct
{
uint16_t version; // 版本值
uint16_t inversion; // version值的取反(~version)
} img_ver_t;
此外 i.MXRT1170 上名列前茅个 FlexSPI 的 AHB 映射地址是 0x3000_0000,而 i.MXRTxxx 上名列前茅个 FlexSPI 的 AHB 映射地址是 0x0800_0000,这是系统设计差异,需要注意。
Note:下图中示意地址均是 Flash 偏移地址,没有包含 AHB 映射地址,另外这里假设第二份 image 偏移地址在 0x400000(具体是由 otp 配置值来决定的)。

3、使能双程序启动的otp配置地址不同
i.MXRTxxx 上关于使能双程序启动的 otp 配置定义与 i.MXRT1170 上是一致的,只是因为两者 otp 空间设计不同,所以具体配置地址不同。i.MXRTxxx 上具体配置在 otp BOOT_CFG2/3 上面:
//Remap功能的ADDR_START寄存器固定设为 Flash 起始映射地址。
otp 0x188[31:28] - FlexSPI remap size //App的最大长度,标识了名列前茅份App的结束地址,该值加上ADDR_START后被填入Remap功能的ADDR_END寄存器。
otp 0x18C[31:22] - Second image offset //标识了第二份App的起始地址(在Flash中偏移位置),即填入Remap功能的ADDR_OFFSET寄存器的值。
这次我们要在 MIMXRT595-EVK 板卡上实测,这个板子 FlexSPI0 上挂了两片 Flash,默认连接的 64MB OctalFlash,还有一片 8MB QuadSPI Flash(需要做板子改动才能使能)。为了跟之前测试保持一致,还是借助 MCUBootUtility 工具将 Second image offset 烧录为 0x10,FlexSPI remap size 保持默认 0,即第二份 image 偏移地址在 Flash 0x400000(4MB)处,最大 image 长度也是 4MB。

4、暂存状态的非易失寄存器有差异
i.MXRT1170 是用非易失寄存器 SRC_GPR10 其中 2bit 来记录当前启动状态的,而 i.MXRTxxx 上则复杂得多,它采用了 SYSCTL0 外设里的一个非易失寄存器的全部 32bit 来暂存启动状态。
// Load redundant boot options stored in specific register
#define LOAD_REDUNDANT_BOOT_OPTIONS() (*(volatile uint32_t *)(SYSCTL0_BASE + 0x384))
// Store redundant boot options in specific register before system reset
#define SET_REDUNDANT_BOOT_OPTIONS(val) ((*(volatile uint32_t *)(SYSCTL0_BASE + 0x384)) = val)
这个 32bit 寄存器功能原型如下,它不单纯是用做双程序启动的状态记录了,还糅合了 ROM API 功能。具体用法可以在芯片参考手册 ROM API 小节找到。
typedef struct _user_app_boot_invoke_option
{
union
{
struct
{
uint32_t reserved : 8;
uint32_t boot_image_index : 4;
uint32_t instance : 4;
uint32_t boot_interface : 4;
uint32_t mode : 4;
uint32_t tag : 8;
} B;
uint32_t U;
} option;
} user_app_boot_invoke_option_t;
5、image 版本判断逻辑不同
在 i.MXRT1170 上 image version 头有效的条件一定是其高低16bit符合取反关系,而 i.MXRTxxx 上除了这个条件外,其认定 0xFFFFFFFF 也是一个有效版本(被定为最低版本)。芯片参考手册里有比较详细的 version 判断逻辑如下,这个逻辑跟 i.MXRT1170 上差异还是比较大的,i.MXRTxxx 上 BootROM 只会启动包含有效版本号的 image,版本有效性是 image 能被启动的一个必要条件,不像 i.MXRT1170 上版本信息只是单纯用来判断启动顺序,不作为 image 是否有效的标准。
延伸阅读1:i.MXRT11xx是什么
i.MXRT11xx是恩智浦半导体(现在的NXP Semiconductors)推出的一款高性能、超低功耗的Cortex-M微控制器,采用Arm Cortex-M33内核,主频高达500 MHz,支持DSP和浮点计算,并提供了丰富的外设和接口,可广泛应用于工业自动化、医疗设备、智能家居、汽车等领域。该系列微控制器还具备低功耗、安全可靠、易用性等特点,并支持多种存储介质和通信协议,适应不同的应用场景需求。
