CCMRAM使用方法:Keil5和IAR
CCMRAM是什么?
Core Coupled Memory,内核专用内存区域,对于st的f4系列芯片,仅内核的dbus总线可以访问,DMA不能访问该内存区域。因此,无法在kei 的项目配置里面直接设置该地址为项目内存,不然有需要dma访问的变量定义在该区域后,DMA访问将失效照成数据无法读取写入等问题。
宏定义区分ac5和ac6和gcc编译器
参考链接:
- 升级 MDK 5.37 后的问题处理: AC6编译选项, printf, 重启失效等
- 处理编译器识别
- 处理如题问题等
- GCC如何将变量编译到指定ROM地址
- 详细介绍了如何将代码编译到指定位置且讨论了相关错误如何处理
- 还介绍了如何最大话的利用ROM空间
- stm32 ccmram的使用(stm32f407)
- 很传统直接的介绍ccmram的用法
- GCC-LD 连接脚本分析–uboot.lds
两种方法,看情况选择一种即可
1 | // 方法一 |
使用CCMRAM内存
keil设置
- keil里target栏设置IRAM2为CCMRAM地址和大小,IRAM1为普通RAM地址和大小
- linker栏取消勾选Use Memory Layout。。。
- 然后下面面的scatter file变为可修改文件,点击右边的edit
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16LR_IROM1 0x08000000 0x00100000 { ; load region size_region
ER_IROM1 0x08000000 0x00100000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
.ANY (+XO)
}
RW_IRAM1 0x20000000 0x00020000 { ; RW data
.ANY (+RW +ZI)
}
RW_IRAM2 0x10000000 0x00010000 {
.ANY (ccmram) // 括号内意思是iram2地址范围可以存储所有放在ccmram的变量
}
}
// 将IRRAM2修改为ccmram即可
// 编译后查看map文件验证即可 - 验证:
1
2
3
4
5
6// 在map文件最后一部分,看到设置的ccmram的IRAM2有自己定义的数据大小即为成功
Execution Region RW_IRAM2 (Exec base: 0x10000000, Load base: 0x08007318, Size: 0x0000c000, Max: 0x00010000, ABSOLUTE, COMPRESSED[0x00000184])
Exec Addr Load Addr Size Type Attr Idx E Section Name Object
0x10000000 COMPRESSED 0x0000c000 Data RW 17 ccmram main.o
IAR配置
- 右键项目选择“Optimal…”
- 在”Linker”栏的”Config”选项卡可以看到链接文件的配置选项
- 默认”Override default”是勾选的,不用管
- 文本编辑栏内icf文件就是该项目的内存配置文件
- 根据icf文件地址找到该文件并打开
- 使用cubemx生成的icf文件只需要在末尾添加
place in CCMRAM_region { section .ccmram };
这一句即可 - 保存文件即配置完成
- icf文件示例及说明
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36/*###ICF### Section handled by ICF editor, don't touch! ****/
/*-Editor annotation file-*/
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
/*-Specials-*/
define symbol __ICFEDIT_intvec_start__ = 0x08000000;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_ROM_start__ = 0x08000000;
define symbol __ICFEDIT_region_ROM_end__ = 0x080FFFFF;
define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
define symbol __ICFEDIT_region_RAM_end__ = 0x2001FFFF;
define symbol __ICFEDIT_region_CCMRAM_start__ = 0x10000000;
define symbol __ICFEDIT_region_CCMRAM_end__ = 0x1000FFFF;
/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 0x400;
define symbol __ICFEDIT_size_heap__ = 0x200;
/**** End of ICF editor section. ###ICF###*/
define memory mem with size = 4G;
define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
define region CCMRAM_region = mem:[from __ICFEDIT_region_CCMRAM_start__ to __ICFEDIT_region_CCMRAM_end__];
define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
initialize by copy { readwrite };
do not initialize { section .noinit };
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
place in ROM_region { readonly }; // {}表示该ROM_region可以存放{}内类型的变量代码等,可以存放指定到{}内的代码变量
place in RAM_region { readwrite,
block CSTACK, block HEAP };
place in CCMRAM_region { section .ccmram }; //(需要新加的那句话)使用方法 定义的变量后面加 @ ".ccmram"; - 配置堆栈到ccmram
1
2
3
4// 也可以修改*icf中关于堆栈的配置项目
place in CCMRAM_region { readwrite, block CSTACK, block HEAP };
// readwrite,CSTACK,HEAP都是已经定义过的宏,无需指定变量到这里
// 该配置将ccmram视为了普通ram了,若无dma参与,则无关紧要 - 配置fsmc外扩的ram
1
2
3
4//添加外置RAM到region
define region EXTRAM_region = mem:[from __ICFEDIT_region_EXTRAM_start__ to __ICFEDIT_region_EXTRAM_end__];
//定义使用标记
place in EXTRAM_region { section .extram };
更方便的使用ccmram
1 | // keil5编译器识别+iar识别+ccmram定义 |
keil 编译下载的地址和我设置的地址不一样,无法修改怎么办?
项目设置,linker界面,scatter file点击edit,对memory layout文件进行编辑,将rom地址修改为需要的地址即可。
原因:root板ram空间不够用,将64k的ccmram扩展出来,扩展ccmram需要修改memory layout文件,linker界面选择Use menory layout from target dialog是使用target配置的内存布局,否则就是使用用户编辑的那个sct,内存布局文件