电子说
应用笔记AN12077 解释了如何通过应用程序启动代码中的软件重新分配FlexRAM。下面将进一步详细说明进行这些修改的方法。
RT | Internal SRAM | FlexRAM |
---|---|---|
RT1010 | Up to 128 KB | Up to 128 KB |
RT1015 | Up to 128 KB | Up to 128 KB |
RT1020 | Up to 256 KB | Up to 256 KB |
RT1050 | Up to 512 KB | Up to 512 KB |
RT1060 | Up to 1MB | Up to 512 KB |
RT1064 | Up to 1MB | Up to 512 KB |
对于RT106x系列,1MB的内部SRAM中只有512 KB可以通过FlexRAM重新分配为DTCM、ITCM和OCRAM。剩余的512 KB来自OCRAM,无法重新分配。对于所有其他RT10xx,可以将整个内部SRAM重新分配为DTCM、ITCM和OCRAM。应用笔记AN12077 第3.1.3.1节解释了重新分配FlexRAM时的大小限制。值得一提的是,所有RT10xx部件中的ROM引导加载程序都使用OCRAM,因此在重新分配FlexRAM时,应该保留一些OCRAM,这不适用于RT106x,因为将始终拥有512 KB的OCRAM,无法重新分配。
MCUXpresso IDE中的实现
首先,需要将SDK示例导入MCUXpresso IDE工作区。为RT1050-EVKB导入了igpio_led_output示例。如果编译此项目,将看到RT1050-EVKB上FlexRAM的默认配置如下:
SRAM_DTC:128 KB,SRAM_ITC:128 KB,SRAM_OC:256 KB
现在需要转到文件startup_mimxrt1052.c中的复位处理程序。重新分配FlexRAM必须在配置FlexRAM之前完成,这就是为什么要在复位处理程序中完成的原因。需要修改以重新分配FlexRAM的寄存器是IOMUX _GPR_GPR16和IOMUX _GPR _GPR17。
Register | Address |
---|---|
IOMUXC_GPR_GPR16 | 0x400AC040 |
IOMUXC_GPR_GPR17 | 0x400AC044 |
需要确定如何重新分配FlexRAM,以查看需要加载到寄存器IOMUXC_GPR_GPR17中的值。如果希望具有以下配置:
SRAM_DTC | 256 KB |
SRAM_ITC | 128 KB |
SRAM_OC | 128 KB |
以下对IOMUXC_GPR_GPR17寄存器的解释:
需要加载到寄存器的值是0xAAAAFF55。其中,前4个存储块对应于128KB的SRAM_OC,接下来的4个存储块对应于128 KB的SRAM_ITC,最后8个存储块是256KB的SRAM-DTC。现在就可以开始在 ResetISR处理程序中编写代码了。首先要做的是将新值加载到寄存器IOMUXC_GPR_GPR17中。之后,需要配置寄存器IOMUXC_GPR_GPR16,以指定FlexRAM存储体配置应取自寄存器IOMUX _GPR_GPR 17,而不是熔丝Fuse。然后,如果在FlexRAM的新配置中,SRAM_DTC或SRAM_ITC的大小为0,则需要禁用寄存器IOMUXC_GPR_GPR16中的这些存储器。代码如下所示:
void ResetISR(void) { // Disable interrupts __asm volatile ("cpsid i"); /* Reallocating the FlexRAM */ __asm (".syntax unified " "LDR R0, =0x400ac044 "//Address of register IOMUXC_GPR_GPR17 "LDR R1, =0xaaaaff55 "//FlexRAM configuration DTC = 265KB, ITC = 128KB, OC = 128KB "STR R1,[R0] " "LDR R0,=0x400ac040 "//Address of register IOMUXC_GPR_GPR16 "LDR R1,[R0] " "ORR R1,R1,#4 "//The 4 corresponds to setting the FLEXRAM_BANK_CFG_SEL bit in register IOMUXC_GPR_GPR16 "STR R1,[R0] " #ifdef FLEXRAM_ITCM_ZERO_SIZE "LDR R0,=0x400ac040 "//Address of register IOMUXC_GPR_GPR16 "LDR R1,[R0] " "AND R1,R1,#0xfffffffe "//Disabling SRAM_ITC in register IOMUXC_GPR_GPR16 "STR R1,[R0] " #endif #ifdef FLEXRAM_DTCM_ZERO_SIZE "LDR R0,=0x400ac040 "//Address of register IOMUXC_GPR_GPR16 "LDR R1,[R0] " "AND R1,R1,#0xfffffffd "//Disabling SRAM_DTC in register IOMUXC_GPR_GPR16 "STR R1,[R0] " #endif ".syntax divided "); #if defined (__USE_CMSIS) // If __USE_CMSIS defined, then call CMSIS SystemInit code SystemInit();
如果编译项目,将看到控制台上显示的内存分布仍然是默认配置。这是因为修改了Reset处理程序以重新分配FlexRAM,但没有修改链接器文件以匹配这些新大小。为此,需要转到项目的属性。进入属性后,需要转到C/C++构建->MCU设置。一旦进入MCU设置,需要修改SRAM内存的大小以匹配新配置。
在进行这些更改后,如果编译项目,将看到控制台中显示的内存分布与现在新大小相匹配。
需要修改内存保护单元(MPU)以匹配这些新的内存大小。为此,需要转到文件板中的函数BOARD_ConfigMPU.c。在该函数中,需要找到分别对应于SRAM_ITC、SRAM_DTC和SRAM_OC的区域5、6和7。与寄存器IOMUXC_GPR_GPR14相同,如果内存的新大小不是32、64、128、256或512,则需要选择下一个更大的数字。配置应如下所示:
/* Region 5 setting: Memory with Normal type, not shareable, outer/inner write back */ MPU->RBAR = ARM_MPU_RBAR(5, 0x00000000U); MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_128KB); /* Region 6 setting: Memory with Normal type, not shareable, outer/inner write back */ MPU->RBAR = ARM_MPU_RBAR(6, 0x20000000U); MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_256KB); /* Region 7 setting: Memory with Normal type, not shareable, outer/inner write back */ MPU->RBAR = ARM_MPU_RBAR(7, 0x20200000U); MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_128KB);
最后,需要将堆栈放在DTCM内存的开头。为此,需要转到项目的属性。从那里,必须用C/C++构建和管理Linker脚本。
然后,需要在ResetISR函数中再添加两条汇编指令。我们必须在汇编代码的开头添加以下两条指令:
这些就是在启动期间重新分配FlexRAM所需的所有更改。
调试会话: 为了验证刚才所做的所有修改是否正确,将启动调试会话。一旦到达main,在运行应用程序之前,将转到外设视图查看寄存器IOMUX _GPR_GPR16和IOMUX _GPR _GPR17,并验证值是否正确。如下图所示,在寄存器IOMUXC_GPR_GPR16中,将FLEXRAM_BANK_CFG_SEL配置为1,以使用寄存器IOMUX _GPR_GPRS17配置FLEXRAM。
最后,在寄存器IOMUXC_GPR_GPR17中,我们可以看到对应于新配置的值0xAAAAFF55。
通过熔丝重新分配FlexRAM
上述操作是如何通过在复位处理程序中编写一些代码来通过软件重新分配FlexRAM。此过程工作正常,使用此方法测试可以配置不同大小RAM,但一旦找到应用程序的正确配置,建议通过熔丝配置这些新大小,而不是使用寄存器IOMUX _GPR_GPR17。在代码中重新配置FlexRAM有很多危险区域。这几乎都归结为这样一个事实:写入RAM的任何代码/数据/堆栈信息都可能在重新分配期间改变位置。这就是为什么一旦找到正确的配置,就应该通过熔丝进行应用。如果使用Fuse来配置FlexRAM,那么就不必担心代码和数据的移动,因为Fuse 设置被应用为硬件默认设置。记住,一旦烧了熔丝,就没有退路了!这就是为什么首先通过软件方法尝试配置很重要。烧完熔丝后,无需修改复位处理程序,只需修改MPU以更改我们之前看到的区域大小和项目的MCU设置,以匹配通过熔丝配置的新内存大小。
负责FlexRAM配置的熔丝为Default_FlexRAM_Part,此熔丝的地址为0x6D0[15:13]。可以在参考手册的Fusemap一章中找到有关此保险丝和不同配置的更多信息。要烧熔丝,建议使用blhost或MCUBootUtility。两个工具的下载链接如下:
https://www.nxp.com/webapp/sps/download/license.jsp?colCode=blhost_2.6.2&appType=file1&location=null&DOWNLOAD_ID=null
https://github.com/JayHeng/NXP-MCUBootUtility
ResetISR.c参考代码:
审核编辑:汤梓红
全部0条评论
快来发表一下你的评论吧 !