STM32的程序和数据存储分布
存储域 | 意义 | 存储介质 |
---|---|---|
Code | 代码域 | ROM |
RO-data | 只读数据域 | ROM |
RW-data | 可读可写数据域,指初始化为非0值的可读写数据 | 不运行的时候ROM;运行的时候RAM |
ZI-data | 可读可写数据域,指初始化为0值的可读写数据 | RAM |
ZI-data的Stack | 栈:存储局部变量 | ZI-data的栈空间 |
ZI-data的Heap | Heap:使用malloc动态分配的空间 | ZI-data的堆空间 |
程序状态与区域 | 组成 |
---|---|
程序存储需要占用的ROM区 | Code + RO-data + RW-data |
程序执行需要占用的RAM区 | ZI-data + RW-data |
程序执行需要占用的ROM区 | Code + RO-data |
查看工程文件所需要的的ROM和RAM
.map
文件
STM32的ROM内存分布
.map
文件中搜索Load Region LR_IROM1
,即可查看ROM1
中的内存分布情况
存储域 | 意义 |
---|---|
向量表 | 中断向量表 |
Code | 代码 |
RO-data | 只读数据域 |
RW-data | 存储可读可写数据域,指初始化为非0值的可读写数据的数据 |
向量表的分布
打开文件startup_stm32f429_439xx.s
,该文件中有详细的向量表分布情况
类型 | 意义 |
---|---|
__initial_sp | 栈顶地址 |
Reset_Handler | 复位向量地址,也就是函数入口地址 |
NMI_Handler | |
NMI_Handler | |
HardFault_Handler | |
省略 |
Keil5生成的Bin/Hex文件分析
生成的Hex中应要有向量表
Code
RO-data
RW-data
存储域 | 意义 |
---|---|
向量表 | 中断向量表 |
Code | 代码 |
RO-data | 只读数据域 |
RW-data | 存储可读可写数据域,指初始化为非0值的可读写数据的数据 |
- 向量表
图中蓝色选中的区域为向量表
- Code
由于Code过多,这里仅展示部分Code
- RO-data
在main.c中定义一个常量,并在main()
使用它
const char str[] = "Hello Wolrd!";
int main(void)
{
char *p = str;
}
查看.map
文件,如下
在Hex文件中找到该地址0x0800373c
4. RW-data
在main.c定义两个全局变量
uint16_t tempData1 = 0x1234;
uint16_t tempData2 = 0x5678;
在Hex文件中找数据34 12
或者78 56
(先存的是低字节的数据)
STM32的RAM内存分布
.map
文件中搜索Execution Region RW_IRAM1
,即可查看RAM1
中的内存分布情况
存储域 | 意义 | 备注 |
---|---|---|
RW-data | 可读可写数据域,指初始化为非0值的可读写数据 | RW-data的数据存在ROM中,数据存放的地址见Load Addr |
ZI-data | 可读可写数据域,指初始化为0值的可读写数据 | |
堆 | ||
栈 |
查看栈顶和栈底地址
.map
中搜索STACK
为栈底地址
.map
中搜索__initial_sp
为栈底地址
查看堆顶和堆底地址
.map
中搜索Heap
为堆底地址
.map
中搜索STACK
为堆顶地址,也可以自己计算堆顶地址
常用操作
Keil5生成二进制文件
fromelf --bin -o "$L@L.bin" "#L"
查看最大堆栈使用情况
打开工程输出的.html
文件