痞子衡嵌入式:恩智浦i.MX RT1xxx系列MCU启动那些事(11.A)- FlexSPI NOR启动时间(RT1170)


  你们好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给你们介绍的是恩智浦i.MX RT1170 FlexSPI NOR启动时间html

  痞子衡刚刚拿到i.MXRT1170 B0版本的芯片,火烧眉毛地在上面跑了一些A0版本上早已验证过的demo,功能一切正常,没有什么额外迁移工做。由于目前只有B0版本芯片,没有配套EVK,因此痞子衡是在RT1170内部Validation板上作测试的(RT主芯片以及Flash芯片所有放在Socket里的,很是方便更换),正好痞子衡最近整理工位,找到了很是多来自不一样厂家的串行Flash样片,何不趁此时顺便测一下Serial NOR启动时间,毕竟Serial NOR是i.MXRT启动首选设备,启动时间确定是你们比较感兴趣的。git

  关于i.MXRT1170启动时间,痞子衡以前在A0版本上测过 《SEMC NAND启动时间》,有了以前的测试基础,本篇文章就是照葫芦画瓢。不过因为Serial NOR的特殊性,本文会同时测XIP和Non-XIP时间,以及两种典型的Flash工做模式下(四线SDR,八线DDR)的时间,工做量要稍微大一些,让咱们开始吧。github

1、准备工做

1.1 知识储备

  Serial NOR能够说是你们最熟悉的启动设备了,虽然这个设备能够支持两类App(XIP和Non-XIP)去启动,但你们用得最多的无疑是XIP App,由于XIP下App代码长度能够和Flash容量同样大,这对于复杂功能的应用很重要,可是编写XIP App代码也有一些须要注意的地方,好比在配置系统时钟(不能影响FlexSPI模块)或者擦写Flash时(不支持RWW的话须要拷贝到RAM里执行)有一些限制。微信

  至于Non-XIP,相比XIP会多一个App拷贝过程,启动时间不免会变长。拷贝目标设备选择种类不少,能够是内部RAM(包含TCM和OCRAM),也能够是外部RAM(SDRAM或者HyperRAM)。若是是为了提升代码执行效率,一般会搬移到内部TCM里执行。固然也有搬移到外部SDRAM执行的,不过这种状况须要额外利用DCD功能来完成SEMC模块的初始化以后才能作搬移工做。函数

1.2 时间界定

  关于时间终点,参考《SEMC NAND启动时间》 里的1.2节,方法保持一致。而关于时间起点,本次的测试选点作了一些优化,测NAND启动时为了图方便选在了最靠近POR引脚的电压转换器NC7SP125P5X的输入脚(Pin1)所在的Header上,可是咱们知道任何一个被动电源器件都有转换时间,为了尽量精确测量启动时间,咱们应该消除这种偏差,所以本次选点放在了NC7SP125P5X的输出脚(Pin4),这个脚与主芯片POR引脚是直连的。工具

  为了让你们对电源器件转换时间有个深入感觉,痞子衡此次还特意量了一下Validation板上原始电源输入(5V Jack)到POR引脚上电的时间,这个时间足有210ms,根据电源电路设计以及器件选型的不一样,这个时间是不一样的,因此应该从启动时间里抛除出来。性能

1.3 制做应用程序

  关于应用程序制做,依旧是参考《SEMC NAND启动时间》 里的1.3节,只有一个微小改进,就是把翻转GPIO的代码放在SystemInit()函数最前面,尽量地靠近Reset_Handler。测试

void SystemInit (void) {
    {
        CLOCK_EnableClock(kCLOCK_Iomuxc);
        gpio_pin_config_t led_config = {kGPIO_DigitalOutput, 0, kGPIO_NoIntmode};
        IOMUXC_SetPinMux(IOMUXC_GPIO_AD_03_GPIO9_IO02, 0U);
        GPIO_PinInit(GPIO9, 2, &led_config);
        GPIO_PinWrite(GPIO9, 2, 1u);
    }

	// 关开门狗和SysTick

    while (1);

    // ...
}

1.4 下载应用程序

  应用程序的下载需借助痞子衡开发的NXP-MCUBootUtility工具(v2.3版本及以上),本次痞子衡一共测试了两款Flash,针对不一样的Flash,在下载时选择的模型不同:fetch

  下面模型适用华邦W25Q256系列,配置成了四线、SDR、133MHz工做模式去启动:优化

  下面模型适用旺宏MX25UM51345系列,配置成了八线、DDR、166MHz工做模式去启动:

1.5 示波器抓取信号

  一切准备就绪,能够用示波器抓Serial NOR启动时间了。通道一监测原始5V电源输入信号,通道二监测芯片POR信号,通道三来监测Flash片选信号(FSPI1A_SS0_B),通道四监测LED GPIO信号。

2、开始测试

2.1 测试结果

  在公布结果以前,痞子衡先带你们分析一下示波器抓取的启动时间波形,方便你们理解后续表格里的各项组成。

  先来看你们相对陌生的Non-XIP启动的波形(MX25UM51345G,247KB App)。通道二链接POR引脚,电平拉高是启动计时的开始,启动后会先经历BootROM时间(CM7内核先执行ROM代码,作一些常规系统初始化,读取用户启动配置,而后配置好FlexSPI模块),底下再经历BootFlash时间(仍是在ROM里执行,不过此时开始访问外部Flash,从Flash里读取FDCB、IVT、BootData以及搬移App,因此你会看到通道三(Flash的片选信号)上会有持续的波形变化,搬移完成以后便跳转到App里执行),最后你会看到通道四电平拉高了(App在执行)。

  做为比较,再来看一下XIP启动的波形(MX25UM51345G,246KB App)。BootROM时间跟Non-XIP基本差很少,这是能够理解的,一样的ROM代码在执行,消耗的机器周期是不变的。BootFlash的时间明显缩短了,Flash片选的波形只有屈指可数的几回,这是由于ROM此时只须要读取FDCB、IVT、BootData,根据IVT里的连接地址信息得知App不须要搬移就直接跳转了。

  分析完了启动时间组成,让咱们看结果吧。痞子衡基于Flash工做模式、App长度、App执行地址的组合一共作了8个测试,结果以下表所示(注:表中结果都是在1.25M次/秒的采样率下所得):

Flash型号
Timing模式
App长度
(bytes)
App执行位置 BootROM时间 BootFlash时间 总启动时间
W25Q256J
4bit, SDR, 133MHz
16390 XIP 6.926 ms 1.611 ms 8.537 ms
17922 ITCM 6.939 ms 2.203 ms 9.142 ms
251910 XIP 6.920 ms 1.612 ms 8.532 ms
253442 ITCM 6.953 ms 8.795 ms 15.748 ms
MX25UM51345G
8bit, DDR, 166MHz
16390 XIP 6.942 ms 1.618 ms 8.560 ms
17922 ITCM 6.944 ms 2.312 ms 9.256 ms
251910 XIP 6.916 ms 1.647 ms 8.563 ms
253442 ITCM 6.935 ms 8.897 ms 15.832 ms

2.2 结果分析

  从上面表格里的结果咱们能够获得以下三个结论:

  • 结论1:不论是哪一种Flash链接,BootROM时间差很少是固定的,大概在6.9ms
  • 结论2:XIP启动的状况下,BootFlash时间几乎也是固定的,跟App长度无关,大概在1.6ms
  • 结论3:Non-XIP启动的状况下,BootFlash时间跟App长度成正比,可是跟Flash工做模式(速度)不是正比(甚至能够说关系不太大)

  关于结论3里的BootFlash时间跟Flash工做模式(速度)不是正比这点有必要展开研究一下。痞子衡的测试结果是ROM从Flash拷贝247KB数据到ITCM,不管是从QSPI Flash拷贝仍是从Octal Flash拷贝所花时间居然几乎是一致的,这个看起来挺奇怪的,毕竟仅从Flash自身读访问速度而言,Octal Flash应该是QSPI Flash的五倍(8bit x 2 x 166MHz) / (4bit x 1 x 133MHz)。

  为了解开谜题,痞子衡对时序图里CS信号作了进一步分析,下图是QSPI Flash的启动时序图,ROM拷贝247KB的数据耗时约7.833ms,每一个CS周期是114.4us,扣除时序前期的空闲时间以及读Boot Header,拷贝App期间共有62个CS周期,那么每一个CS周期实际拷贝了4KB数据,这表明ROM配置了FlexSPI prefetch buffer的长度为4KB(RT1170最大是4KB,RT1060最大是1KB)而且使能了Prefetch功能。从QSPI Flash自己速度理论计算,读4KB数据应该耗时 4KB / (4bit x 133MHz) = 61.59us,这与实际测量的CS信号的低电平时间是吻合的。再来看CS信号周期的高电平(idle)时间足有52.8us,为何会有这么长的空闲时间?疑问先放在这里。

  一样的方法再来分析一下Octal Flash的启动时序图。从Octal Flash自己速度理论计算,读4KB数据应该耗时 4KB / (8bit x 2 x 166MHz) = 12.33us,这与实际测量的CS信号的低电平时间依然是吻合的。结合上面分析的QSPI Flash CS低有效时间来看,二者确实是五倍的关系。可是此时的CS信号周期的高电平时间比QSPI Flash下的时间要更长,达到了100.47us,最终致使两种不一样性能Flash下拷贝时间差很少。

  分析到这里,咱们已经找到了线索,ROM从Flash prefetch buffer里拷贝4KB数据到TCM固定耗时约112us,所以速度瓶颈不在Flash自己读速率,而在于搬移时的开销,那么是什么致使了这个固定开销?

  由于ROM代码是个黑盒子,咱们看不见,痞子衡为了找到这个系统开销,在Octal Flash Non-XIP启动的App里用memcpy作了一样的数据搬移。根据上面表格里的结果,咱们知道ROM里搬移230KB数据需耗时6.576ms,经测试App里搬移230KB数据仅需3.265ms,ROM和App的区别主要是执行效率不同(ROM默认配置的CPU主频是400MHz(注:最高能够配到696MHz),App配置的CPU主频是996MHz),因此CPU主频是影响固定开销的因素。

memcpy((void *)0x6000, (const void *)0x30002000, 230 * 1024);

  由于Non-XIP App没有为FlexSPI映射地址开启cache,痞子衡特意开了cache再次作了测试,此次拷贝230KB数据仅需724us,这个值几乎已经逼近了理论计算值(230KB/4KB) x 12.33us = 708.9us,因此ROM是在没有使能cache下作的数据搬移,Cache是否使能也是影响固定开销的因素。

//#if defined(XIP_EXTERNAL_FLASH) && (XIP_EXTERNAL_FLASH == 1)
    /* Region 7 setting: Memory with Normal type, not shareable, outer/inner write back. */
    MPU->RBAR = ARM_MPU_RBAR(7, 0x30000000U);
    MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_RO, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_16MB);
//#endif

  这个发现也告诉咱们使用memcpy()函数搬移Flash数据,是否使能cache对执行效率影响很是大。使能cache以后,作数据搬移时,CPU往TCM写数据与cache从Flash里预取数据能够更大程序的并行,而且cache的读都是burst操做,能加速搬移。而若是不使能cache,下一次的Flash读须要等待上一次CPU写完TCM才会开始,搬移时间会长。

  至此,恩智浦i.MX RT1170 FlexSPI NOR启动时间痞子衡便介绍完毕了,掌声在哪里~~~

欢迎订阅

文章会同时发布到个人 博客园主页CSDN主页微信公众号 平台上。

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