基于stm32的内存管理(X)

一、简介

1. 功能

内存管理,是指软件运行时对计算机内存资源的分配和使用的技术。其最主要的目的是如何高效,快速的分配,并且在适当的时候释放和回收内存资源。

2. 概念

内存管理的实现方法有很多种,他们其实最终都是要实现 2 个函数: malloc  free。

malloc 函数用于内存申请。

free 函数用于内存释放。 

从上图可以看出,分块式内存管理由内存池和内存管理表两部分组成。内存池被等分为 n块,对应的内存管理表,大小也为 n,内存管理表的每一个项对应内存池的一块内存。
内存管理表的项值代表的意义为:当该项值为 0 的时候,代表对应的内存块未被占用,当该项值非零的时候,代表该项对应的内存块已经被占用,其数值则代表被连续占用的内存块数。比如某项值为 10,那么说明包括本项对应的内存块在内,总共分配了 10 个内存块给外部的某个指针。
内存分配方向如图所示,是从顶->底的分配方向。即首先从最末端开始找空内存。当内存管理刚初始化的时候,内存表全部清零,表示没有任何内存块被占用。

三、分配原理

当指针 p 调用 malloc 申请内存的时候,先判断 p 要分配的内存块数(m),然后从第 n 项开 始,向下查找,直到找到 m 块连续的空内存块(即对应内存管理表项为 0),然后将这 m 个内存管理表项的值都设置为 m(标记被占用),最后,把最后的这个空内存块的地址返回指针 p完成一次分配。注意,如果当内存不够的时候(找到最后也没找到连续的 m 块空闲内存),则
返回 NULL  p,表示分配失败。

四、释放原理

 p 申请的内存用完,需要释放的时候,调用 free 函数实现。 free 函数先判断 p 指向的内存地址所对应的内存块,然后找到对应的内存管理表项目,得到 p 所占用的内存块数目 m(内存管理表项目的值就是所分配内存块的数目),将这 m 个内存管理表项目的值都清零,标记释放,完成一次内存释放。 

五、重要参数

内存的大小 =  内存池大小 + 内存管理表的大小

内存块(32个字节)\times  分割块( N ) = 内存池容量(字节)

( 内存管理表所占字节(U16 : 2个字节) \times 分割块(N)) =  内存管理表容量(字节)

一般情况下,内存块 和 内存池容量的值是知道的,是程序员根据硬件容量指定的。这里我们指定内存块为32字节,内存池容量为40K。

所以 分割块(N)=   内存池容量(字节) \div 内存块(32个字节)= 40K \div 32 = 40 \times 1024 \div32 = 1280。

那 内存管理表容量(字节) =  2 \times 分割块(N)= 2 \times (内存池容量(字节) \div 内存块(32个字节)) = 2 \times 1280 = 2560。

定义两个内存,一个是内部内存(40K),一个是外部内存SRAM(960K).

内存管理参数:

内存池总大小:40K
内存管理状态表大小:1280 (U16) 数据块个数N
内存分块大小:32 字节


内存池总大小:960K
内存管理状态表大小:30720(U16) 数据块个数N
内存分块大小:32 字节


定义结构体:
struct _m_mallco_dev
{
    u8  *membase[2]; //2个内存池 内部内存和外部内存的内存池
    u16 *memmap[2];  //2个内存管理状态表 
    u8  memrdy[2];      //内存初始化标志
}
定义数组:
内存池:
__align(32) u8 mem1base[40960];  //40K   内存容量(字节) 32个字节一个块,块对齐
__align(32) u8 mem2base[983040] __attribute__((at(0x68000000))); //960K  内存容量(字节)

内存管理状态表:
u16 mem1mapbase[1280];      //内存表大小  40K / 32
u16 mem2mapbase[30720];     //内存表大小  960K / 32


定义的结构体指向定义的数组。
struct _m_mallco_dev mallco_dev=
{
    mem1base,mem1base,
    mem1mapbase,mem1mapbase,
    0,0,
}

五、分配内存流程

1. 根据传进来的SIZE,确认需要分配几块内存块。比如说需要M块。

2. 在内存中,查找连续空闲的M块内存块,如果连续的空闲块不够M块,则向下一部分连续的空间进行查找。如果连续的空闲块个数有M块,则将这M块的内存管理状态表写上M,表示连续的M块内存,被使用了。

六、释放内存流程

1.   根据传进来的偏移量offset , 算出属于第几项L,然后读出L项的内存管理状态表的值R。

2.  将L项往后的L个内存管理状态值改为0。

发布了105 篇原创文章 · 获赞 30 · 访问量 16万+

猜你喜欢

转载自blog.csdn.net/happygrilclh/article/details/102686173
今日推荐