|
|
@@ -107,52 +107,54 @@ IAR 编译器在 High 优化级别下的下拉框提供了三种优化策略: |
|
|
|
|
|
|
|
#### 链接文件 |
|
|
|
|
|
|
|
(.icf链接脚本控制内存分配(Flash/ROM、RAM 布局)关键硬件相关文件) |
|
|
|
|
|
|
|
 |
|
|
|
ICF是告诉编译器:你的程序、变量、代码应该放到芯片哪一块内存里的“地图”文件。 |
|
|
|
|
|
|
|
在 `IAR` 编译环境下,`__section_start("name")` 是一个 **内置宏**,它返回指定段(section)`name` 的起始地址。通常用于获取某个内存段的起始地址,比如某个代码段、数据段、或者自己定义的特殊段。 |
|
|
|
|
|
|
|
**举例** |
|
|
|
| 功能 | ICF 术语 | |
|
|
|
| ------------- | ----------------------------------- | |
|
|
|
| 定义内存 | `define region` | |
|
|
|
| 放置代码/数据 | `place in region` | |
|
|
|
| 放中断表 | `place at start of ROM { .intvec }` | |
|
|
|
| 特殊变量段 | `.noinit` | |
|
|
|
|
|
|
|
``` |
|
|
|
extern unsigned int __section_start("MY_SECTION"); |
|
|
|
/* 定义芯片的内存结构 */ |
|
|
|
define symbol __ICFEDIT_region_ROM_start__ = 0x08000000; |
|
|
|
define symbol __ICFEDIT_region_ROM_end__ = 0x0803FFFF; |
|
|
|
|
|
|
|
void func() { |
|
|
|
unsigned int *ptr = (unsigned int *)__section_start("MY_SECTION"); |
|
|
|
// 现在 ptr 指向 MY_SECTION 段的起始地址,可以用来操作该内存区域 |
|
|
|
} |
|
|
|
``` |
|
|
|
define symbol __ICFEDIT_region_RAM_start__ = 0x20000000; |
|
|
|
define symbol __ICFEDIT_region_RAM_end__ = 0x20007FFF; |
|
|
|
|
|
|
|
这里 `__section_start("MY_SECTION")` 返回的是链接器脚本中 `MY_SECTION` 段的起始地址。 |
|
|
|
/* 创建实际使用的内存区域(ROM 和 RAM) */ |
|
|
|
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 symbol __ICFEDIT_size_cstack__ = 0x0400; /* 1KB Stack */ |
|
|
|
define symbol __ICFEDIT_size_heap__ = 0x0400; /* 1KB Heap */ |
|
|
|
|
|
|
|
/* 为 IAR 系统定义符号,用于 startup 文件 */ |
|
|
|
define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__; |
|
|
|
define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__; |
|
|
|
|
|
|
|
**IAR ICF 文件(.icf)的了解及变量如何分配内存区域** |
|
|
|
/* 开始放置内容 */ |
|
|
|
initialize by copy { readwrite }; |
|
|
|
do not initialize { section .noinit }; /* .noinit 不初始化 */ |
|
|
|
|
|
|
|
ICF(**IAR Linker Configuration File**)用于定义程序的内存布局,包括代码、数据、堆栈等在内存中的分布。 |
|
|
|
|
|
|
|
**变量分配到特定内存区域的方法**: |
|
|
|
|
|
|
|
你可以通过修改 `.icf` 文件中的 `define block` 和 `place in` 语句来控制变量在内存中的分布。 |
|
|
|
|
|
|
|
**示例(将某段变量放到特定内存区域):** |
|
|
|
|
|
|
|
``` |
|
|
|
icf复制编辑define region MY_RAM = mem:[from 0x20010000 to 0x20010FFF]; |
|
|
|
define block my_section with alignment = 8 { section .mydata }; |
|
|
|
place in MY_RAM { block my_section }; |
|
|
|
``` |
|
|
|
/* Flash(ROM)放置策略 */ |
|
|
|
place at start of ROM_region { readonly section .intvec }; /* 中断向量表 */ |
|
|
|
place in ROM_region { readonly }; /* 代码和常量 */ |
|
|
|
|
|
|
|
然后在代码中定义变量时,使用 `__attribute__((section(".mydata")))` 或 IAR 的 `__section`: |
|
|
|
/* SRAM(RAM)放置策略 */ |
|
|
|
place in RAM_region { readwrite, /* 初始化变量 */ |
|
|
|
block HEAP, /* 堆 */ |
|
|
|
block CSTACK, /* 栈 */ |
|
|
|
section .noinit }; /* 不初始化区 */ |
|
|
|
|
|
|
|
``` |
|
|
|
c |
|
|
|
|
|
|
|
(.icf链接脚本控制内存分配(Flash/ROM、RAM 布局)关键硬件相关文件) |
|
|
|
|
|
|
|
复制编辑 |
|
|
|
__no_init uint8_t my_buffer[1024] @ ".mydata"; // IAR语法 |
|
|
|
``` |
|
|
|
 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -350,6 +352,18 @@ c复制编辑void foo() { |
|
|
|
|
|
|
|
 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
 |
|
|
|
|
|
|
|
勾选 Enable stack usage analysis |
|
|
|
|
|
|
|
 |
|
|
|
|
|
|
|
打开 .map文件,搜索STACK USAGE |
|
|
|
|
|
|
|
 |
|
|
|
|
|
|
|
### 单步调试 |
|
|
|
|
|
|
|
#### 逐过程 |
|
|
|