[mw_shl_code=c,true]//内存池(4字节对齐)
__align(4) u8 mem1base[MEM1_MAX_SIZE];//内部SRAM内存池一共有这么多的内存可以分配
__align(4) u8 mem2base[MEM2_MAX_SIZE] __attribute__((at(0X68000000))); //外部SRAM内存池[/mw_shl_code]
[mw_shl_code=c,true]#define MEM1_BLOCK_SIZE 32 //内存块大小为32字节
#define MEM1_MAX_SIZE 40*1024 //最大管理内存 40K
#define MEM1_ALLOC_TABLE_SIZE MEM1_MAX_SIZE/MEM1_BLOCK_SIZE //内存表大小
//mem2内存参数设定.mem2的内存池处于外部SRAM里面,其他的处于内部SRAM里面
#define MEM2_BLOCK_SIZE 32 //内存块大小为32字节
#define MEM2_MAX_SIZE 680*1024 //最大管理内存200K
#define MEM2_ALLOC_TABLE_SIZE MEM2_MAX_SIZE/MEM2_BLOCK_SIZE //内存表大小
//内存管理表
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[2]={MEM1_ALLOC_TABLE_SIZE,MEM2_ALLOC_TABLE_SIZE}; //内存表大小
const u32 memblksize[2]={MEM1_BLOCK_SIZE,MEM2_BLOCK_SIZE}; //内存分块大小
const u32 memsize[2]={MEM1_MAX_SIZE,MEM2_MAX_SIZE}; //内存总大小
struct _m_mallco_dev
{
void (*init)(u8); //初始化
u8 (*perused)(u8); //内存使用率
u8 *membase[2]; //内存池 管理2个区域的内存
u16 *memmap[2]; //内存管理状态表
u8 memrdy[2]; //内存管理是否就绪
};
//内存管理控制器
struct _m_mallco_dev mallco_dev=
{
mem_init, //内存初始化
mem_perused, //内存使用率
mem1base,mem2base, //内存池
mem1mapbase,mem2mapbase,//内存管理状态表是一个指针数组
0,0, //内存管理未就绪
};
u32 mem_malloc(u8 memx,u32 size)
{
signed long offset=0;
u16 nmemb; //需要的内存块数
u16 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--)//搜索整个内存控制区 看看有多少个为0连续块啊
{
if(!mallco_dev.memmap[memx][offset])cmemb++;//如果有内存块为0连续空内存块数增加
else cmemb=0; //连续内存块清零
if(cmemb==nmemb) //找到了连续nmemb个空内存块
{
for(i=0;i<nmemb;i++) //标注内存块非空
{
mallco_dev.memmap[memx][offset+i]=nmemb;
}
return (offset*memblksize[memx]);//返回偏移地址
}
}
return 0XFFFFFFFF;//未找到符合分配条件的内存块
} [/mw_shl_code]
1, 内存管理表和真正的内存池是怎么对应起来的。
我看函数里只有内存管理表指针数组
u16 *memmap[2]; //内存管理状态表
还有内存池
u8 *membase[2]; //内存池 管理2个区域的内存
我知道这两个是32倍的关系,下面的这个语句
[mw_shl_code=c,true] mallco_dev.memmap[memx][offset+i]=nmemb; [/mw_shl_code]
我知道前面这句话虽然是操作内存管理状态表,但实际上是要操作内存池就是*membase[2],
这两个之间是怎么联系起来的呢
2在堆区返回偏移地址就能得到绝对地址吗?
在堆区申请变量时地址由编译器自动分配啊,怎么函数最后返回了一个偏移地址呢,偏移地址就能代替要申请变量的地址吗?
[mw_shl_code=c,true] return (offset*memblksize[memx]);//返回偏移地址 [/mw_shl_code]
|