CooCox 1.1.4 on mbed with simple blinky example

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers mm.c Source File

mm.c

Go to the documentation of this file.
00001 /**
00002  *******************************************************************************
00003  * @file       mm.c
00004  * @version    V1.1.4    
00005  * @date       2011.04.20
00006  * @brief      memory management implementation code of CooCox CoOS kernel. 
00007  *******************************************************************************
00008  * @copy
00009  *
00010  * INTERNAL FILE,DON'T PUBLIC.
00011  * 
00012  * <h2><center>&copy; COPYRIGHT 2009 CooCox </center></h2>
00013  *******************************************************************************
00014  */ 
00015 
00016 
00017 /*---------------------------- Include ---------------------------------------*/
00018 #include <coocox.h>
00019 
00020 
00021 #if  CFG_MM_EN > 0
00022 /*---------------------------- Variable Define -------------------------------*/
00023 MM    MemoryTbl [CFG_MAX_MM] = {{0}};/*!< Table which save memory control block. */
00024 U32   MemoryIDVessel  = 0;         /*!< Memory ID container.                   */
00025 
00026 /**
00027  *******************************************************************************
00028  * @brief      Create a memory partition     
00029  * @param[in]  memBuf       Specify memory partition head address.       
00030  * @param[in]  blockSize    Specify memory block size.  
00031  * @param[in]  blockNum     Specify memory block number.
00032  * @param[out] None
00033  * @retval     E_CREATE_FAIL  Create memory partition fail.
00034  * @retval     others         Create memory partition successful.            
00035  *
00036  * @par Description
00037  * @details    This function is called to create a memory partition.
00038  *******************************************************************************
00039  */
00040 OS_MMID CoCreateMemPartition(U8* memBuf,U32 blockSize,U32 blockNum)
00041 {
00042     U8        i,j;
00043     U8        *memory;
00044     P_MemBlk  memBlk;
00045     memory = memBuf;
00046     
00047 #if CFG_PAR_CHECKOUT_EN >0              /* Check validity of parameter        */
00048     if(memBuf == Co_NULL)
00049     {
00050         return  E_CREATE_FAIL;
00051     }
00052     if(blockSize == 0)
00053     {
00054         return  E_CREATE_FAIL;  
00055     }
00056     if((blockSize&0x3) != 0)
00057     {
00058         return  E_CREATE_FAIL;  
00059     }
00060     if(blockNum<=1)
00061     {
00062         return  E_CREATE_FAIL;
00063     }
00064 #endif
00065 
00066     OsSchedLock();                      /* Lock schedule                      */
00067     for(i = 0; i < CFG_MAX_MM; i++)
00068     {
00069         if((MemoryIDVessel  & (1 << i)) == 0)  /* Is free memory ID?           */
00070         {
00071             MemoryIDVessel  |= (1<<i);   /* Yes,assign ID to this memory block */
00072             OsSchedUnlock();            /* Unlock schedule                    */
00073             MemoryTbl [i].memAddr   = memory;/* Initialize memory control block*/
00074             MemoryTbl [i].freeBlock = memory;    
00075             MemoryTbl [i].blockSize = blockSize;
00076             MemoryTbl [i].blockNum  = blockNum;
00077             memBlk  = (P_MemBlk)memory;     /* Bulid list in this memory block*/ 
00078             for(j=0;j<blockNum-1;j++)
00079             {
00080                 memory = memory+blockSize;
00081                 memBlk->nextBlock = (P_MemBlk)memory;
00082                 memBlk = memBlk->nextBlock;
00083             }
00084             memBlk->nextBlock = Co_NULL;
00085             return i;                   /* Return memory block ID             */
00086         }
00087     }
00088     OsSchedUnlock();                    /* Unlock schedule                    */
00089     return E_CREATE_FAIL;               /* Error return                       */
00090 }
00091 
00092 
00093 /**
00094  *******************************************************************************
00095  * @brief      Delete a memory partition      
00096  * @param[in]  mmID     Specify memory partition that want to delete.   
00097  * @param[out] None
00098  * @retval     E_INVALID_ID   The memory partition id passed was invalid,delete fail.
00099  * @retval     E_OK           Delete successful.             
00100  *
00101  * @par Description
00102  * @details    This function is called to Delete a memory partition.
00103  *******************************************************************************
00104  */
00105 StatusType CoDelMemoryPartition(OS_MMID mmID)
00106 {
00107     P_MM  memCtl;
00108 #if CFG_PAR_CHECKOUT_EN >0              /* Check validity of parameter        */
00109     if(mmID >= CFG_MAX_MM)
00110     {
00111         return E_INVALID_ID;
00112     }
00113     if( ((1<<mmID)&MemoryIDVessel ) == 0)
00114     {
00115         return E_INVALID_ID;
00116     }
00117 #endif  
00118     OsSchedLock();                      /* Lock schedule                      */
00119     memCtl = &MemoryTbl [mmID];          /* Release memory control block       */
00120     MemoryIDVessel &= ~(1<<mmID);
00121     OsSchedUnlock();                    /* Unlock schedule                    */
00122     
00123     memCtl->memAddr   = Co_NULL;
00124     memCtl->freeBlock = Co_NULL;
00125     memCtl->blockSize = 0;
00126     memCtl->blockNum  = 0;  
00127     return E_OK;                        /* Return OK                          */
00128 }
00129 
00130 
00131 /**
00132  *******************************************************************************
00133  * @brief      Get free block number in a memory partition    
00134  * @param[in]  mmID    Specify memory partition.    
00135  *
00136  * @param[out] E_INVALID_ID  Invalid ID was passed and get counter failure.   
00137  * @param[out] E_OK          Get current counter successful.
00138  * @retval     fbNum         The number of free block.  
00139  *
00140  * @par Description
00141  * @details    This function is called to get free block number in a memory 
00142  *             partition.
00143  *******************************************************************************
00144  */
00145 U32 CoGetFreeBlockNum(OS_MMID mmID,StatusType* perr)
00146 {
00147     U32       fbNum;    
00148     P_MM      memCtl;
00149     P_MemBlk  memBlk;
00150 #if CFG_PAR_CHECKOUT_EN >0              /* Check validity of parameter        */
00151     if(mmID >= CFG_MAX_MM)
00152     {
00153         *perr = E_INVALID_ID;
00154         return 0;
00155     }
00156     if( ((1<<mmID)&MemoryIDVessel ) == 0)
00157     {
00158         *perr = E_INVALID_ID;           /* Invalid memory id,return 0         */
00159         return 0;
00160     }
00161 #endif  
00162     memCtl = &MemoryTbl [mmID];
00163     OsSchedLock();                      /* Lock schedule                      */
00164     memBlk = (P_MemBlk)(memCtl->freeBlock);/* Get the free item in memory list*/
00165     fbNum  = 0;
00166     while(memBlk != Co_NULL)               /* Get counter of free item           */
00167     {
00168         fbNum++;
00169         memBlk = memBlk->nextBlock;     /* Get next free iterm                */
00170     }
00171     OsSchedUnlock();                    /* Unlock schedul                     */
00172     *perr = E_OK;                              
00173     return fbNum;                       /* Return the counter of free item    */
00174 }
00175 
00176 
00177 /**
00178  *******************************************************************************
00179  * @brief      Get a memory buffer from memory partition        
00180  * @param[in]  mmID     Specify memory partition that want to assign buffer.    
00181  * @param[out] None
00182  * @retval     Co_NULL     Assign buffer fail.
00183  * @retval     others   Assign buffer successful,and return the buffer pointer. 
00184  *       
00185  * @par Description
00186  * @details    This function is called to Delete a memory partition.
00187  *******************************************************************************
00188  */
00189 void* CoGetMemoryBuffer(OS_MMID mmID)
00190 {
00191     P_MM      memCtl;
00192     P_MemBlk  memBlk;
00193 #if CFG_PAR_CHECKOUT_EN >0              /* Check validity of parameter        */
00194     if(mmID >= CFG_MAX_MM)
00195     {
00196         return Co_NULL;
00197     }
00198     if( ((1<<mmID)&MemoryIDVessel )  == 0)
00199     {
00200         return Co_NULL;
00201     }
00202 #endif
00203     memCtl = &MemoryTbl [mmID];  
00204     OsSchedLock();                      /* Lock schedule                      */            
00205     if(memCtl->freeBlock == Co_NULL )    /* Is there no free item in memory list */
00206     {
00207         OsSchedUnlock();                /* Unlock schedule                    */
00208         return Co_NULL;                    /* Yes,error return                   */
00209     }
00210     memBlk = (P_MemBlk)memCtl->freeBlock;       /* Get free memory block      */
00211     memCtl->freeBlock = (U8*)memBlk->nextBlock; /* Reset the first free item  */
00212     OsSchedUnlock();                    /* Unlock schedule                    */
00213     return memBlk;                      /* Return free memory block address   */
00214 }
00215 
00216 
00217 
00218 /**
00219  *******************************************************************************
00220  * @brief      Free a memory buffer to memory partition  
00221  * @param[in]  mmID    Specify  memory partition.
00222  * @param[in]  buf     Specify  memory buffer that want to free.    
00223  * @param[out] None
00224  * @retval     E_INVALID_ID          The memory partition id passed was invalid.
00225  * @retval     E_INVALID_PARAMETER   The parameter passed was invalid.  
00226  * @retval     E_OK                  Free successful.    
00227  *
00228  * @par Description
00229  * @details    This function is called to Delete a memory partition.
00230  *******************************************************************************
00231  */
00232 StatusType CoFreeMemoryBuffer(OS_MMID mmID,void* buf)
00233 {
00234     P_MM      memCtl;
00235     P_MemBlk  memBlk;
00236 #if CFG_PAR_CHECKOUT_EN >0              /* Check validity of parameter        */
00237     if(mmID >= CFG_MAX_MM)
00238     {
00239         return E_INVALID_ID;
00240     }
00241     if( ((1<<mmID)&MemoryIDVessel ) == 0)
00242     {
00243         return E_INVALID_ID;
00244     }
00245     if(buf == Co_NULL)
00246     {
00247         return E_INVALID_PARAMETER;
00248     }
00249 #endif  
00250 
00251     memCtl = &MemoryTbl [mmID];
00252 #if CFG_PAR_CHECKOUT_EN >0              /* Check validity of parameter        */
00253     if((U32)buf < (U32)(memCtl->memAddr))
00254     {
00255         return E_INVALID_PARAMETER;
00256     }
00257     if((U32)buf > (U32)(memCtl->memAddr + memCtl->blockSize*memCtl->blockNum))
00258     {
00259         return E_INVALID_PARAMETER;
00260     }
00261     if(((U32)buf - (U32)(memCtl->memAddr))%(memCtl->blockSize) != 0)
00262     {   
00263         return E_INVALID_PARAMETER; 
00264     }
00265 #endif
00266     memBlk = (P_MemBlk)buf;             /* Reset the first free item          */
00267     OsSchedLock();
00268     memBlk->nextBlock = (P_MemBlk)memCtl->freeBlock;
00269     memCtl->freeBlock = buf;
00270     OsSchedUnlock();
00271     return E_OK;                        /* Return OK                          */
00272 }
00273 
00274 #endif
00275