关于os中内存管理在stm32中应用的梳理

关于os中内存管理在stm32中应用的梳理_第1张图片

这是stm32f407中内存的地址以及大小,地址是从0x20000000开始到0x20020000结束,共128K,这是程序以及os malloc所公用大小,多有程序的运行就都是在这里进行的。
关于os中内存管理在stm32中应用的梳理_第2张图片
这是stm32f407启动文件中关于堆栈的分配,有图可知栈stack 大小为1024字节,堆heap大小为512字节。这里分配的堆和栈有什么用呢,以前一直没有搞明白。
栈区:有编译器自动分配以及释放,用于存储函数中定义的局部变量、函数参数、函数返回值、返回地址、中断时的cpu寄存器中数值等,最简易但不太确切的说法就是,栈区存放的就是过程中数据。分配和释放由编译器自动分配和释放。
堆区:主要是用于malloc,由程序员来指定分配与释放,当你在程序中调用系统的malloc和free时,使用的就是heap的512字节数据。
如果规定内存中地址增大的方向为向上,0x20000000->0x20000001向上增长,那么栈地址是向下增长,堆地址是向上增长。
在mdk编译完成后会看到如下:
这里写图片描述
MDK下Code,RO-data,RW-data,ZI-data这几个段:
Code是存储程序代码的。
​RO-data是存储const常量和指令。
​RW-data是存储初始化值不为0的全局变量。
​ZI-data是存储未初始化的全局变量或初始化值为0的全局变量。
Flash=Code + RO Data + RW Data;
RAM= RW-data+ZI-data;

由以上我们知道,实际上我们用到的我们想自己来分配的空间的首地址是0x20000000+HEAP+Stack+RW-data+ZI-data。也就是说我们自定的管理内存的首地址不能是0x20000000;

嵌入式系统的堆栈,不管是用什么方法来得到内存,感觉他的方式都和编程中的堆差不多。目前我知道两种获得内存情况:

(1)用庞大的全局变量数组来圈住一块内存,然后将这个内存拿来进行内存管理和分配。这种情况下,堆栈占用的内存就是上面说的:如果没有初始化数组,或者数组的初始化值为0,堆栈就是占用的RAM的ZI-data部分;如果数组初始化值不为0,堆栈就占用的RAM的RW-data部分。这种方式的好处是容易从逻辑上知道数据的来由和去向。freeRTOS默认用的就是这种方式。当然也可通过自定义设置为方式2;

(2)​就是把编译器没有用掉的RAM部分拿来做内存分配,也就是除掉RW-data+ZI-data+编译器堆+编译器栈后剩下的RAM内存中的一部分或者全部进行内存管理和分配。这样的情况下就只需要知道内存剩下部分的首地址和内存的尾地址,然后要用多少内存,就用首地址开始挖,做一个链表,把内存获取和释放相关信息链接起来,就能及时的对内存进行管理了。内存管理的算法多种多样,不详说,这样的情况下:OS的内存分配和自身局部变量或者全局变量不冲突,之前我就在这上面纠结了很久,以为函数里面的变量也是从系统的动态内存中得来的。这种方式感觉更加能够明白自己地址的开始和结束;
在rtthread中定义的

#define STM32_SRAM_BEGIN    (&Image$$RW_IRAM1$$ZI$$Limit)

实际上就是将rt_malloc的首地址指定到0x20000000+HEAP+Stack+RW-data+ZI-data。把系统分配完成之后的剩余内存空间管理起来。

你可能感兴趣的:(freeRTOS)