IMXRT分散加载⽂件修改OCRAM,DTCM、ITCM⼤⼩
分散加载
MXRT1052/1064芯⽚的RAM空间分为四种类型:ITCM,DTCM,OCRAM以及外部SDRAM,其中前⾯三个属于芯⽚内部
RAM,RT1052有512KB,RT1064为1MB,⽀持⽤户静态分配,SDRAM属于外置RAM,最⼤⽀持到1.5G扩展空间。ITCM和DTCM 是直接挂在芯⽚内核总线,速度可以达到与内核同频的600M,OCRAM挂在Sys AXI 64位总线,速度只能到达133M,外部SDRAM速度则可达到166M,⽽同时RT1050/1064内⼜有各32K的指令cache和数据cache,⽤于提⾼代码在外部Nor Flash中XIP执⾏的效率。从速度的⾓度看,将所有的⽤户代码分配ITCM/DTCM,能够发挥到最⼤性能,从存储空间⼤⼩的⾓度看,代码存放在SDRAM或者外部Flash最简单,⽽从USB/DMA使⽤的⾓度来看,RAM空间分配在OCRAM空间最为⽅便。所以这些不同RAM类型速度/⼤⼩的差异和cache的存在,就决定了要想让IMXRT性能发挥到最⼤,就需要⽤户根据客户实际应⽤⼿动修改内部RAM空间中ITCM/DTCM/OCRAM的⼤⼩分配,并定位关键代码和数据到指定RAM空间中运⾏。
1.如何将关键代码和数据到指定RAM中运⾏?
① IAR中⾸先到使⽤的对应分散加载⽂件,⽤记事本打开;
② 确定⾃⼰的内存分配,如下是默认的⼀种分配⽅式。
/* 中断向量表 */
cacheable
define symbol m_interrupts_start =0x70002000;
define symbol m_interrupts_end =0x700023FF;
// 代码存放位置
define symbol m_text_start =0x70002400;
define symbol m_text_end =0x703FFFFF;
// DTCRAM 128K
define symbol dtcram_start =0x20000000;
define symbol dtcram_end =0x2001FFFF;
// OCRAM 768K
define symbol ocram_start =0x20200000;
define symbol ocram_end =0x202BFFFF;
/
/ itcram 128K 注意不要从0x00000000开始
define symbol itcram_start =0x00000004;
define symbol itcram_end =0x0001FFFF;
/* FLASH配置和ivt等信息 */
define exported symbol m_boot_hdr_conf_start =0x70000000;
define symbol m_boot_hdr_ivt_start =0x70001000;
define symbol m_boot_hdr_boot_data_start =0x70001020;
define symbol m_boot_hdr_dcd_data_start =0x70001030;
③ 规定堆栈区域⼤⼩,根据⾃⼰的实际情况分配,堆⼀般是⽤malloc函数动态分配内存区域,栈是程序的局部变量存储空间,可以适当分配⼤⼀点。
// 栈⼤⼩局部变量
if(isdefinedsymbol(__stack_size__)){
define symbol __size_cstack__ = __stack_size__;
}else{
define symbol __size_cstack__ =0x4000;
}
// 堆⼤⼩动态分配malloc分配的空间
if(isdefinedsymbol(__heap_size__)){
define symbol __size_heap__ = __heap_size__;
}else{
define symbol __size_heap__ =0x8000;
}
// RAM中的中断向量表这⾥没有使⽤
define exported symbol __VECTOR_TABLE = m_interrupts_start;
define exported symbol __VECTOR_RAM = m_interrupts_start;
define exported symbol __RAM_VECTOR_TABLE_SIZE =0x0;
define memory mem with size =4G;
④ 定义⼀些储存区域和地址块
// 定义存储地址区域(region)
define region TEXT_region = mem:[from m_interrupts_start to m_interrupts_end]
| mem:[from m_text_start to m_text_end];
define region DTCRAM_region = mem:[from dtcram_start to dtcram_end - __size_cstack__];
define region ITCRAM_region = mem:[from itcram_start to itcram_end];
define region OCRAM_region = mem:[from ocram_start to ocram_end];
/
/ 栈段栈最好分配在DTCRAM中
define region CSTACK_region = mem:[from dtcram_end - __size_cstack__+1 to dtcram_end];
// 定义地址块
define block CSTACK with alignment =8, size = __size_cstack__ {};
define block HEAP with alignment =8, size = __size_heap__ {};
define block RW { readwrite };
define block ZI { zi };
define block NCACHE_VAR { section NonCacheable , section NonCacheable.init };
define block ITCRAM with alignment =8{ section ITCRAMAccess};
define block DTCRAM with alignment =8{ section DTCRAMAccess};
define block OTCRAM with alignment =8{ section OTCRAMAccess};
⑤ 添加IAR⾃动初始化区域
// 初始化sections
initialize by copy { readwrite, section .textrw};
initialize by copy { section ITCRAMAccess, section DTCRAMAccess,
section OCRAMAccess};
do not initialize { section .noinit };
//IAR的ICF⽂件中宏导出给程序使⽤
place at address mem: m_interrupts_start { readonly section .intvec };
place at address mem:m_boot_hdr_conf_start { section .f };
place at address mem:m_boot_hdr_ivt_start { section .boot_hdr.ivt };
place at address mem:m_boot_hdr_boot_data_start { readonly section .boot_hdr.boot_data };
place at address mem:m_boot_hdr_dcd_data_start { readonly section .boot_hdr.dcd_data };
keep{ section .f, section .boot_hdr.ivt, section .boot_hdr.boot_data, section .boot_hdr.dcd_data };
⑥ 将步骤4中定义的储存区域和地址块关联起来
// 把⼀系列sections和blocks放置在某个region中。sections和blocks将按任意顺序放置。
place in TEXT_region { readonly };//代码存放区域
place in DTCRAM_region { block RW };//RW段存放区域(全局或静态不为0变量)
place in DTCRAM_region { block ZI };//ZI段存放区域(全局或静态为0变量)
place in OCRAM_region { last block HEAP };//malloc 动态申请内存区域
place in DTCRAM_region { block NCACHE_VAR };//NCACHE区域需要配合MPU使⽤
place in CSTACK_region { block CSTACK };//站区域局部变量
place in ITCRAM_region { block ITCRAM };//ITCRAM区域
place in DTCRAM_region { block DTCRAM };//DTCRAM区域
place in OCRAM_region { block OCRAM };//OCRAM区域
⑦ 我们上⾯在步骤4中定义了地址块ITCRAMAccess、 DTCRAMAccess、OCRAMAccess,如何在IAR中将变量放到对应地址块呢?
⑧ 打开fsl_common.h,仿照官⽅AT_NONCACHEABLE_SECTION宏定义添加如下宏定义。
#if (defined(__ICCARM__))
#define AT_ITCRAM_SECTION(func) func @"ITCRAMAccess"
#define AT_DTCRAM_SECTION(func) func @"DTCRAMAccess"
#define AT_OCRAM_SECTION(func) func @"OCRAMAccess"
#elif(defined(__ARMCC_VERSION))
#define AT_ITCRAM_SECTION(func) __attribute__((section("ITCRAMAccess"))) func
#define AT_DTCRAM_SECTION(func) __attribute__((section("DTCRAMAccess"))) func
#define AT_OCRAM_SECTION(func) __attribute__((section("OCRAMAccess"))) func
#elif(defined(__GNUC__))
#define AT_ITCRAM_SECTION(func) __attribute__((section("ITCRAMAccess"))) func
#define AT_DTCRAM_SECTION(func) __attribute__((section("DTCRAMAccess"))) func
#define AT_OCRAM_SECTION(func) __attribute__((section("OCRAMAccess"))) func
#endif
⑨ 打开BOARD_ConfigMPU(); 函数修改MPU配置,验证对应的数据分配到了指定位置。
使⽤宏定义修饰函数或者变量,将函数和变量存放到指定位置。
AT_ITCRAM_SECTION(void delayms(uint16_t ms))
{
volatile uint32_t i =0;
while(ms--)
{
for(i =0; i <30000;++i)
{
__asm("NOP");/* delay */
}
}
}
AT_DTCRAM_SECTION(uint8_t dcrambuf[100][1024]);
AT_OCRAM_SECTION(uint8_t orambuf[100][1024]);
⑩ MDK中类似IAR,打开分散加载⽂件,在⾥⾯添加块ITCRAMAccess、 DTCRAMAccess、OCRAMAccess。通过步骤8中的宏定义可以将关键代码和变量存放到指定位置。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论