您的位置:首页 > 其它

单片机上内存管理(重定义malloc & free)de实现

2017-08-25 16:36 459 查看
   在单片机上经常会需要用到像标准c库中的内存分配,可是单片机并没有内存管理机制,如果直接调用库函数(malloc,free...),会导致内存碎片越用越多,很容易使系统崩溃掉,这里分享一个自己写的适用于单片机的内存分配方法,具备轻量级的内存管理能力,有效减少内存碎片,提高单片机系统工作稳定性。

   如下图,heap_start开始的地方,是我们存放用户数据的地方,在heap_end之前都是大小固定的一个个内存管理块,内存管理块用于记录每次用户申请内存的地址、大小、释放情况。在malloc时,会优先选择和用户申请空间最相当的内存块,以减少内存碎片产生。在free的内存块时,如果遇到相邻内存块均为空闲块时,便会将几块相邻的内存块合并成一块,以减少内存碎片。



alloc.c

#include <string.h>
#define ALLOC_SIZE    0x8000	//32k
unsigned  char 	      mem_alloc[ALLOC_SIZE];

#define HEAP_START	 &mem_alloc[0]
#define HEAP_END	 &mem_alloc[0x7fff]

typedef enum
{
UNUSED = 0,
USED,
}USED_STATUS;

typedef struct MENAGE_BLOCK
{
unsigned long *ptr;
unsigned int size_t;
USED_STATUS sta;
}menage_block;

static unsigned int	 block_num = 0;

void alloc_init(void)
{
menage_block   			*main_uint;

main_uint 					= (menage_block *)(HEAP_END - sizeof(menage_block));
main_uint->ptr   	 	= (unsigned long *)HEAP_START;
main_uint->size_t 	=  ALLOC_SIZE - sizeof(menage_block);
main_uint->sta      =  UNUSED;
block_num 					=  1;
}

void *malloc(unsigned int num_bytes)
{
unsigned int i,suitable,suit_size=0xffffffff;
menage_block     		*uint;
if(num_bytes <= 0)
{
return NULL;
}
uint 	=  (menage_block *)(HEAP_END - block_num*sizeof(menage_block));
for(i=0;i<block_num;i++)
{
if((uint[i].sta == UNUSED)&&(uint[i].size_t>=num_bytes))
{
if(uint[i].size_t < suit_size)
{
suitable  = i;
suit_size = uint[i].size_t;
}
}
}
if(suit_size == 0xffffffff)
{
return NULL;
}
if(uint[suitable].size_t > num_bytes)
{
block_num += 1;
memcpy(uint-sizeof(menage_block),uint,suitable*sizeof(menage_block));
uint[suitable-1].ptr    = (unsigned long *)((unsigned int)uint[suitable].ptr + num_bytes);
uint[suitable-1].size_t = uint[suitable].size_t - num_bytes;
uint[suitable-1].sta    = UNUSED;

uint[suitable].sta		 = USED;
uint[suitable].size_t  = num_bytes;
return (void *)uint[suitable].ptr;
}
else if(uint[suitable].size_t == num_bytes)
{
uint[suitable].sta = USED;
return (void *)uint[suitable].ptr;
}
else
{
return NULL;
}
}

void free (void *ptr)
{
unsigned int i,j,status=0;
menage_block    *uint;
uint 		= (menage_block *)(HEAP_END - block_num*sizeof(menage_block));
for(i=0;i<block_num;i++)
{
if(ptr == uint[i].ptr)
{
status = 1;
uint[i].sta = UNUSED;
}
}
if(status == 0)
{
return ;
}
for(i=0;i<(block_num-2);i++)
{
if(uint[i].sta == UNUSED&&uint[i+1].sta == UNUSED&&uint[i+2].sta==UNUSED&&block_num>=3)
{
uint[i+2].size_t = uint[i].size_t + uint[i+1].size_t + uint[i+2].size_t;
for(j=i;j>0;j--)
{
uint[j+1].ptr 	 = uint[j-1].ptr;
uint[j+1].size_t = uint[j-1].size_t;
uint[j+1].sta		 = uint[j-1].sta;
}
block_num -= 2;
break;
}
}
for(i=0;i<(block_num-1);i++)
{
if(uint[i].sta == UNUSED&&uint[i+1].sta == UNUSED&&block_num>=2)
{
uint[i+1].size_t = uint[i].size_t + uint[i+1].size_t;
for(j=i;j>0;j--)
{
uint[j].ptr 	 = uint[j-1].ptr;
uint[j].size_t = uint[j-1].size_t;
uint[j].sta		 = uint[j-1].sta;
}
block_num -= 1;
break;
}
}
}
alloc.h

#ifndef __ALLOC_H__
#define __ALLOC_H__
#include "global.h"

void alloc_init(void);
void *malloc(unsigned int num_bytes);
void free (void *ptr);

#endif
用法:void mem_test(void)
{
unsigned int i;
unsigned int *m1;

alloc_init();//内存分配初始化
m1 = malloc(100);//申请100字节空间
if(m1 != NULL)
{
memset(m1,0xff,100);//使用此空间




}
free(m1);//释放此空间
}


                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐