📄 kernelheap.c
字号:
/**
*******************************************************************************
* @file kernelHeap.c
* @version V1.13
* @date 2010.04.26
* @brief kernel heap management implementation code of CooCox CoOS kernel.
*******************************************************************************
* @copy
*
* INTERNAL FILE,DON'T PUBLIC.
*
* <h2><center>© COPYRIGHT 2009 CooCox </center></h2>
*******************************************************************************
*/
/*---------------------------- Include ---------------------------------------*/
#include <coocox.h>
#if CFG_KHEAP_EN >0
/*---------------------------- Variable Define -------------------------------*/
U32 KernelHeap[KHEAP_SIZE] = {0}; /*!< Kernel heap */
P_FMB FMBlist = NULL; /*!< Free memory block list */
KHeap Kheap = {0}; /*!< Kernel heap control */
/*---------------------------- Function Declare ------------------------------*/
static P_FMB GetPreFMB(P_UMB usedMB);
/**
*******************************************************************************
* @brief Create kernel heap
* @param[in] None
* @param[out] None
* @retval None
*
* @par Description
* @details This function is called to create kernel heap.
*******************************************************************************
*/
void CoCreateKheap(void)
{
Kheap.startAddr = (U32)(KernelHeap); /* Initialize kernel heap control */
Kheap.endAddr = (U32)(KernelHeap) + KHEAP_SIZE*4;
FMBlist = (P_FMB)KernelHeap; /* Initialize free memory block list*/
FMBlist->nextFMB = NULL;
FMBlist->nextUMB = NULL;
FMBlist->preUMB = NULL;
}
/**
*******************************************************************************
* @brief Allocation size bytes of memory block from kernel heap.
* @param[in] size Length of menory block.
* @param[out] None
* @retval NULL Allocate fail.
* @retval others Pointer to memory block.
*
* @par Description
* @details This function is called to allocation size bytes of memory block.
*******************************************************************************
*/
void* CoKmalloc(U32 size)
{
P_FMB freeMB,newFMB,preFMB;
P_UMB usedMB,tmpUMB;
U8* memAddr;
U32 freeSize;
U32 kheapAddr;
#if CFG_PAR_CHECKOUT_EN >0 /* Check validity of parameter */
if( size == 0 )
{
return NULL;
}
#endif
/* Word alignment,and add used memory head size */
size = (((size+3)>>2)<<2) + 8;
kheapAddr = Kheap.endAddr; /* Get the end address of kernel heap */
OsSchedLock(); /* Lock schedule */
freeMB = FMBlist; /* Get first item of free memory list */
preFMB = NULL;
while(freeMB != NULL ) /* Is out of free memory list? */
{ /* No */
if(freeMB->nextUMB == NULL) /* Is last item of free memory list? */
{ /* Yes,get size for this free item */
freeSize = kheapAddr - (U32)(freeMB);
}
else /* No,get size for this free item */
{
freeSize = (U32)(freeMB->nextUMB) -1 - (U32)(freeMB);
}
if(freeSize >= size) /* If the size equal or greater than need */
{ /* Yes,assign in this free memory */
usedMB=(P_UMB)freeMB;/* Get the address for used memory block head*/
/* Get the address for used memory block */
memAddr = (U8*)((U32)(usedMB) + 8);
/* Is left size of free memory smaller than 12? */
if((freeSize-size) < 12)
{
/* Yes,malloc together(12 is the size of the header information
of free memory block ). */
if(preFMB != NULL)/* Is first item of free memory block list? */
{ /* No,set the link for list */
preFMB->nextFMB = freeMB->nextFMB;
}
else /* Yes,reset the first item */
{
FMBlist = freeMB->nextFMB;
}
if(freeMB->nextUMB != NULL) /* Is last item? */
{ /* No,set the link for list */
tmpUMB = (P_UMB)((U32)(freeMB->nextUMB)-1);
tmpUMB->preMB = (void*)((U32)usedMB|0x1);
}
usedMB->nextMB = freeMB->nextUMB;/* Set used memory block link*/
usedMB->preMB = freeMB->preUMB;
}
else /* No,the left size more than 12 */
{
/* Get new free memory block address */
newFMB = (P_FMB)((U32)(freeMB) + size);
if(preFMB != NULL)/* Is first item of free memory block list? */
{
preFMB->nextFMB = newFMB; /* No,set the link for list */
}
else
{
FMBlist = newFMB; /* Yes,reset the first item */
}
/* Set link for new free memory block */
newFMB->preUMB = (P_UMB)((U32)usedMB|0x1);
newFMB->nextUMB = freeMB->nextUMB;
newFMB->nextFMB = freeMB->nextFMB;
if(freeMB->nextUMB != NULL) /* Is last item? */
{ /* No,set the link for list */
tmpUMB = (P_UMB)((U32)(freeMB->nextUMB)-1);
tmpUMB->preMB = newFMB;
}
usedMB->nextMB = newFMB; /* Set used memory block link */
usedMB->preMB = freeMB->preUMB;
}
if(freeMB->preUMB != NULL) /* Is first item? */
{ /* No,set the link for list */
tmpUMB = (P_UMB)((U32)(freeMB->preUMB)-1);
tmpUMB->nextMB = (void*)((U32)usedMB|0x1);
}
OsSchedUnlock(); /* Unlock schedule */
return memAddr; /* Return used memory block address */
}
preFMB = freeMB; /* Save current free memory block as previous */
freeMB = freeMB->nextFMB; /* Get the next item as current item*/
}
OsSchedUnlock(); /* Unlock schedule */
return NULL; /* Error return */
}
/**
*******************************************************************************
* @brief Release memory block to kernel heap.
* @param[in] memBuf Pointer to memory block.
* @param[out] None
* @retval None
*
* @par Description
* @details This function is called to release memory block.
*******************************************************************************
*/
void CoKfree(void* memBuf)
{
P_FMB curFMB,nextFMB,preFMB;
P_UMB usedMB,nextUMB,preUMB;
#if CFG_PAR_CHECKOUT_EN >0 /* Check validity of parameter */
if(memBuf == NULL)
{
return;
}
#endif
usedMB = (P_UMB)((U32)(memBuf)-8);
#if CFG_PAR_CHECKOUT_EN >0 /* Check validity of parameter */
if((U32)(memBuf) < Kheap.startAddr)
{
return;
}
if((U32)(memBuf) > Kheap.endAddr)
{
return;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -