简介
之前有用过RT10xx的朋友知道,FlexRam :ITCM/DTCM和OCRAM共享。其中RT101x,RT102x和RT105x是必须预留最少32K的OCRAM分配;RT106x和RT117x是可以不在FlexRam中配置,因为他们有额外的OCRAM。通常情况下,如果工程源码都能赛到TCM里面肯定是效率最高的,但是很多时候我们需要很大的缓存时候就需要用上OCRAM甚至是SDRAM的了。
注意:RT117x需要考虑是否使用ECC我们先不考虑这个,就先不使用吧
1. FlexRam配置方法
这里首先笔者建议FlexRam全部交给TCM用,毕竟OCRAM速度会比TCM差很多。
同之前的RT系列一样,FlexRam分配最小单位为Bank,每个Bank为32KB。RT1176拥有16个Bank,即512K
配置寄存器每两位表示一个Bank(32KB),其中
00表示未使用
01表示配置为OCRAM
10表示配置为DTCM
11表示配置为ITCM
需要注意的是,配置寄存器同以往的有点点不一样,寄存器基地址变化为: IOMUXC_GPR base address: 400E_4000h
FlexRam Bank配置分别由gpr17和gpr18来配置
具体配置如下:
/* Reset Handler */
.thumb_func
.align 2
.globl Reset_Handler
.weak Reset_Handler
.type Reset_Handler, %function
Reset_Handler:
cpsid i /* Mask interrupts */
.equ VTOR, 0xE000ED08
ldr r0, =VTOR
ldr r1, =__Vectors
str r1, [r0]
ldr r2, [r1]
msr msp, r2
/*FlexRam 内存分配*/ //OCRAM = 0KB, DTCM = 352KB ,ITCM = 160KB,
ldr R0,=0x400E4040 //gpr16 使能FLEXRAM_BANK_CFG
ldr R1,=0x0000AA07
str R1,[R0]
ldr R0,=0x400E4044 //gpr17 0:15 有效
ldr R1,= 0x0000FFEA
str R1,[R0]
ldr R0,=0x400E4048 //gpr18 0:15 有效
ldr R1,= 0x0000AAAA
str R1,[R0]
ldr r0,=SystemInit
blx r0
cpsie i /* Unmask interrupts */
ldr r0,=__main
bx r0
.pool
.size Reset_Handler, . - Reset_Handler
2. scf链接脚本修改
结合FlexRam的修改,更新对应的链接脚本
#define __ram_vector_table_size__ 0x00000400
#define m_flash_config_start 0x30000400
#define m_flash_config_size 0x00000C00
#define m_ivt_start 0x30001000
#define m_ivt_size 0x00001000
#define m_interrupts_start 0x30002000
#define m_interrupts_size 0x00000400
#define m_text_start 0x30002400
#define m_text_size 0x00FBDC00
/*ITCM 160kB*/
#define m_itcm_start 0x00000000
#define m_itcm_size 0x00028000
#define m_interrupts_ram_start 0x00000000
#define m_interrupts_ram_size __ram_vector_table_size__
#define m_data_start (0x20000000 + m_interrupts_ram_size)
#define m_data_size (0x00040000 - m_interrupts_ram_size)
#define m_text_itcm_start m_itcm_start + m_interrupts_size
#define m_text_itcm_size m_itcm_size
/*DTCM 352kB*/
#define m_dtcm_start 0x20000000
#define m_dtcm_size 0x00058000
#define m_data_dtcm_start m_dtcm_start
#define m_data_dtcm_size m_dtcm_size
/*OCRAM M4 256KkB 测试该区域会慢1倍多*/
#define m_ocram_start 0x20200000
#define m_ocram_size 0x00040000
#define m_data_ocram_start m_ocram_start
#define m_data_ocram_size m_ocram_size
/*OCRAM1 512kB*/
#define m_ocram1_start 0x20240000
#define m_ocram1_size 0x00080000
/*OCRAM2 512kB*/
#define m_ocram2_start 0x202C0000
#define m_ocram2_size 0x00080000
#define m_core1_image_start 0x30FC0000
#define m_core1_image_size 0x00040000
/*SDRAM*/
#define m_sdram_start 0x80000000
#define m_sdram_size 0x02000000
/* Sizes */
#if (defined(__stack_size__))
#define Stack_Size __stack_size__
#else
#define Stack_Size 0x1000
#endif
#if (defined(__heap_size__))
#define Heap_Size __heap_size__
#else
#define Heap_Size 0x0400
#endif
LR_m_text m_flash_config_start m_text_start+m_text_size-m_flash_config_start
{ ; load region size_region
RW_m_config_text m_flash_config_start FIXED m_flash_config_size
{ ; load address = execution address
*(.boot_hdr.conf, +FIRST)
}
RW_m_ivt_text m_ivt_start FIXED m_ivt_size
{ ; load address = execution address
*(.boot_hdr.ivt, +FIRST)
*(.boot_hdr.boot_data)
*(.boot_hdr.dcd_data)
}
;向量表初始位置,需要拷贝到执行效率更高的地方
VECTOR_ROM m_interrupts_start FIXED m_interrupts_size
{ ; load address = execution address
*(.isr_vector,+FIRST)
}
ER_m_text m_text_start FIXED m_text_size
{ ; load address = execution address
*(InRoot$$Sections) ;__main 函数段 必须在flash,执行相关拷贝工作
; startup_mimxrt1176_cm7.o(.text)
system_MIMXRT1176_cm7.o (+RO)
*(.RESET)
}
;向量表运行域
VECTOR_RAM m_interrupts_ram_start EMPTY m_interrupts_ram_size
{
}
RW_m_ram_text m_text_itcm_start m_text_itcm_size
{ ;
.ANY (+RO)
}
RW_m_dtcm_data m_dtcm_start m_data_dtcm_size-Stack_Size-Heap_Size
{ ; RW data
.ANY (+RW +ZI)
*(RamFunction)
*(NonCacheable.init)
*(*NonCacheable)
}
RW_Ocram2_Data m_ocram2_start m_ocram2_size
{
* (ocram_data)
}
RW_Ocram1_Data m_ocram1_start m_ocram1_size
{
; * (ocram_data)
}
RW_m_sdram_data m_sdram_start m_sdram_size
{
*(sdram_data)
}
ARM_LIB_STACK m_data_dtcm_start+m_data_dtcm_size EMPTY -Stack_Size
{ ; Stack region growing down
}
ARM_LIB_HEAP +0 EMPTY Heap_Size
{ ; Heap region growing up
}
}
LR_CORE1_IMAGE m_core1_image_start
{
CORE1_REGION m_core1_image_start m_core1_image_size
{
*(*core1_code)
}
}
这里需要注意的是OCRAM分为几类:OCRAM1、OCRAM2、OCRAM M4、OCRAM M7(FlexRam)。因为配置上没使用ECC,配置FlexRam的时候也没配置OCRAM,所以OCRAM M7这部分就不用考虑了。接下来只需要关心剩余部分: