uCMEM.c

/*
;*****************************************************************************************************
;* Copyright (c) 2006 by JiaoJinXing. 
;* All rights reserved.
;*
;*---- 文件信息 --------------------------------------------------------------------------------------
;* 文   件   名 : uCMEM.c
;* 创   建   人 : 焦进星
;* 描        述 : 内存管理文件
;*
;*---- 历史版本信息 ----------------------------------------------------------------------------------
;* 日  期  : 2009年 2 月 14 日
;* 创 人  : 风城少主
;* 描  述  : 建立版本 V1.0.0
;*---- 联系方式 --------------------------------------------------------------------------------------
;*
;* Email    : wyoujtg@163.com
;* Web    : http://user.qzone.qq.com/376637405
;*
;*****************************************************************************************************
;*/


#include "Type.h"


#include "uCOS_II.h"


#include "uCMEM.h"




FreeMem *uCMEM_FreeMem;




/*
;*****************************************************************************************************
;* 函数名称 : uCMEM_Init
;* 描    述 : 内存管理初始化
;* 输  入 : Addr: 有效的内存块的起始地址, Size: 内存块的大小
;*   
;* 输  出 : TRUE OR FALSE
;* 作 者 : 焦进星
;* 日 期 : 2009年2月10日
;*----------------------------------------------------------------------------------------------------
;* 修改备注 : 
;*****************************************************************************************************
;*/
uint8 uCMEM_Init(void *Addr, uint32 Size)
{
#if OS_CRITICAL_METHOD == 3                            /* Allocate storage for CPU status register     */
    OS_CPU_SR  cpu_sr = 0;
#endif
FreeMem *ThisFreeMem;


OS_ENTER_CRITICAL();


/* 调整内存块的大小, 使其为字的倍数 */
Size = Size & ~(sizeof(int) - 1);


if (Addr != NULL && Size > sizeof(UsingMem))
{
ThisFreeMem = (FreeMem *)Addr;


ThisFreeMem->Prev = NULL;
ThisFreeMem->Next = NULL;
ThisFreeMem->Size = Size;


uCMEM_FreeMem = ThisFreeMem;


OS_EXIT_CRITICAL();

return TRUE;
}


OS_EXIT_CRITICAL();

return FALSE;
}




/*
;*****************************************************************************************************
;* 函数名称 : uCMEM_New
;* 描    述 : 内存申请
;* 输  入 : Size: 内存块的大小
;*   
;* 输  出 : 可用的内存块的起始地址 或 NULL
;* 作 者 : 焦进星
;* 日 期 : 2009年2月10日
;*----------------------------------------------------------------------------------------------------
;* 修改备注 : 
;*****************************************************************************************************
;*/
void *uCMEM_New(uint32 Size)
{
#if OS_CRITICAL_METHOD == 3                            /* Allocate storage for CPU status register     */
    OS_CPU_SR  cpu_sr = 0;
#endif
FreeMem *ThisFreeMem;
UsingMem *Rt;




OS_ENTER_CRITICAL();

/* 调整分配的大小,按字分配,比要求的大,并加上占用内存头 */
Size = ((Size + (sizeof(int) - 1)) & ~(sizeof(int) - 1)) + sizeof(UsingMem);


/* 查找第一块足够大的空闲内存 */
ThisFreeMem = uCMEM_FreeMem;


while (ThisFreeMem != NULL)
{
if (ThisFreeMem->Size >= Size)
{
break;
}


ThisFreeMem = ThisFreeMem->Next;
}


/* 没有一块足够大的空闲内存可分配 */
if (ThisFreeMem == NULL)
{
OS_EXIT_CRITICAL();

return NULL;
}


/* 如果剩余的空间不足以形成一个空闲内存头, 则整块空闲内存分配出去 */
if (ThisFreeMem->Size < (Size + sizeof(FreeMem)))
{
/* 从双向链表删除该节点 */
if (ThisFreeMem->Prev)
{
ThisFreeMem->Prev->Next = ThisFreeMem->Next;
}


if (ThisFreeMem->Next)
{
ThisFreeMem->Next->Prev = ThisFreeMem->Prev;
}


/* 调整分配的大小 */
Size = ThisFreeMem->Size;


Rt = (UsingMem *)ThisFreeMem;
}
else
{
/* 调整未分配的大小 */
ThisFreeMem->Size -= Size;


/* 从该空闲内存块的高端分配 */
Rt = (UsingMem *)((uint8 *)ThisFreeMem + ThisFreeMem->Size);
}


/* 占用内存的大小 */
Rt->Size = Size;

OS_EXIT_CRITICAL();

/* 用户可使用的内存起始地址 */
return (uint8 *)Rt + sizeof(UsingMem);
}




/*
;*****************************************************************************************************
;* 函数名称 : uCMEM_Free
;* 描    述 : 内存释放
;* 输  入 : Addr: 已分配的内存块的起始地址
;*   
;* 输  出 : 无
;* 作 者 : 焦进星
;* 日 期 : 2009年2月10日
;*----------------------------------------------------------------------------------------------------
;* 修改备注 : 
;*****************************************************************************************************
;*/
void uCMEM_Free(void *Addr)
{
#if OS_CRITICAL_METHOD == 3                            /* Allocate storage for CPU status register     */
    OS_CPU_SR  cpu_sr = 0;
#endif
FreeMem *ThisFreeMem, *Temp;
UsingMem *ThisUsingMem;
uint32 Size;




if (Addr == NULL)
{
return ;
}


OS_ENTER_CRITICAL();

/* 计算占用内存头 */
ThisUsingMem = (UsingMem *)((uint8 *)Addr - sizeof(UsingMem));
/*
//本段程序有些BUG,会引起数据中止,需要进行处理--东狮山
while (1)
{  
if (ThisFreeMem > (FreeMem *)ThisUsingMem)
{
ThisFreeMem = ThisFreeMem->Prev;
break;
}
 
if (ThisFreeMem->Next == NULL)
{
break;
}

//RS232_Printf("IN MEM\n");//用于调试
ThisFreeMem = ThisFreeMem->Next;
}
*/
Size = ThisUsingMem->Size;


/* 如果两块内存相邻 */
if ( ((uint8 *)ThisFreeMem + ThisFreeMem->Size) == (uint8 *)ThisUsingMem )
{
/* 合并之 */
ThisFreeMem->Size += Size;


/* 有下一块 */
if (ThisFreeMem->Next)
{
/* 下一块 */
Temp = ThisFreeMem->Next;


/* 如果两块内存相邻 */
if ((uint8 *)ThisUsingMem + Size == (uint8 *)(Temp))
{
/* 合并之 */
ThisFreeMem->Next = Temp->Next;


ThisFreeMem->Size += Temp->Size;


if (Temp->Next)
{
Temp->Next->Prev = ThisFreeMem;
}
}
}
}
else
{
((FreeMem *)ThisUsingMem)->Prev = ThisFreeMem;


/* 有下一块 */
if (ThisFreeMem->Next)
{
/* 下一块 */
Temp = ThisFreeMem->Next;


ThisFreeMem->Next = (FreeMem *)ThisUsingMem;


/* 如果两块内存相邻 */
if ((uint8 *)ThisUsingMem + Size == (uint8 *)(Temp))
{
/* 合并之 */
((FreeMem *)ThisUsingMem)->Next = Temp->Next;


if (Temp->Next)
{
Temp->Next->Prev = (FreeMem *)ThisUsingMem;
}


((FreeMem *)ThisUsingMem)->Size = Size + Temp->Size;
}
else
{
/* 插入一个节点 */
((FreeMem *)ThisUsingMem)->Next = Temp;


((FreeMem *)ThisUsingMem)->Size = Size;


Temp->Prev = (FreeMem *)ThisUsingMem;
}
}
else
{
/* 插入一个节点 */
ThisFreeMem->Next = (FreeMem *)ThisUsingMem;

((FreeMem *)ThisUsingMem)->Next = NULL;


((FreeMem *)ThisUsingMem)->Size = Size;
}
}

OS_EXIT_CRITICAL();
}


/*
;*****************************************************************************************************
;* 函数名称 : GetStkSpace
;* 描    述 : 分配任务栈空间
;* 输  入 : Size: 任务栈空间的大小
;*   
;* 输  出 : 任务栈空间起始地址
;* 作 者 : 焦进星
;* 日 期 : 2009年4月26日
;*----------------------------------------------------------------------------------------------------
;* 修改备注 : 
;*****************************************************************************************************
;*/
OS_STK * GetStkSpace(uint32 size)
{
OS_STK *pStk = (OS_STK *)uCMEM_New(size*sizeof(OS_STK));

#if OS_STK_GROWTH == 1


return &pStk[size-1];

#else


return pStk;

#endif
}


/*
;*****************************************************************************************************
;* 函数名称 : FreeStkSpace
;* 描    述 : 释放任务栈空间
;* 输  入 : stk: 任务栈空间起始地址,  Size: 任务栈空间的大小
;*   
;* 输  出 : 无
;* 作 者 : 焦进星
;* 日 期 : 2009年4月26日
;*----------------------------------------------------------------------------------------------------
;* 修改备注 : 
;*****************************************************************************************************
;*/
void FreeStkSpace(OS_STK *stk, uint32 size)
{

#if OS_STK_GROWTH == 1


uCMEM_Free(stk-size+1);

#else


uCMEM_Free(stk);

#endif
}


/*
;*****************************************************************************************************
;* End of File
;*****************************************************************************************************
;*/



















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值