/** ******************************************************************************* * @file mm.c * @version V1.12 * @date 2010.03.01 * @brief memory management implementation code of CooCox CoOS kernel. ******************************************************************************* * @copy * * INTERNAL FILE,DON'T PUBLIC. * *

© COPYRIGHT 2009 CooCox

******************************************************************************* */ /*---------------------------- Include ---------------------------------------*/ #include #if CFG_MM_EN > 0 /*---------------------------- Variable Define -------------------------------*/ MM MemoryTbl[CFG_MAX_MM] = {{0}};/*!< Table which save memory control block. */ U32 MemoryIDVessel = 0; /*!< Memory ID container. */ /** ******************************************************************************* * @brief Create a memory partition * @param[in] memBuf Specify memory partition head address. * @param[in] blockSize Specify memory block size. * @param[in] blockNum Specify memory block number. * @param[out] None * @retval E_CREATE_FAIL Create memory partition fail. * @retval others Create memory partition successful. * * @par Description * @details This function is called to create a memory partition. ******************************************************************************* */ OS_MMID CoCreateMemPartition(U8* memBuf,U32 blockSize,U32 blockNum) { U8 i,j; U8 *memory; P_MemBlk memBlk; memory = memBuf; #if CFG_PAR_CHECKOUT_EN >0 /* Check validity of parameter */ if(memBuf == NULL) { return E_CREATE_FAIL; } if(blockSize == 0) { return E_CREATE_FAIL; } if((blockSize&0x3) != 0) { return E_CREATE_FAIL; } if(blockNum<=1) { return E_CREATE_FAIL; } #endif OsSchedLock(); /* Lock schedule */ for(i = 0; i < CFG_MAX_MM; i++) { if((MemoryIDVessel & (1 << i)) == 0) /* Is free memory ID? */ { MemoryIDVessel |= (1<nextBlock = (P_MemBlk)memory; memBlk = memBlk->nextBlock; } memBlk->nextBlock = NULL; return i; /* Return memory block ID */ } } OsSchedUnlock(); /* Unlock schedule */ return E_CREATE_FAIL; /* Error return */ } /** ******************************************************************************* * @brief Delete a memory partition * @param[in] mmID Specify memory partition that want to delete. * @param[out] None * @retval E_INVALID_ID The memory partition id passed was invalid,delete fail. * @retval E_OK Delete successful. * * @par Description * @details This function is called to Delete a memory partition. ******************************************************************************* */ StatusType CoDelMemoryPartition(OS_MMID mmID) { P_MM memCtl; #if CFG_PAR_CHECKOUT_EN >0 /* Check validity of parameter */ if(mmID >= CFG_MAX_MM) { return E_INVALID_ID; } if( ((1<memAddr = NULL; memCtl->freeBlock = NULL; memCtl->blockSize = 0; memCtl->blockNum = 0; return E_OK; /* Return OK */ } /** ******************************************************************************* * @brief Get free block number in a memory partition * @param[in] mmID Specify memory partition. * * @param[out] E_INVALID_ID Invalid ID was passed and get counter failure. * @param[out] E_OK Get current counter successful. * @retval fbNum The number of free block. * * @par Description * @details This function is called to get free block number in a memory * partition. ******************************************************************************* */ U32 CoGetFreeBlockNum(OS_MMID mmID,StatusType* perr) { U32 fbNum; P_MM memCtl; P_MemBlk memBlk; #if CFG_PAR_CHECKOUT_EN >0 /* Check validity of parameter */ if(mmID >= CFG_MAX_MM) { *perr = E_INVALID_ID; return 0; } if( ((1<freeBlock);/* Get the free item in memory list*/ fbNum = 0; while(memBlk != NULL) /* Get counter of free item */ { fbNum++; memBlk = memBlk->nextBlock; /* Get next free iterm */ } OsSchedUnlock(); /* Unlock schedul */ *perr = E_OK; return fbNum; /* Return the counter of free item */ } /** ******************************************************************************* * @brief Get a memory buffer from memory partition * @param[in] mmID Specify memory partition that want to assign buffer. * @param[out] None * @retval NULL Assign buffer fail. * @retval others Assign buffer successful,and return the buffer pointer. * * @par Description * @details This function is called to Delete a memory partition. ******************************************************************************* */ void* CoGetMemoryBuffer(OS_MMID mmID) { P_MM memCtl; P_MemBlk memBlk; #if CFG_PAR_CHECKOUT_EN >0 /* Check validity of parameter */ if(mmID >= CFG_MAX_MM) { return NULL; } if( ((1<freeBlock == NULL ) /* Is there no free item in memory list */ { OsSchedUnlock(); /* Unlock schedule */ return NULL; /* Yes,error return */ } memBlk = (P_MemBlk)memCtl->freeBlock; /* Get free memory block */ memCtl->freeBlock = (U8*)memBlk->nextBlock; /* Reset the first free item */ OsSchedUnlock(); /* Unlock schedule */ return memBlk; /* Return free memory block address */ } /** ******************************************************************************* * @brief Free a memory buffer to memory partition * @param[in] mmID Specify memory partition. * @param[in] buf Specify memory buffer that want to free. * @param[out] None * @retval E_INVALID_ID The memory partition id passed was invalid. * @retval E_INVALID_PARAMETER The parameter passed was invalid. * @retval E_OK Free successful. * * @par Description * @details This function is called to Delete a memory partition. ******************************************************************************* */ StatusType CoFreeMemoryBuffer(OS_MMID mmID,void* buf) { P_MM memCtl; P_MemBlk memBlk; #if CFG_PAR_CHECKOUT_EN >0 /* Check validity of parameter */ if(mmID >= CFG_MAX_MM) { return E_INVALID_ID; } if( ((1<0 /* Check validity of parameter */ if((U32)buf < (U32)(memCtl->memAddr)) { return E_INVALID_PARAMETER; } if((U32)buf > (U32)(memCtl->memAddr + memCtl->blockSize*memCtl->blockNum)) { return E_INVALID_PARAMETER; } if(((U32)buf - (U32)(memCtl->memAddr))%(memCtl->blockSize) != 0) { return E_INVALID_PARAMETER; } #endif memBlk = (P_MemBlk)buf; /* Reset the first free item */ OsSchedLock(); memBlk->nextBlock = (P_MemBlk)memCtl->freeBlock; memCtl->freeBlock = buf; OsSchedUnlock(); return E_OK; /* Return OK */ } #endif