一般 MCU 包含的存储空间有:片内 Flash 与片内 RAM,RAM 相当于内存,Flash 相当于硬盘。编译器会将一个程序分类为好几个部分,分别存储在 MCU 不同的存储区。 Keil 工程在编译完之后,会有相应的程序所占用的空间提示信息,如下所示:
上面提到的 Program Size 包含以下几个部分: 1)Code: 代码段,存放程序的代码部分 2)RO-data:只读数据段, 存放程序中定义的常量; 3)RW-data: 读写数据段,存放初始化为非0值的全局变量 4)ZI-data: 零数据段,存放未初始化的全局变量及初始化为0的变量; 编译完工程会生成一个. map 的文件,该文件说明了各个函数占用的尺寸和地址,在文件的最后几行也说明了上面几个字段的关系:
1) RO Size 包含了 Code 及 RO-data,表示程序占用Flash空间的大小 2)RW Size 包含了RW-data及ZI-data,表示运行时占用的RAM的大小 3)ROM Size 包含了Code, RO Data以及RW Data, 表示烧写程序所占用的Flash空间的大小 程序运行之前,需要有文件实体被烧录到 STM32 的 Flash 中,一般是 bin 或者 hex 文件,该被烧录文件称为可执行映像文件。如图 3-3 中左图所示,是可执行映像文件烧录到 STM32 后的内存分布,它包含 RO 段和 RW 段两个部分:其中 RO 段中保存了 Code、RO-data 的数据,RW 段保存了 RW-data 的数据,由于 ZI-data 都是 0,所以未包含在映像文件中。 STM32 在上电启动之后默认从 Flash 启动,启动之后会将 RW 段中的 RW-data(初始化的全局变量)搬运到 RAM 中,但不会搬运 RO 段,即 CPU 的执行代码从 Flash 中读取,另外根据编译器给出的 ZI 地址和大小分配出 ZI 段,并将这块 RAM 区域清零
! G/ m3 K' t: h) M: K2 d7 l | 其中动态内存堆为未使用的 RAM 空间,应用程序申请和释放的内存块都来自该空间。 如下面的例子:
代码中的 msg_ptr 指针指向的 128 字节内存空间位于动态内存堆空间中。 而一些全局变量则是存放于 RW 段和 ZI 段中,RW 段存放的是具有初始值的全局变量(而常量形式的全局变量则放置在 RO 段中,是只读属性的),ZI 段存放的系统未初始化的全局变量,如下面的例子:
sensor_value 存放在 ZI 段中,系统启动后会自动初始化成零(由用户程序或编译器提供的一些库函数初始化成零)。sensor_inited 变量则存放在 RW 段中,而 sensor_enable 存放在 RO 段中。 |
X-NUCLEO-IKS4A1实现手势滑动
STM32G系列RS485自动收发控制以及自适应波特率实战
STM32G0系列ADC扫描序列模式解读
STM32固件库分享,超全系列整理
【经验分享】FPGA作为从机与STM32进行SPI协议通信---Verilog实现
【管管推荐】STM32经验分享篇
STM32G030F6P6基于HAL库模拟SPI驱动1.8寸TFT LCD屏幕
STM32的CAN FD位定时设置注意事项
基于STM32将移植 SBSFU 到 STM32G070过程分享
基于STM32G030 RAM不够用经验分享