一种简单的内存分配和释放方法

     在资源紧张的单片机系统中,比如几十K的flash空间,如果调用malloc,free等开发环境自带的库函数,往往会占用本来就已经不富裕的存储空间。 例如STM0XX系列单片机,flash空间只有64K, RAM为8K, 使用了malloc, free函数,编译环境为IAR8.3, 最后在map文件看到malloc,free占用将近6K大小的程序段。

    基于上述因素,在这实现了一种简单的内存分配机制。基本原理如下:

    首先开辟一段全局的数组,做为内存池。 比如2000bytes, gBuf[2000];然后定义一个内存块的大小,比如20bytes;然后定义一个内存块信息数组,每个内阻块对应一个字节,gBufInfo[2000/20];   标记原则为如果当前的内存块被占用,则在gBufInfo中写入占用的块数, 比如从0位置连续申请了3个内阻块,则gBufInfo[0]=3,gBufInfo[1]=3,gBufInfo[2]=3;

具体代码如下:

#define BUF_TOTAL_SIZE   		2000
#define BUF_SIZE   		20   // must align 4 bytes

uint8_t gBuf[BUF_TOTAL_SIZE];
uint8_t gBufInfo[BUF_TOTAL_SIZE/BUF_SIZE];

void InitBuf()
{
	memset(gBuf, 0, BUF_TOTAL_SIZE);
	memset(gBufInfo, 0, sizeof(gBufInfo));
}



void *MallocDef(unsigned short uLen)
{

	if (0 == uLen)  return NULL;
	unsigned char uNeedBufNum = ((uLen-1) / BUF_SIZE) + 1;
	unsigned char uEmptyCnt = 0;
	unsigned char uStartPos = 0;
	unsigned char uBufNum = BUF_TOTAL_SIZE / BUF_SIZE;
	for (int i=0; i<uBufNum; i++)
	{
		if (0 == gBufInfo[i])
		{
			uEmptyCnt++;
		}
		else
		{
			uEmptyCnt = 0;
		}
		if (uEmptyCnt == uNeedBufNum)
		{
			uStartPos = i+1-uNeedBufNum;

			for (int j=0; j<uNeedBufNum; j++)
			{
				gBufInfo[uStartPos+j] = uNeedBufNum;
			}
			return (void*)&gBuf[BUF_SIZE * uStartPos];
		}
	}
	return NULL;
}

void FreeDef(void *pBuf)
{
	if (NULL == pBuf) return;
	int Pos = (int)pBuf - (int)gBuf;

	Pos = Pos / BUF_SIZE;

	if (Pos >= (BUF_TOTAL_SIZE / BUF_SIZE))  return;
	
	unsigned char uUseBufNum = gBufInfo[Pos];

	for (int i=0; i<uUseBufNum; i++)
	{
		gBufInfo[Pos + i] = 0;
	}
	
}

unsigned   short CalcFreeBufNum()
{
	unsigned char uBufNum = BUF_TOTAL_SIZE / BUF_SIZE;
	unsigned char uNum = 0;
	for (int i=0; i<uBufNum; i++)
	{
		if (0 == gBufInfo[i])
		{
			uNum++;
		}
	}
	return uNum;
}

 

优点: 代码简单小巧,原理简单。

缺点:一个内阻块的空间无法百分百的利用, 比如申请5个字节内存,则同样会占用一个内阻块20字节。

        搜索空余内存块采用遍历方式,如果内存块较多则搜索时间变成长, 但对于单片机系统几百个内阻块来说,时间上

      不存在问题。

 

总结: 只选对的,不选贵的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值