如何使用使用方式一 知道了这块特殊内存,那么我们怎么来使用他呢?常用Keil的人应该知道,在其配置中,有如下选项:
在默认情况下,其中的IRAM2我们不选中,现在我们就可以选中该部分。这样,Keil在生产代码时,就会自动将变量分配到该部分RAM中了。具体的可以打开,Keil生成的.map文件看看。
Execution Region RW_IRAM2 (Base: 0x10000000, Size: 0x00005ce4, Max: 0x00010000, ABSOLUTE)
Base Addr Size Type Attr Idx E Section Name Object
0x10000000 0x00005ce4 Zero RW 16003 .bss ram2.o
Execution Region RW_IRAM1 (Base: 0x20000000, Size: 0x0001b360, Max: 0x00020000, ABSOLUTE, COMPRESSED[0x000000c8])
Base Addr Size Type Attr Idx E Section Name Object
0x20000000 0x00000001 Data RW 264 .data pbuf.o 0x20000001 0x00000001 Data RW 909 .data api_msg.o
注意:
如果仅仅定义几个变量,可能Keil不会将其放到该RAM中。 我在用的时候,没有选中RAM2,Keil仍然把部分内存放到了RAM2中,不知为啥! 但是,这样就有一个问题:由于其只能被内核访问,一旦Keil将例如DMA用的内存放到了该部分RAM中,那么DMA将不能工作! 那么怎么使用更合适呢?
使用方式二 如前所说,直接让编译器自动分配貌似不太合适,所以我们可以自己指定分配的内存。这其中也有两种方式。 第一种依靠分散加载文件(.sct),更强大,直接定义一个文件(例如,名字为 RAM2.c),将所有要放得变量均放到该文件中,然后如下修改分散加载文件。
LR_IROM1 0x0800C000 0x00100000 { ; load region size_region ER_IROM1 0x0800C000 0x00100000 { ; load address = execution address *.o (RESET, +First) ; 中断向量表 *(InRoot$$Sections) .ANY (+RO) }
RW_IRAM1 0x20000000 0x00020000 { ; RW data .ANY (+RW +ZI) } ; 指定使用CCM RW_IRAM2 0x10000000 0x00010000 { RAM2.O (RAM2,+RW +ZI) } }
还有一种方式就是直接使用编译器指令:__attribute__+at。在定义变量时,如下即可:
UINT32 EventNum __attribute__((at(0x10000000))) = 0;
当然,这种方式也可以稍微变化一下,使用__attribute__+section。给变量指定一个节区名字,然后在分散加载文件中指定节区位置。 如上处理编译后,可查看map文件对应部分内存中变量的分配了。
|