定义内存池 ##
//内部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;//未找到符合分配条件的内存块
}
“`