痞子衡嵌入式:借助i.MXRT10xx系列INIT_VTOR功能可以缩短程序热重启时间
大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家分享的是借助i.MXRT10xx系列INIT_VTOR功能可以缩短程序热重启时间。
最近痞子衡写了篇文章 《i.MXRT从Serial NAND启动时间测量》,这篇文章详细测试了不同长度的 Non-XIP 程序在不同 NAND 访问速度下由 BootROM 加载启动所需要的时间,比如 240KB 的程序在 60MHz NAND 的访问速度下启动时间接近 30ms,这个启动时间对于有些响应时间敏感的应用(比如汽车电子)来说还是比较长的。
对于 Non-XIP 程序,经过冷启动后,其程序体本身已经被加载进芯片内部 SRAM 了,除非发生 POR,否则 SRAM 中的程序会一直保持着。假设程序在恶劣的电磁环境中运行,代码里虽然包含异常复位的处理,但是每次程序复位启动时间还是和冷启动时间一样长(每次都需要 BootROM 搬移加载),有点难以接受。那么对于这种热启动的情况,程序启动时间能够缩短吗?答案是可以的,今天痞子衡就介绍下 i.MXRT 上的 INIT_VTOR 特性:
- 备注1:本文主角是i.MXRT1050,但内容也基本适用其它i.MXRT10xx系列。
- 备注2:同样的测试在i.MXRT1160/1170下无效,因为CM7_INIT_VTOR所在的IOMUXC_LPSR_GPR->GPR26在软复位下不能保持。
一、INIT_VTOR功能简介
在介绍 INIT_VTOR 功能之前,大家首先要对 ARM Cortex-M 内核的中断向量表偏移寄存器 SCB->VTOR 功能有所了解,具体可以看痞子衡的旧文 《Cortex-M中断向量表原理及其重定向方法》。
简单来说,芯片上电启动后内核都是从 SCB->VTOR 指向的地址处获取程序中断向量表里的第二个向量即所谓的复位函数 Reset_Handler。有了复位函数,就找到了程序入口。
; 摘取自 startup_MIMXRT1052.s
__vector_table
DCD sfe(CSTACK)
DCD Reset_Handler
DCD NMI_Handler
DCD HardFault_Handler
DCD MemManage_Handler
DCD BusFault_Handler
DCD UsageFault_Handler
...
对于 i.MXRT1050,我们知道芯片上电复位都是执行 BootROM 代码,BootROM 中断向量表固定放在了 0x0020_0000 地址处。那么这个 0x0020_0000 地址是怎么被赋给 SCB->VTOR 寄存器的呢?这就引出了本文主角 IOMUXC_GPR->GPR16[32:7] - CM7_INIT_VTOR 位,这 25bits 的 CM7_INIT_VTOR 值每次复位都会被芯片系统自动加载进 SCB->VTOR[32:7] 中,其默认值即对应 BootROM 中断向量表地址。
正如痞子衡旧文 《妙用i.MXRT1xxx里SystemReset不复位的GPR寄存器》 提及的那样,IOMUXC_GPR 寄存器仅在 POR 复位或者整体重新上电时才会被置位,这就意味着我们在应用程序中只需要设置一次 CM7_INIT_VTOR 值,其后不管发生多少次类似 NVIC_SystemReset() 的复位,CM7_INIT_VTOR 值都不会改变。
二、使用INIT_VTOR加速程序热重启
有了上一节的理论基础,我们来做个实验。痞子衡找了一块 MIMXRT1050-EVK12(Rev.A)板卡,将其启动设备换成串行 NAND 启动(电阻切换到使能 U33,并将 U33 替换成华邦 W25N01GV)。
然后按照串行 NAND 启动时间测试方法那样修改 \SDK_2_13_0_EVKB-IMXRT1050\boards\evkbimxrt1050\demo_apps\led_blinky\iar 例程(debug build,即代码在 ITCM 运行,注意修改链接文件中的 m_interrupts_start = 0x00002000),并在 SystemInit() 函数里调用如下测试函数,根据是否设置 IOMUXC_GPR->GPR16 寄存器编译出两个不同镜像文件(直接编辑 bin 文件将其均填充至 120KB)。
void set_led_gpio(void)
{
CLOCK_EnableClock(kCLOCK_Iomuxc);
gpio_pin_config_t USER_LED_config = {
.direction = kGPIO_DigitalOutput,
.outputLogic = 0U,
.interruptMode = kGPIO_NoIntmode
};
GPIO_PinInit(GPIO1, 9U, &USER_LED_config);
IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_09_GPIO1_IO09, 0U);
IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_09_GPIO1_IO09, 0x10B0U);
SystemCoreClockUpdate();
GPIO_PinWrite(GPIO1, 9U, 0U);
SDK_DelayAtLeastUs(5000, SystemCoreClock);
// 根据是否设置 CM7_INIT_VTOR 分别编译两个不同镜像文件
// 设置 CM7_INIT_VTOR 指向地址 0x00002000,即用户应用程序中断向量表
IOMUXC_GPR->GPR16 = (IOMUXC_GPR->GPR16 & (~IOMUXC_GPR_GPR16_CM7_INIT_VTOR_MASK)) | IOMUXC_GPR_GPR16_CM7_INIT_VTOR(0x2000 >> 7);
NVIC_SystemReset();
while (1);
}
然后借助 MCUBootUtility 工具将这两个不同镜像文件下载进串行 NAND flash,并测试相应启动时间。这里 Flash 运行速度就选择 60MHz:
下面是不设置 IOMUXC_GPR->GPR16 的程序启动时间测试结果,无论是一开始的 POR 冷启动还是后面 NVIC_SystemReset() 引起的热启动,启动时间都需要约 18.66ms:

下面是设置了 IOMUXC_GPR->GPR16 指向 0x2000 之后的程序启动时间测试结果,只有一开始的 POR 冷启动时间是 18.66ms,后面 NVIC_SystemReset() 引起的热启动时间仅需要约 5.26ms。

上述实验结果证明,设置 IOMUXC_GPR->GPR16 指向应用程序中断向量表之后确实能缩短程序热启动时间。有朋友可能会疑问,设置了从 ITCM 直接热启动后为何还是有 5.26ms 的启动时间?这其实主要是从进入应用程序 Reset_Handler 到执行到测试 GPIO 拉低时的代码所消耗的时间,并且需要注意的是由 BootROM 加载执行的程序默认是在 ROM 配置后的 396MHz 主频下执行的(主频够快,测试代码消耗时间可以忽略不计),而直接复位从 ITCM 里执行的程序是在默认主频 12MHz 下执行的(主频较慢,测试代码消耗时间不得不计)。
最后再提一下,除了直接在应用程序里设置 IOMUXC_GPR->GPR16 之外,也可以借助 BootROM 的 DCD 功能来设置,同样可以借助 MCUBootUtility 直接完成(详细步骤可参考 《利用i.MXRT1xxx系列ROM集成的DCD功能可轻松配置指定外设》),痞子衡实测是有效的。
翻看 RT1050 参考手册 System Boot 章节,IOMUXC_GPR 寄存器地址空间也确实在有效的 DCD 设置范围。
至此,借助i.MXRT10xx系列INIT_VTOR功能可以缩短程序热重启时间痞子衡便介绍完毕了,掌声在哪里~~~
欢迎订阅
文章会同时发布到我的 博客园主页、CSDN主页、知乎主页、微信公众号 平台上。
微信搜索"痞子衡嵌入式"或者扫描下面二维码,就可以在手机上第一时间看了哦。

痞子衡嵌入式:借助i.MXRT10xx系列INIT_VTOR功能可以缩短程序热重启时间的更多相关文章
- 痞子衡嵌入式:恩智浦LPC系列MCU开发那些事 - 索引
大家好,我是痞子衡,是正经搞技术的痞子.本系列痞子衡给大家介绍的是恩智浦LPC系列微控制器相关知识. 恩智浦半导体最早于2003年便开始推出LPC系列MCU,但早期的产品LPC2000/3000系列属 ...
- 痞子衡嵌入式:浅谈i.MXRT10xx系列MCU外接24MHz晶振的作用
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是i.MXRT10xx系列MCU外接24MHz晶振的作用. 痞子衡之前写过一篇关于时钟引脚的文章 <i.MXRT1xxx系列MCU时 ...
- 痞子衡嵌入式:借助Serial Plot软件测量i.MXRT系列FlexSPI驱动Flash页编程执行时间
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是i.MXRT系列FlexSPI驱动Flash页编程执行时间. 痞子衡之前写过一篇文章 <串行NOR Flash的页编程模式对于量产 ...
- 痞子衡嵌入式:恩智浦i.MX RT1xxx系列MCU启动那些事(13.A)- LPSPI NOR启动时间(RT1170)
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是恩智浦i.MX RT1170 1bit SPI NOR恢复启动时间. 本篇是i.MXRT1170启动时间评测第三弹了,前两篇分别给大家评 ...
- 痞子衡嵌入式:飞思卡尔i.MX RT系列MCU启动那些事(4)- Flashloader初体验(blhost)
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是飞思卡尔i.MX RT系列MCU的Flashloader. 在上一篇文章 Serial Downloader模式(sdphost, mf ...
- 痞子衡嵌入式:飞思卡尔i.MX RT系列MCU启动那些事(8)- 从Raw NAND启动
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是飞思卡尔i.MX RT系列MCU的Raw NAND启动. 前面铺垫了七篇启动系列文章,终于该讲具体Boot Device了,我们知道i. ...
- 痞子衡嵌入式:飞思卡尔i.MX RT系列MCU启动那些事(9)- 从Parallel NOR启动
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是飞思卡尔i.MX RT系列MCU的Parallel NOR启动. 上一篇讲i.MXRT从Raw NAND启动的文章 从Raw NAND启 ...
- 痞子衡嵌入式:飞思卡尔Kinetis系列MCU启动那些事(2)- KBOOT形态(ROM/Bootloader/Flashloader)
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是飞思卡尔Kinetis系列MCU的KBOOT形态. 痞子衡在前一篇文章里简介了 KBOOT架构,我们知道KBOOT是一个完善的Bootl ...
- 痞子衡嵌入式:恩智浦i.MX RT1xxx系列MCU启动那些事(11.0)- FlexSPI NOR启动时间(RT1170)
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是恩智浦i.MX RT1170 FlexSPI NOR启动时间. 痞子衡刚刚拿到i.MXRT1170 B0版本的芯片,迫不及待地在上面跑了 ...
- 痞子衡嵌入式:深入i.MXRT1050系列ROM中串行NOR Flash启动初始化流程
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是深入i.MXRT1050系列ROM中串行NOR Flash启动初始化流程. 从外部串行NOR Flash启动问题是i.MXRT系列开发最 ...
随机推荐
- Rsync文件同步及备份
Rsync文件同步及备份 目录 Rsync文件同步及备份 Rsync基本概述 远程文件传输 服务端口 Rsync的三种传输模式 本地方式(类似cp) 远程方式(类似scp) 守护进程(C/S结构) R ...
- 文心一言 VS chatgpt (1)-- 算法导论1.1
1.给出现实生活中需要排序的一个例子或者现实生活中需要计算凸壳的一个例子. 文心一言: 现实生活中需要排序的一个例子: 在一个商店里,顾客需要购买一些商品.他们需要按照价格从低到高排序,以便更容易地找 ...
- 2020-09-06:Docker的命名空间有哪些?
福哥答案2020-09-06: 福哥口诀法:命进I网挂U用 1.进程命名空间.CLONE_NEWPID.进程编号. 2.IPC 命名空间.CLONE_NEWPIPC.信号量.消息队列何共享内存. 3. ...
- 2020-10-09:假如我能拿到别人的URL,然后篡改数据(金额)发送给系统,如何避免这种事情的发生?
福哥答案2020-10-09:#福大大架构师每日一题# [此答案来自知乎:](https://www.zhihu.com/question/424764253) 这种敏感url一般都有安全机制的:1. ...
- 2022-09-15:Range模块是跟踪数字范围的模块。 设计一个数据结构来跟踪表示为 半开区间 的范围并查询它们。 半开区间 [left, right) 表示所有 left <= x < righ
2022-09-15:Range模块是跟踪数字范围的模块. 设计一个数据结构来跟踪表示为 半开区间 的范围并查询它们. 半开区间 [left, right) 表示所有 left <= x < ...
- 2021-11-01:寻找重复数。给定一个包含 n + 1 个整数的数组 nums ,其数字都在 1 到 n 之间(包括 1 和 n),可知至少存在一个重复的整数。假设 nums 只有 一个重复的整数
2021-11-01:寻找重复数.给定一个包含 n + 1 个整数的数组 nums ,其数字都在 1 到 n 之间(包括 1 和 n),可知至少存在一个重复的整数.假设 nums 只有 一个重复的整数 ...
- 2023-05-15:对于某些非负整数 k ,如果交换 s1 中两个字母的位置恰好 k 次, 能够使结果字符串等于 s2 ,则认为字符串 s1 和 s2 的 相似度为 k。 给你两个字母异位词 s1
2023-05-15:对于某些非负整数 k ,如果交换 s1 中两个字母的位置恰好 k 次, 能够使结果字符串等于 s2 ,则认为字符串 s1 和 s2 的 相似度为 k. 给你两个字母异位词 s1 ...
- postman接口关联-token值
背景: 在测试工作中,测试鉴权的接口需要用到登录接口的token,需要我们先调用登录接口,获得token,然后把即时获得的token填入请求中发送请求,我们可以用设置全局变量的办法解决这个问题 实 ...
- 【一步步开发AI运动小程序】十、姿态动作相似度比较
随着人工智能技术的不断发展,阿里体育等IT大厂,推出的"乐动力"."天天跳绳"AI运动APP,让云上运动会.线上运动会.健身打卡.AI体育指导等概念空前火热.那 ...
- 快速把PDF文档里的表格粘贴到excel的方法
1 打开需要复制的PDf文件,点一下页面上方的"选择文本"按钮(如下图中手图标左边的箭头),以便选中文本 2 ctrl c 需要复制的表格,到excel中ctrl v.这时候所有类 ...