前言
看到一个简单的内存分配器, 移植过来放到自己的开发板, 想用这个主要是它比较小而且自己也容易看懂, 目前基本也够用了
基本数据结构定义
typedef unsigned int addr_t; //地址类型定义
//可用内存描述
typedef struct
{
unsigned int size;
addr_t addr;
} freeinfo_t;
//内存管理器
typedef struct {
int frees, maxfrees, lostsize, losts;
freeinfo_t *free;
} memx_t;
管理方法定义
void memx_init(memx_t *man) {
man->frees = 0; /* 剩余容量 */
man->maxfrees = 0; /* 统计:最大值 */
man->lostsize = 0; /* 释放失败的容量 */
man->losts = 0; /* 释放失败的次数*/
return;
};
unsigned int memx_total(memx_t *man) {
unsigned int i, t = 0;
for (i = 0; i < man->frees; i++) {
t += man->free[i].size;
}
return t;
};
addr_t memx_alloc(memx_t *man, unsigned int size){
unsigned int i;
addr_t a;
for (i = 0; i < man->frees; i++) {
if (man->free[i].size >= size) {
/* 有足够容量 */
a = man->free[i].addr;
man->free[i].addr += size;
man->free[i].size -= size;
if (man->free[i].size == 0) {
/* free里没有了, 那么向前移动 */
man->frees--;
for (; i < man->frees; i++) {
man->free[i] = man->free[i + 1];
}
}
return a;
}
}
return 0; /* 没了返回0 */
};
int memx_free(memx_t *man, addr_t addr, unsigned int size) {
int i, j;
/* 查找放入的位置 */
for (i = 0; i < man->frees; i++) {
if (man->free[i].addr > addr) {
break;
}
}
if (i > 0) {
/* 前面有的 */
if (man->free[i - 1].addr + man->free[i - 1].size == addr) {
/* 前面的空间可以合并 */
man->free[i - 1].size += size;
if (i < man->frees) {
/* 后面有 */
if (addr + size == man->free[i].addr) {
/* 后面的也可以合并 */
man->free[i - 1].size += man->free[i].size;
/* free[i]删除, 向前移动下 */
man->frees--;
for (; i < man->frees; i++) {
man->free[i] = man->free[i + 1];
}
}
}
return 0; /* 完成 */
}
}
/* 前面合并不了 */
if (i < man->frees) {
/* 后面有的 */
if (addr + size == man->free[i].addr) {
/* 后面可以合并 */
man->free[i].addr = addr;
man->free[i].size += size;
return 0; /* 成功 */
}
}
/* 前后都没法合并 */
if (man->frees < MEMMAN_FREES) {
/* 后面的空间移动下, 制作间隙 */
for (j = man->frees; j > i; j--) {
man->free[j] = man->free[j - 1];
}
man->frees++;
if (man->maxfrees < man->frees) {
man->maxfrees = man->frees; /* 更新最大值 */
}
man->free[i].addr = addr;
man->free[i].size = size;
return 0; /* 成功结束 */
}
/* 没有空间移动了 */
man->losts++;
man->lostsize += size;
return -1; /* 失败 */
}
定义自己包装函数库, 释放时自动处理size, 也可提高移植性
#define FREE_MAP_SIZE (MEMMAN_FREES * sizeof(freeinfo_t))
memx_t man; //静态注册内存管理器
// 初始化函数, 启动时调用
void MEM_Init() {
man.free = (freeinfo_t *)Bank1_SRAM3_ADDR; // 初始化内存起始地址
memx_init(&man); //初始化内存管理器
memx_free(&man, (addr_t)Bank1_SRAM3_ADDR + FREE_MAP_SIZE, 1024 * 1024 - FREE_MAP_SIZE); // 释放内存, 需留出开始的一段给free数组
}
// 4K对齐的内存分配
void *MEM_Malloc4k(int size) {
size = (size + 16 + 0xfff) & 0xfffff000;
char *p = (char *)memx_alloc(&man, size); //申请
if(p != 0) {
*((int *)p) = size; //保存size
p += 16;
}
return p; //返回地址
}
// 4K对齐的内存释放
void MEM_Free4k(void *p) {
char *q = p;
int size;
if (q!=0) {
q -= 16;
size = *((int *)q); //取回size
memx_free(&man, (addr_t)q, size); //释放
}
}
// 申请内存
void *MEM_Malloc(int size) {
char *p = (char *)memx_alloc(&man, size + 16);
if(p != 0) {
*((int *)p) = size;
p += 16;
}
return p;
}
// 释放内存
void MEM_Free(void *p) {
char *q = p;
int size;
if (q!=0) {
q -= 16;
size = *((int *)q);
memx_free(&man, (addr_t)q, size + 16);
}
}
// LCD 里显示剩余内存
void MEM_ShowFreeSize()
{
char free_log[12];
u32 total = memx_total(&man) / 1024;
sprintf(free_log, "free:%uK", total);
FRONT_COLOR=BLACK;
//低于300K红色
if(total < 300) {
FRONT_COLOR=RED;
}
LCD_ShowString(245,460,200,16,16, (u8 *)free_log);//显示内存容量
}