大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家介绍的是i.MXRT1170上串行NOR Flash双程序可交替启动设计

  在上一篇文章 《i.MXRT1060/1010上串行NOR Flash冗余程序启动设计》 里,痞子衡详细介绍了 i.MXRT10xx 上的冗余程序启动设计,本质上这就是个双备份程序启动, NOR Flash 里存两份一样的 image,物理地址靠前的 image 0 启动失效就继续启动后面的 image 1,多一层保障。

  i.MXRT1170 是区别于 i.MXRT10xx 的第二代架构,性能/功能更加强大,其在继承 i.MXRT10xx 冗余程序启动的基础上,新增了双程序可交替启动设计,今天我们就来聊聊这个话题:

一、初识双程序可交替启动

  与 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.MXRT1060/1010上串行NOR Flash冗余程序启动设计》 第 2 节里一模一样的方法,在恩智浦官方 MIMXRT1170-EVK 开发板上做测试,这个板子 FlexSPI1 上挂了两片 Flash,默认连接的 16MB QuadSPI Flash,还有一片 64MB OctalFlash(需要做板子改动才能使能)。

  在 i.MXRT1170 fuse 里关于冗余程序启动的使能位定义与 i.MXRT10xx 上差不多,只不过 fuse 地址从 0x6E0 换到了 0xC80。还是跟之前测试一样借助 MCUBootUtility 工具将 FLEXSPI_NOR_SEC_IMAGE_OFFSET 烧录为 0x10,xSPI_FLASH_IMAGE_SIZE 保持默认 0,即第二份 image 偏移地址在 Flash 0x400000(4MB)处,最大 image 长度也是 4MB。

  继续用 \SDK_2.11.0_MIMXRT1170-EVK\boards\evkmimxrt1170\demo_apps\led_blinky\cm7\iar\flexspi_nor_debug 例程生成两个稍微不一样的 image,闪灯间隔时间一个是 200ms(image L - iled_blinky_cm7_delay200ms.bin),另一个是 2s(image H - iled_blinky_cm7_delay2s.bin)。在 MCUBootUtility 工具主界面下使用 All-In-One 操作将 image L 下载进 Flash(base address 设为 0x30000400),使用通用编程器界面 Write 操作将 image H 也下载进 Flash(Start 设为 0x400400)。

  现在 Flash 里有了两份 image,当第一份 image 启动失败后,i.MXRT1170 BootROM 不是立刻去执行下一份 image ,还是那个取巧的方法,在一个软复位不置位的寄存器里(SRC_GPR10)标记当前状态,然后调用 NVIC_SystemReset() 重新进入 BootROM 执行。不过此时标记位从 GPR10[30] 换到了 GPR10[27:26],虽然是 2bit 状态,但设值 1/2/3 等效于设值 1,因为对于串行 NOR Flash 最多就是两份 image。这时候如果你想挂 J-Link 改写 SRC_GPR10 去做快速验证恐怕无法如愿,因为 《i.MXRT1170上用J-Link连接复位后PC总是停在0x223104》。

  所以在 i.MXRT1170 上只能老老实实做破坏 image 完整性的动作来验证冗余程序启动,经实测其效果与 i.MXRT10xx 是完全一致的。

三、实测双程序可交替启动

  现在我们开始实测双程序可交替启动,主要的工作量就是为 image L 和 image H 添加 version 启动头,并且将它们分别下载进 Flash。因为我们想验证物理地址靠后的 image H 比 image L 优先启动(冗余程序启动做不到这点),所以需要将 image H 的 version 头版本设高一点。

3.1 为 image 添加 version 启动头

  还是在 \SDK_2.11.0_MIMXRT1170-EVK\boards\evkmimxrt1170\demo_apps\led_blinky\cm7\iar\flexspi_nor_debug 例程基础上,首先在工程链接文件 MIMXRT1176xxxxx_cm7_flexspi_nor.icf 添加如下语句,指定 .img_ver 段的位置。

define symbol m_boot_img_ver_start           = 0x30000600;
place at address mem: m_boot_img_ver_start { section .img_ver };

  然后在工程随便一个源文件里添加如下常量 s_bt_img_l_ver 定义,这个 image 闪灯间隔时间是 200ms(image L - iled_blinky_cm7_delay200ms_ver0.bin),版本是 0x0000(注意编译链接工程时为防止 s_bt_img_l_ver 被优化,可以在工程选项 Linker / Input / Keep symbols 里将其添加进去)。

const img_ver_t s_bt_img_l_ver @ ".img_ver" = {.version = 0x0000,.inversion = ~0x0000,
};

  同样的工程,再生成另一个闪灯间隔时间为 2s(image H - iled_blinky_cm7_delay2s_ver1.bin) 的 image 时使用如下常量 s_bt_img_h_ver 定义,版本是 0x0001。

const img_ver_t s_bt_img_h_ver @ ".img_ver" = {.version = 0x0001,.inversion = ~0x0001,
};

  当然如果你嫌上述方法繁琐,也可以直接在最终 image binary 文件上做修改(注意 offset 位置一定要找对,i.MXRT1170 SDK XIP binary 文件起始数据对应 Flash 偏移是 0x400,因此文件中 0x200 处才对应 Flash 偏移 0x600):

3.2 下载含 version 头的 image 进 Flash

  现在需要借助 MCUBootUtility 工具的通用编程器功能分别将两个含 version 头的 image L/H 下载进 Flash。这里需要注意的是此时 image L 无法再通过主界面 All-In-One 操作来下载了,因为工具 v3.4 版本及以下没有对 version 启动头做识别处理,因此会丢掉 version 头数据(这个考虑会在 v4.0 之后加入支持)。

  两个 image 下载完成,一切工作就结束了,这时候你调整芯片启动模式到 2'b10 - Flash boot,给板卡重新上电,应该可以看到 image H 正在执行。

3.3 BootROM中判断version的逻辑

  BootROM 中关于 version 启动头是否有效以及版本高低判断逻辑其实是有一点复杂的,这里把具体代码分享给大家,方便大家为 image 设置有效的 version 头以及正确使能这个双程序可交替启动特性。

  判断逻辑代码主要意思是仅当 image L 的版本不是 0xFFFFFFFF 且 image H 的版本是有效的(img_ver 高低16bit符合取反关系)情况下,如果 image L 版本无效或者 image L 版本有效但比 image H 版本低,则物理地址靠后的 image H 优先启动。除此以外其余情况,一律是物理地址靠前的 image L 优先启动。

uint32_t image_l_base = 0x30000000
uint32_t image_h_base = 0x30400000uint32_t get_image_index(void)
{uint32_t redundant_boot = ((SRC->GPR[9] & 0x0C000000) >> 26);static uint32_t image_index[] = { 0, 0 };img_ver_t image_l_version = *(img_ver_t *)(image_l_base + 0x600);img_ver_t image_h_version = *(img_ver_t *)(image_h_base + 0x600);if ((image_l_version.version != 0xFFFFu || image_l_version.inversion != 0xFFFFu) &&((0xFFFFu & image_h_version.version) == (0xFFFFu ^ image_h_version.inversion)) &&((0xFFFFu & image_l_version.version) != (0xFFFFu ^ image_l_version.inversion) || (image_l_version.version < image_h_version.version))){image_index[0] = 1;}else{image_index[1] = 1;}return image_index[redundant_boot];
}

  痞子衡在 MIMXRT1170-EVK 开发板上对image 版本设置情况也做了比较全面的实测,测试结果如下:

image L版本值 image H版本值 启动结果
0xFFFFFFFF 任意值
(实测了0xFFFFFFFF, 0xFFFFAA55, 0xFFFF0000)
先启动image L
失败再启动image H
任意值
(实测了0xFFFFAA55, 0xFFFF0000)
0xFFFFAA55
(或其他无效版本值包括全0xFFs)
先启动image L
失败再启动image H
0xFFFFAA55
(或其他非全0xFFs无效版本值)
0xFFFF0000
(或其他任意有效版本值)
先启动image H
失败再启动image L
0xFFFF0000 0xFFFE0001
(或其他高于0x0的有效版本值)
先启动image H
失败再启动image L
0xFFFE0001 0xFFFE0001或0xFFFF0000 先启动image L
失败再启动image H

四、一些关于 image 的注意事项

  • Note1: 虽然文中所有的测试均是针对 XIP image,但这个冗余程序/双程序可交替启动特性对于 Non-XIP image 也同样适用。
  • Note2: 如果是 XIP image,其链接地址不一定要固定在偏移 0x2000 处,因为 IVT 的存在,其是可以链接在偏移 0x2000 之后的任意位置的。
  • Note3: 如果是 Non-XIP image,在 SDK 包里无法直接生成含启动头的 Non-XIP image binary,这时候可以先使用 MCUBootUtility 主界面的 All-In-One 操作下载一次 image,再通过通用编程器界面 Read 操作读回来便是含启动头的 Non-XIP image binary。

  至此,i.MXRT1170上串行NOR Flash双程序可交替启动设计痞子衡便介绍完毕了,掌声在哪里~~~

欢迎订阅

文章会同时发布到我的 博客园主页、CSDN主页、知乎主页、微信公众号 平台上。

微信搜索"痞子衡嵌入式"或者扫描下面二维码,就可以在手机上第一时间看了哦。

痞子衡嵌入式:聊聊i.MXRT1170上串行NOR Flash双程序可交替启动设计相关推荐

  1. 痞子衡嵌入式:揭秘i.MXRTxxx系列上串行NOR Flash双程序可交替启动设计

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是i.MXRT500/600上串行NOR Flash双程序可交替启动设计. 在上一篇文章 <i.MXRT1170上串行NOR Fla ...

  2. 痞子衡嵌入式:揭秘i.MXRT1060,1010上串行NOR Flash冗余程序启动设计

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是i.MXRT1060,1010上串行NOR Flash冗余程序启动设计. 工业产品设计里经常会有冗余程序/备份程序设计的需求,因为在工业 ...

  3. 痞子衡嵌入式:IVT里的不同entry设置可能会造成i.MXRT1xxx系列启动App后发生异常跑飞...

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是IVT里的不同entry设置可能会造成i.MXRT1xxx系列启动App后发生异常跑飞问题的分析解决经验. 事情缘起恩智浦官方论坛上的一 ...

  4. 痞子衡嵌入式:串行NOR Flash的页编程模式对于量产效率的影响

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是串行NOR Flash的页编程模式对于量产效率的影响. 任何嵌入式产品最终都绕不开量产效率话题,尤其是对于主控是非内置 Flash 型 ...

  5. 痞子衡嵌入式:超级下载算法(RT-UFL)开发笔记(1) - 执行在不同CM内核下

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是超级下载算法开发笔记(1)之执行在不同CM内核下. 文接上篇 <RT-UFL - 一个适用全平台i.MXRT的超级下载算法设计&g ...

  6. 痞子衡嵌入式:导致串行NOR Flash在i.MXRT下无法正常下载/启动的常见因素之QE bit...

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是导致串行NOR Flash在i.MXRT下无法正常下载/启动的常见因素之QE bit. i.MXRT系列MCU发布已两年多了,基于i.M ...

  7. 痞子衡嵌入式:简析i.MXRT1170 XECC功能特点及其保护串行NOR Flash和SDRAM之道

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是i.MXRT1170 XECC功能特点及其保护串行NOR Flash和SDRAM之道. ECC 是 "Error Correc ...

  8. 痞子衡嵌入式:深扒i.MXRTxxx系列ROM中集成的串行NOR Flash启动SW Reset功能及其应用场合...

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是i.MXRTxxx系列ROM中集成的串行NOR Flash启动SW Reset功能及其应用场合. 在串行 NOR Flash 热启动过程 ...

  9. 痞子衡嵌入式:在串口波特率识别实例里逐步展示i.MXRT上提升代码执行性能的十八般武艺...

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是在串口波特率识别实例里逐步展示i.MXRT上提升代码执行性能的十八般武艺. 恩智浦 MCU SE 团队近期一直在加班加点赶 SBL 项目 ...

最新文章

  1. 矩阵的终极分解-奇异值分解 SVD
  2. xmodmap: unable to open display '' Error: Couldn't connect to XServer passing null display
  3. C++设计模式-Bridge桥接模式
  4. 测试:fiddler使用
  5. MySQL慢查询之慢SQL定位、日志分析与优化方案
  6. Rabbitmq消息中间件整合Springboot
  7. sprintboot入门
  8. java水仙花数代码_java知识分享篇(五)
  9. Ant—使用Ant构建简单Java项目(三)
  10. Mysql源码编译安装主从复制
  11. 联想IBM服务器装系统教程,联想thinkpad系统安装攻略 每一个步骤都有
  12. 卸载Symantec——无需密码,卸载干净,Windows
  13. C#中new一个对象的过程说明
  14. excel分类_Excel 的10个神奇功能,你会用几个?
  15. 测试架构师需要具备哪些能力?
  16. qute图(女生勿进
  17. 青云MR集群初步使用指南
  18. 【工业大数据】工业大数据:构建制造型企业新型能力
  19. [转]把自己从一个疯狂下载者变成一个学习者
  20. MIME::Base64, encode_base64(), decode_base64()

热门文章

  1. ETC营销数据统计及展示
  2. python的歌曲评论数据分析_用Python爬取陈奕迅歌曲10万条评论的新发现
  3. 微信公众平台python_python搭建微信公众平台
  4. C# 正尝试在 OS 加载程序锁内执行托管代码。不要尝试在 DllMain 或映像初始化函数内运行托管代码,这样做会导致应用程序挂起。
  5. Python中Scapy网络嗅探模块的使用
  6. windows7 为系统盘瘦身
  7. 关于使用网页做托福TPO在chrome上没有声音,找不到autoplay-policy
  8. 东软慧聚助力汽车“芯”节能减排
  9. csgo 放置机器人_csgo怎么在确定位置放置一个bot?
  10. iPad2通过DFU模式刷机