⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 kernelheap.c

📁 基于MDK的LPC1100处理器开发应用例程
💻 C
📖 第 1 页 / 共 2 页
字号:
/**
 *******************************************************************************
 * @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>&copy; 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 + -