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

眼看着i.MXRT1170上市日期越来越近了,恩智浦软硬件技术支持团队也正在紧锣密鼓地开发SDK以及参考设计。因为官方首次在i.MXRT1170 EVK板上(Rev.B)放了一片旺宏的Raw NAND芯片,而i.MXRT当然是支持从Raw NAND启动的,因此痞子衡打算为大家测一测Raw NAND的启动时间(这里指在ITCM执行,暂不考虑在SDRAM执行)


  大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家介绍的是恩智浦i.MX RT1170 Raw NAND启动时间。

  关于i.MXRT1170这颗划时代的MCU,痞子衡去年10月在其刚发布的时候,专门写过一篇文章介绍过其特点(详见 《终于可以放开聊一聊i.MXRT1170这颗划时代MCU了》),眼看着其上市日期越来越近了,恩智浦软硬件技术支持团队也正在紧锣密鼓地开发SDK以及参考设计。因为官方首次在i.MXRT1170 EVK板上(Rev.B)放了一片旺宏的Raw NAND芯片,而i.MXRT当然是支持从Raw NAND启动的,因此痞子衡打算为大家测一测Raw NAND的启动时间(这里指在ITCM执行,暂不考虑在SDRAM执行)。

一、准备工作

1.1 知识储备

  在开始测试之前,你需要认真读一下痞子衡的旧文 《恩智浦i.MX RT1xxx系列MCU启动那些事(8)- 从Raw NAND启动》,对i.MXRT从Raw NAND启动的原理有一个充分认识。
  Raw NAND启动不同于你最熟悉的Serial NOR启动,由于NAND访问的特殊性(仅能按Page读,且允许坏块),因此其仅支持Non-XIP Application(即需要把Application image从NAND中全部拷贝出来,放到RAM中执行),无法原地执行。这个拷贝工作就由芯片内部的BootROM来完成,为了让BootROM顺利完成拷贝工作,我们需要在NAND中放一些特殊数据(即下面的FCB, DBBT, IVT)。
  FCB永远放在NAND的第一个block里的固定位置,BootROM首先从NAND中读取FCB(此时是利用eFuse 0x940和0xC80里的简化时序配置选项),FCB中含有三类信息:用户设置的完整时序配置数据(可选的)、DBBT位置,IVT位置。BootROM首先会检查是否存在完整时序配置数据,如果有,则使用这个数据重新配置NAND访问时序。然后BootROM会继续获取DBBT数据,获知当前NAND的坏块信息,接下来便是根据IVT信息获取Application数据完成拷贝(拷贝过程中需要避开坏块)。

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

1.2 时间界定

  说到启动时间的界定,其实无非是找到时间起点以及时间终点。
  时间起点很好办,根据i.MXRT1170芯片POR信号变化即可(下图中的RST_TGTMCU_B的上升沿),也就是芯片开始上电为起点。

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

  时间终点稍微有点难办,如果监测Raw NAND信号(比如CE#最后一个上沿)有点难抓,也不够精准,毕竟BootROM拷贝完所有Application image数据后是否还会做一些校验工作才会跳转不得而知,所以还是以执行到Application为准。到了Application的执行就简单了,在Application里加个GPIO翻转(比如点灯)即可,我们只需抓取这个GPIO的信号变化(抓下图中R1855的上升沿)。

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

1.3 制作应用程序

  现在我们开始制作测试用的Non-XIP Application,以\SDK_xxx_MIMXRT1170-EVK\boards\evkmimxrt1170\demo_apps\led_blinky\cm7\下的工程为基础,但需要做一些修改。
  痞子衡以IAR工程示例,首先需要选中debug build(release也行),这个build即是在ITCM中执行的Non-XIP版本,而且其链接文件里的m_interrupts_start也需要从0x00000000修改为0x00002000(这里如果不明白的话,继续回去看痞子衡写的Raw NAND启动文章)。

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

  这个工程里的led_blinky.c里已经有GPIO翻转代码了,但是位置在main()函数里,为了得到尽量准确的启动时间,我们应该把GPIO翻转的代码提前,下面是程序Reset_Handler代码,原则上我们应该要在这里加汇编,但是为了简单起见,我们也可以在SystemInit()函数里加C代码(痞子衡认为在data/bss段初始化之前就可以了)。

        PUBWEAK Reset_Handler
        SECTION .text:CODE:REORDER:NOROOT(2)
Reset_Handler
        CPSID   I               ; Mask interrupts
        LDR     R0, =0xE000ED08
        LDR     R1, =__vector_table
        STR     R1, [R0]
        LDR     R2, [R1]
        MSR     MSP, R2
        LDR     R0, =SystemInit
        BLX     R0
        CPSIE   I               ; Unmask interrupts
        LDR     R0, =__iar_program_start
        BX      R0

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

  编译后可以得到一个17732 bytes的Application(可以生成.srec格式,方便后面下载),但是我们知道Raw NAND启动时间跟Application长度是成正比的(主要耗时就是在拷贝上),所以我们还需要再制作一个稍微大一些的Application,可以直接在代码里加上如下const数组定义,并且在IAR的Option/Linker/Input里的Keep symbols里加上s_dummyBuffer,防止这个数组被优化掉。

const uint8_t s_dummyBuffer[1024*230] = {0};

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

1.4 下载应用程序

  应用程序的下载需借助痞子衡开发的NXP-MCUBootUtility工具(v2.2版本及以上),将i.MXRT启动模式设到SDP模式(EVK上SW1拨码开关设为4'b0001),然后给板子上电。软件的使用不予赘述,NAND具体配置如下即可,后面的测试我们只需要更改ONFI Timing Mode这一个参数。

Note: 这个工具会自动生成FCB(包含完整NAND时序配置), DBBT, IVT并将其和Application一起下载进Raw NAND中

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

  程序下载完成后,将i.MXRT启动模式设到Internal Boot模式(EVK上SW1拨码开关设为4'b0010),并且将启动设备设为Raw NAND(EVK上SW2拨码开关设为10'b0000010000),断电重启你应该就可以看到LED灯会亮,这代表Raw NAND启动成功了。

1.5 示波器抓取信号

  一切准备就绪,可以用示波器抓Raw NAND启动时间了。除了通道一监测POR信号,通道三监测LED GPIO信号,为了更直观地看启动过程,痞子衡特地加了通道二来监测NAND_CE#信号,这样可以看到Application拷贝过程。

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

二、开始测试

2.1 影响因素

2.1.1 App长度

  App的长度是影响启动时间的第一因素。痞子衡在前面 1.3节 制作应用程序里,已经制作了两个不同长度的App用于测试。

2.1.2 NAND访问模式

  NAND访问模式是影响启动时间的第二因素。SEMC支持的NAND访问模式一共两种,分别是IPG CMD模式和AXI CMD模式,前者是应用程序手动发命令去一次读取4byte数据到SEMC数据寄存器,然后再从寄存器中取数据;后者是应用程序访问指定的AXI空间(假定也是取4byte),由SEMC自动发命令读取4byte并放到对应AXI映射空间里。
  NXP-MCUBootUtility工具里所依赖的flashloader固定使用IPG CMD模式,因此想切换到AXI CMD模式,需要从SDK/middleware/mcu-boot中获取flashloader源码,修改源码(在semc_nand_mem_config()函数中做如下修改)后重新编译使用。

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

  使用修改后的flashloader程序下载完成Application之后,需要在回读的image数据中偏移0x109的地址查看数据(0x01代表AXI,0x00代表IPG)。

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

  痞子衡继续使用示波器抓取NAND_RE#信号如下:
  这是IPG CMD模式下的时序(ONFI timing mode5):

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

  这是AXI CMD模式下的时序(ONFI timing mode5):

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

  从上述时序上看,AXI CMD模式读取数据明显比IPG CMD模式更高效,每4byte访问之后的间隔时间大大缩短。

2.1.3 ONFI Timing Mode

  ONFI Timing Mode是影响启动时间的第三因素。NXP-MCUBootUtility工具中支持更改ONFI Timing Mode(主要是将设置写进FCB),痞子衡查了下EVK板上这颗NAND芯片,能支持mode0 - mode5一共6种模式,我们就先来看看最慢的mode0和最快的mode5是否设置生效。在程序下载完成之后,需要在回读的image数据中偏移0x153的地址查看数据(0x01代表mode0,0x06代表mode5)。

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

  Raw NAND访问是通过SEMC模块实现的,SEMC一次会从NAND读取4byte放到内部32bit数据寄存器中,痞子衡使用示波器抓取NAND_RE#信号如下:
  这是ONFI Timing Mode0下的时序:

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

  这是ONFI Timing Mode5下的时序:

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

  从上述时序上看,ONFI Timing Mode设置是生效的,mode5耗时确实比mode0短一些,与ONFI 1.0手册里规定的数值基本是吻合的。

2.2 测试结果

  前面分析完了影响因素,现在到了公布结果的时候了,痞子衡基于前面的影响因子组合一共做了8个测试,结果如下表所示。总之一句话,想要最快的启动时间,设为AXI访问模式以及ONFI Timing Mode5即可,另外如果对启动时间敏感(比如Auto应用),不妨做两级启动(Boot+App),Boot尽量小,App可以很大,Boot起来之后去做一些启动任务(响应CAN,点亮LCD屏),然后由Boot再去慢慢加载App。

NAND访问模式 ONFI时序模式 Application长度 启动时间
IPG CMD mode 0 - 10MHz 17732 bytes 40.58ms
IPG CMD mode 5 - 50MHz 17732 bytes 38.90ms
IPG CMD mode 0 - 10MHz 253252 bytes 172.3ms
IPG CMD mode 5 - 50MHz 253252 bytes 164.3ms
AXI CMD mode 0 - 10MHz 17732 bytes 32.8ms
AXI CMD mode 5 - 50MHz 17732 bytes 32.6ms
AXI CMD mode 0 - 10MHz 253252 bytes 104.9ms
AXI CMD mode 5 - 50MHz 253252 bytes 78.86ms

  测试结果波形图较多,痞子衡且放一张(AXI, mode0, 17732bytes)给大家看看吧。

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

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

上一篇:【DB笔试面试52】​在Oracle中,下列哪种标量类型不能保存到数据库表中()


下一篇:一步一步搭建11gR2 rac+dg之DG 机器配置(七)