内存管理实验笔记

定义内存池 ##

//内部SRAM内存池 32字节对齐 说明一次取出32字节 效率高
__align(32) u8 mem1base[MEM1_MAX_SIZE];
_**_align(32)** u8 mem2base[MEM2_MAX_SIZE] attribute((at(0X68000000)));

定义管理内存池的表

**虽然起到管理内存的作用  但是同时也带来了内存开销(浪费内存)**

u16 mem1mapbase[MEM1_ALLOC_TABLE_SIZE]; //内部SRAM内存池MAP
u16 mem2mapbase[MEM2_ALLOC_TABLE_SIZE] attribute((at(0X68000000+MEM2_MAX_SIZE))); //外部SRAM内存池MAP

//内存管理参数 //这几个数组中存放的是 内存表和内存池大小

const u32 memtblsize[SRAMBANK]={MEM1_ALLOC_TABLE_SIZE,MEM2_ALLOC_TABLE_SIZE}; //内存表大小
const u32 memblksize[SRAMBANK]={MEM1_BLOCK_SIZE,MEM2_BLOCK_SIZE}; //内存分块大小
const u32 memsize[SRAMBANK]={MEM1_MAX_SIZE,MEM2_MAX_SIZE};

//内存管理控制器 定义一个结构体

struct _m_mallco_dev
{
    void (*init)(u8);                   //**函数指针**   用于调用初始化函数
    u8 (*perused)(u8);                  //   同样是函数指针 用于调用使用率函数
    u8  *membase[SRAMBANK];     //内存池 管理SRAMBANK个区域的内存   
    u16 *memmap[SRAMBANK];              //内存管理状态表
    u8  memrdy[SRAMBANK];               //内存管理是否就绪
};

定义上述结构体的一个全局变量 并且做相应的初始化

struct _m_mallco_dev mallco_dev=
{
    my_mem_init,                //内存初始化
    my_mem_perused,             //内存使用率
    mem1base,mem2base,          //内存池
    mem1mapbase,mem2mapbase,    //内存管理状态表
    0,0,                        //内存管理未就绪   1表示就绪
};

对内存表和内存池初始化清零操作

//内存管理初始化  
//memx:所属内存块
void my_mem_init(u8 memx)  
{  
    mymemset(mallco_dev.memmap[memx], 0,memtblsize[memx]*2);//内存状态表数据清零  
    mymemset(mallco_dev.membase[memx], 0,memsize[memx]);    //内存池所有数据清零  
    mallco_dev.memrdy[memx]=1;                              //内存管理初始化OK  
}
void mymemset(void *s,u8 c,u32 count)  
{  
    u8 *xs = s;  
    while(count--)*xs++=c;  
}

内存分配函数 malloc(mem_addr,size)
malloc函数返回的是具体地址
所以必须找到连续size大小的内存 并且返回这块连续内存的首地址

怎么查找?

方法:从尾部开始查找以32字节一块为单位 一块一块的向前移动 直到找到连续的结束
所以首先将size/32+size%32 得到需要多少块
从内存管理表尾部开始找把内存管理表管理的块数给 offset偏移量 然后offset– 直到找到连续块跳出循环
找到后别忘了把管理表相应的块置1标记已经在使用

查找依据是?

管理表置0表示未使用

具体代码如下:

//内存分配(内部调用)
//memx:所属内存块
//size:要分配的内存大小(字节)
//返回值:0XFFFFFFFF,代表错误;其他,内存偏移地址 
u32 my_mem_malloc(u8 memx,u32 size)  
{  
    signed long offset=0;  
    u32 nmemb;  //需要的内存块数  
    u32 cmemb=0;//连续空内存块数
    u32 i;  
    if(!mallco_dev.memrdy[memx])mallco_dev.init(memx);//未初始化,先执行初始化 
    if(size==0)return 0XFFFFFFFF;//不需要分配
    nmemb=size/memblksize[memx];    //获取需要分配的连续内存块数
    if(size%memblksize[memx])nmemb++;  
    for(offset=memtblsize[memx]-1(其实这个就是管理的块数量);offset>=0;offset--)//搜索整个内存控制区  
    {     
        if(!mallco_dev.memmap[memx][offset])cmemb++;//连续快计数
        else cmemb=0;                               //如果中间是断开的计数清零  需要重新计数
        if(cmemb==nmemb)                            //找到了连续nmemb个空内存块
        {
            for(i=0;i<nmemb;i++)                    //标注内存块非空   别忘记标记找的块
            {  
                mallco_dev.memmap[memx][offset+i]=nmemb;  
            }  //这不是二维数组 因为memmap[memx]=数组首地址
            return (offset*memblksize[memx]);//返回偏移地址  
        }
    }  
    return 0XFFFFFFFF;//未找到符合分配条件的内存块  
}  

“`

猜你喜欢

转载自blog.csdn.net/shenlong1356/article/details/80149969
今日推荐