/*
;*****************************************************************************************************
;* 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
;*****************************************************************************************************
;*/
;*****************************************************************************************************
;* 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
;*****************************************************************************************************
;*/