RT-Thread 内核基础(三)

2024-01-08 12:32:54

程序内存分布

一般MCU包含的存储空间有:片内Flash与片内RAM,RAM相当于内存,Flash相当于硬盘。
编译器会将一个程序分类为好几个部分,分别存储在MCU不同的存储区。

Keil工程在编译完之后,会有相应的程序所占用的空间提示信息。

linking...
Program Size: Code=48008 RO-data=5660 RW-data=604 ZI-data=2124
After Build - User command \#1: fromelf --bin.\\build\\rtthread-stm32.axf--output rtthread.bin
".\\build\\rtthread-stm32.axf" - 0 Error(s), 0 Warning(s).
Build Time Elapsed: 00:00:07

上面提到的 Program Size 包含以下几个部分:

  1. Code:代码段,存放程序的代码部分。
  2. RO-data:只读数据段,存放程序中定义的常量。
  3. RW-data:读写数据段,存放初始化为非零值的全局变量。
  4. ZI-data:0数据段,存放未初始化的全局变量以及初始化为0的变量。

编译完工程会生成一个.map 的文件,该文件说明了各个函数占用的尺寸和地址,在文件的最后几行也说明了上面几个字段的关系:

Total RO Size (Code + RO Data) 53668 ( 52.41kB)
Total RW Size (RW Data + ZI Data) 2728 ( 2.66kB)
Total ROM Size (Code + RO Data + RW Data) 53780 ( 52.52kB)
  1. RO Size:表示程序占用Flash空间的大小。
  2. RW Size:表示运行时占用的RAM的大小。
  3. ROM Size:表示烧写程序时占用的Flash空间的大小。

程序运行之前,需要有文件实体被烧录到STM32的Flash中,一般是bin或者hex文件,该被烧录文件称为可执行映像文件。
在这里插入图片描述
如左图,是可执行映像文件烧录到STM32后的内存分布,它包含RO段和RW段两个部分:其中 RO 段中保存了 Code、RO-data 的数据,RW 段保存了 RW-data 的数据,由于ZI-data都是0,所以未包含在映像文件中。

STM32在上电启动之后,默认从Flash启动,启动之后会将RW段中的RW-data搬运到RAM中,但不会搬运RO段,即CPU的执行代码从Flash中读取,另外根据编译器给出的地址和大小分配出ZI段,并将这块RAM区域清零。

动态内存堆为未使用的RAM空间,应用程序申请和释放的内存块都来自该空间。

rt_uint8_t *msg_ptr; 
msg_ptr = (rt_uint8_t *)rt_malloc(128);
rt_memset(msg_ptr, 0, 128);

代码中的msg_ptr指针指向的128字节内存空间位于动态内存堆空间中。

而一些全局变量,则是放在RW段和ZI段中。
RW 段存放的是具有初始值的全局变量(而常量形式的全局变量则放置在 RO 段中,是只读属性的),ZI 段存放的系统未初始化的全局变量,如下面的例子:

#include <rtthread.h>

const static rt_uint32_t sensor_enable = 0x000000FE; //RO段
rt_uint32_t sensor_value; //ZI段
rt_bool_t sensor_inited = RT_FALSE; //RW段

void sensor_init()
{
     /* ... */
}

文章来源:https://blog.csdn.net/Caramel_biscuit/article/details/135452469
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。