本帖最后由 小恩GG 于 2021-5-26 13:02 编辑
【经验分享】RT10xxITCM APP高于128K boot解决方案
一 文档简介
最近遇到一个很有趣的案例,并且也找到配套的解决方案,在此分享出来。
案例背景:使用RT1050做flexRAM重新配置:OCRAM 128KB, DTCM 128KB, ITCM256KB,然后生成一个应用代码,比如led_blinky, 这个代码大小超过128KB,并且放到ITCM里面,工程基于MCUXPresso IDE,经过之前的经验分享,可以完美的解决在ITCM里面debug,并且运行稳定。但是当需要下载到外部Flash,并且boot起来的情况下,就出现不能工作的问题。但是当代码大小小于128KB的时候,工作很溜。下面我们以MIMXRT1050-EVKB 以及一个经过修改的SDK led_blinky工程使其在ITCM并且大于128K予以测试,复现问题,分析问题,并且解决问题。
二 案例准备与测试分析
2.1 工程准备
MCUXpresso IDE v11.3.1导入SDK2.9.1_EVKB_IMXRT1050 led_blinky工程。将代码放到ITCM里面,并且修改代码大小,因为代码跑在ITCM属于None XIP,所以在分配地址的时候,通常一般留0X2000给前面的FlexSPI头+IVT+BD+DCD区域,后面开始放APP。本案例中,我们从0X3000开始放APP,然后大小直接定义到256KB也就是0X4000。下面给出具体配置情况:
图1 这里把SRAM_ITC拉到第2行,这样如果代码配置放到RAM,就会直接从这行定义的0X3000开始放代码,并且不会添加FLASH的flexSPI头。 下面选择link application to RAM, 并且Stack的location改为Start,否则会有问题。
图2 代码修改如下,主要就是扩代码大于128KB. 这里定义一段const数组,共2000*20*4=160000字节,也就是0X27100,加上之前偏移的0X3000还有代码部分,已经超出默认的128KB=0X20000。 const uint32_t dummyArray[] = { 共20个1-2000 } 在main中添加下数组的加和,只是调用下数组:
- for(i=0; i<40000; i++) {
- sum += dummyArray[i];
- }
复制代码
由于ITCM的使用大小已经超出默认大小,所以这里需要做flexRAM重新分区,RT1050默认的flexRAM分区情况如下:OCRAM 256KB, DTCM 128KB, ITCM 128KB 下面分区为: OCRAM 128KB, DTCM 128KB, ITCM 256KB 在startup_mimxrt1052.c的ResetISR 头部添加重新配置代码:
- FLEXRAM->TCM_CTRL = 4;
- IOMUXC_GPR->GPR17 = 0x5AFFFFA5;
- IOMUXC_GPR->GPR16 |= 0x7;
- IOMUXC_GPR->GPR14 = (8<<20) | (9<<16) ;// DTCM 128K, ITCM 256K
复制代码
图3 到目前为止,一个完整的大于128KB的ITCM APP已经准备好了,可以先仿真看下,使用MIMXRT1050-EVKB 板载CMSIS DAP debug需要准备一个.scp的脚本,主要也是添加了关于GPR的flexRAM分区调用,否则debug会出问题,在之前的经验分享中也专门讲过。 脚本情况如下:
- 100 REM ===============================
- 110 REM RT1050_connect.scp
- 120 REM
- 130 REM Copyright 2019 NXP
- 140 REM All rights reserved.
- 150 REM ===============================
- 160 print "RT1050 Connect Script"
- 170 REM probelist
- 180 p% = probefirstfound
- 190 rem probeopenbyindex p%
- 200 wireswdconnect p%
- 210 selectprobecore p% 0
- 220 cminitapdp this
- 230 cmhalt this
- 235 goto 320
- 240 rem trap in bootrom
- 250 cmwatchset this 0 0x400F8004 RW
- 260 cmresetvectorcatchclear this
- 270 print "Resetting and trapping"
- 280 cmsysresetreq this
- 290 print "Back from reset"
- 300 cmresetvectorcatchset this
- 310 cmwatchclear this 0
- 320 print "Disabling MPU"
- 330 s% = Peek32 this 0xE000ED94
- 340 s% = s% & 0xFFFFFFFE
- 350 Poke32 this 0xE000ED94 s%
- 360 REM ====== Configure FlexRAM ======
- 370 print "Configure FlexRAM for 128KB OC RAM, 128KB I-TCM, 256KB D-TCM"
- 380 REM TCM CTRL Poke 0x400B0000 - to force RAM clocking and set wait states = b100
- 390 Poke32 this 0x400B0000 0x4
- 400 REM IOMUXC_GPR17 0x400AC044 - this sets bitfield allocation of FlexRAM 32KB banks to OC 128KB b01, I 256KB b11, D 128KB b10
- 410 Poke32 this 0x400AC044 0x5AFFFFA5
- 420 REM IOMUXC_GPR16 0x400AC040 - this sets enables for I and DTCM and the source of the TCM config = 0x200007
- 430 Poke32 this 0x400AC040 0x200007
- 440 Poke32 this 0x400AC038 0x890000
- 450 print "Finished"
- 460 REM ===============================
- 470 end
复制代码
上面脚本命名为RT1050_connect_128Kocram_256Kitcm_128Kdtcm.scp,放到IDE路径:C:\nxp\MCUXpressoIDE_11.3.1_5262\ide\binaries\Scripts Debug配置界面选择刚才准备好的脚本:Run->Debug Configurations Connect script选择刚才的脚本:
图4
图5 可以看到已经进入debug,运行也能看到灯闪烁。 生成.s19备用。 2.2 MFGTool下载代码到flash
可以基于SDK_2.9.1_EVKB-IMXRT1050\middleware\mcu-boot\bin\Tools,不过注意需要添加elftosb和blhost,下载链接: 也可以直接使用Flashloader_i.MXRT1050_GA 在Tools\elftosb\win路径下加入:app.s19,imx-itcm-unsigned.bd,program_flexspinor_image_hyperflash.bd 命令: elftosb.exe-f imx -V -c imx-itcm-unsigned.bd -o ivt_evkbimxrt1050_iled_blinky_0x3000.binevkbimxrt1050_iled_blinky_0x3000.s19 elftosb.exe-f kinetis -V -c program_flexspinor_image_hyperflash.bd -o boot_image.sbivt_evkbimxrt1050_iled_blinky_0x3000_nopadding.bin 生成boot_image.sb烧录之后发现灯不亮。 排除操作性问题。 2.3 不能boot原因分析 首先我们分析一下ROM加载image过程:
图6 可以看到,按照我们目前的情况,IVT BD数据加载都没有问题,但是在最后一步,application加载,由于我们不是使用fuse方式重新配置flexRAM,而是使用GPR寄存器控制,这个GPR寄存器控制放在reset入口的代码里面,所以会导致ROM加载的时候ITCM还是默认的128KB,但是需要加载的应用大小已经完全超出了128KB,这个时候会导致ROM拷贝APP失败,所以应用运行也会失败,那么这种情况该如何解决?
二 解决方案
最大的解决方案就是需要在ROM拷贝Application的时候,已经做好FLEXRAM的重新分配,所以我们可以借助SDRAM使用DCD去配置SEMC的方式,查看DCD支持的有效地址:
图7 很庆幸,可以看到,DCD能够支持IOMUXC_GPR寄存器。 所以下面使用MCUXPresso IDE,生成dcd.bin,方法如下: ConfigTools->Device Configuration, 删掉之前关于SDRAM的配置,配置如下:
图8 这里有个坑需要注意,切不可像小编一样之前使用GPR14,GPR16,GPR17顺序,这样生成的.bin不能工作。
图9 可以看到dcd.bin组成部分是dcd的头,还有三个寄存器地址以及数据。 下面开始运行 elftosb生成.sb文件: imx-itcm-unsigned.bd需要改为如下代码:
- <p>options {
- flags = 0x00;
- # Note: This is an example address, it can be any non-zero address in ITCM region
- startAddress = 0x1000;
- ivtOffset = 0x1000;
- DCDFilePath = "dcd.bin";
- initialLoadSize = 0x2000;
- # Note: This is required if the default entrypoint is not the Reset_Handler
- # Please set the entryPointAddress to Reset_Handler address
- entryPointAddress = 0x00003000;
- }</p><p>sources {
- elfFile = extern(0);
- }</p><p>section (0)
- {
- }
- </p>
复制代码 添加了dcd.bin文件,需要将dcd.bin放到elftosb.exe路径下。继续运行上面2.2节两条命令,
图10 生成boot_image.sb拷贝到: Tools\mfgtools-rel\Profiles\MXRT105X\OSFirmware
图11 下载成功。 SW7改为1-OFF,2-ON,3-ON,4-OFF 按下复位,可以看到小灯闪烁,代码成功运行,也就是说使用DCD添加GPR配置重新分区FlexRAM的方式对大于128KB的ITCM APP有效。 希望该经验分享对大家有用。 |