CoOS Demonstrator adapted to mbed Hardware.

Dependencies:   mbed

Committer:
ericebert
Date:
Fri Dec 03 19:45:30 2010 +0000
Revision:
0:57690853989a
Some basic LED-Flashing works in the CoOS-RTOS using Tasks

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ericebert 0:57690853989a 1 /**
ericebert 0:57690853989a 2 *******************************************************************************
ericebert 0:57690853989a 3 * @file mm.c
ericebert 0:57690853989a 4 * @version V1.1.3
ericebert 0:57690853989a 5 * @date 2010.04.26
ericebert 0:57690853989a 6 * @brief memory management implementation code of CooCox CoOS kernel.
ericebert 0:57690853989a 7 *******************************************************************************
ericebert 0:57690853989a 8 * @copy
ericebert 0:57690853989a 9 *
ericebert 0:57690853989a 10 * INTERNAL FILE,DON'T PUBLIC.
ericebert 0:57690853989a 11 *
ericebert 0:57690853989a 12 * <h2><center>&copy; COPYRIGHT 2009 CooCox </center></h2>
ericebert 0:57690853989a 13 *******************************************************************************
ericebert 0:57690853989a 14 */
ericebert 0:57690853989a 15
ericebert 0:57690853989a 16
ericebert 0:57690853989a 17 /*---------------------------- Include ---------------------------------------*/
ericebert 0:57690853989a 18 #include <coocox.h>
ericebert 0:57690853989a 19
ericebert 0:57690853989a 20
ericebert 0:57690853989a 21 #if CFG_MM_EN > 0
ericebert 0:57690853989a 22 /*---------------------------- Variable Define -------------------------------*/
ericebert 0:57690853989a 23 MM MemoryTbl[CFG_MAX_MM] = {{0}};/*!< Table which save memory control block. */
ericebert 0:57690853989a 24 U32 MemoryIDVessel = 0; /*!< Memory ID container. */
ericebert 0:57690853989a 25
ericebert 0:57690853989a 26 /**
ericebert 0:57690853989a 27 *******************************************************************************
ericebert 0:57690853989a 28 * @brief Create a memory partition
ericebert 0:57690853989a 29 * @param[in] memBuf Specify memory partition head address.
ericebert 0:57690853989a 30 * @param[in] blockSize Specify memory block size.
ericebert 0:57690853989a 31 * @param[in] blockNum Specify memory block number.
ericebert 0:57690853989a 32 * @param[out] None
ericebert 0:57690853989a 33 * @retval E_CREATE_FAIL Create memory partition fail.
ericebert 0:57690853989a 34 * @retval others Create memory partition successful.
ericebert 0:57690853989a 35 *
ericebert 0:57690853989a 36 * @par Description
ericebert 0:57690853989a 37 * @details This function is called to create a memory partition.
ericebert 0:57690853989a 38 *******************************************************************************
ericebert 0:57690853989a 39 */
ericebert 0:57690853989a 40 OS_MMID CoCreateMemPartition(U8* memBuf,U32 blockSize,U32 blockNum)
ericebert 0:57690853989a 41 {
ericebert 0:57690853989a 42 U8 i,j;
ericebert 0:57690853989a 43 U8 *memory;
ericebert 0:57690853989a 44 P_MemBlk memBlk;
ericebert 0:57690853989a 45 memory = memBuf;
ericebert 0:57690853989a 46
ericebert 0:57690853989a 47 #if CFG_PAR_CHECKOUT_EN >0 /* Check validity of parameter */
ericebert 0:57690853989a 48 if(memBuf == 0)
ericebert 0:57690853989a 49 {
ericebert 0:57690853989a 50 return E_CREATE_FAIL;
ericebert 0:57690853989a 51 }
ericebert 0:57690853989a 52 if(blockSize == 0)
ericebert 0:57690853989a 53 {
ericebert 0:57690853989a 54 return E_CREATE_FAIL;
ericebert 0:57690853989a 55 }
ericebert 0:57690853989a 56 if((blockSize&0x3) != 0)
ericebert 0:57690853989a 57 {
ericebert 0:57690853989a 58 return E_CREATE_FAIL;
ericebert 0:57690853989a 59 }
ericebert 0:57690853989a 60 if(blockNum<=1)
ericebert 0:57690853989a 61 {
ericebert 0:57690853989a 62 return E_CREATE_FAIL;
ericebert 0:57690853989a 63 }
ericebert 0:57690853989a 64 #endif
ericebert 0:57690853989a 65
ericebert 0:57690853989a 66 OsSchedLock(); /* Lock schedule */
ericebert 0:57690853989a 67 for(i = 0; i < CFG_MAX_MM; i++)
ericebert 0:57690853989a 68 {
ericebert 0:57690853989a 69 if((MemoryIDVessel & (1 << i)) == 0) /* Is free memory ID? */
ericebert 0:57690853989a 70 {
ericebert 0:57690853989a 71 MemoryIDVessel |= (1<<i); /* Yes,assign ID to this memory block */
ericebert 0:57690853989a 72 OsSchedUnlock(); /* Unlock schedule */
ericebert 0:57690853989a 73 MemoryTbl[i].memAddr = memory;/* Initialize memory control block*/
ericebert 0:57690853989a 74 MemoryTbl[i].freeBlock = memory;
ericebert 0:57690853989a 75 MemoryTbl[i].blockSize = blockSize;
ericebert 0:57690853989a 76 MemoryTbl[i].blockNum = blockNum;
ericebert 0:57690853989a 77 memBlk = (P_MemBlk)memory; /* Bulid list in this memory block*/
ericebert 0:57690853989a 78 for(j=0;j<blockNum-1;j++)
ericebert 0:57690853989a 79 {
ericebert 0:57690853989a 80 memory = memory+blockSize;
ericebert 0:57690853989a 81 memBlk->nextBlock = (P_MemBlk)memory;
ericebert 0:57690853989a 82 memBlk = memBlk->nextBlock;
ericebert 0:57690853989a 83 }
ericebert 0:57690853989a 84 memBlk->nextBlock = 0;
ericebert 0:57690853989a 85 return i; /* Return memory block ID */
ericebert 0:57690853989a 86 }
ericebert 0:57690853989a 87 }
ericebert 0:57690853989a 88 OsSchedUnlock(); /* Unlock schedule */
ericebert 0:57690853989a 89 return E_CREATE_FAIL; /* Error return */
ericebert 0:57690853989a 90 }
ericebert 0:57690853989a 91
ericebert 0:57690853989a 92
ericebert 0:57690853989a 93 /**
ericebert 0:57690853989a 94 *******************************************************************************
ericebert 0:57690853989a 95 * @brief Delete a memory partition
ericebert 0:57690853989a 96 * @param[in] mmID Specify memory partition that want to delete.
ericebert 0:57690853989a 97 * @param[out] None
ericebert 0:57690853989a 98 * @retval E_INVALID_ID The memory partition id passed was invalid,delete fail.
ericebert 0:57690853989a 99 * @retval E_OK Delete successful.
ericebert 0:57690853989a 100 *
ericebert 0:57690853989a 101 * @par Description
ericebert 0:57690853989a 102 * @details This function is called to Delete a memory partition.
ericebert 0:57690853989a 103 *******************************************************************************
ericebert 0:57690853989a 104 */
ericebert 0:57690853989a 105 StatusType CoDelMemoryPartition(OS_MMID mmID)
ericebert 0:57690853989a 106 {
ericebert 0:57690853989a 107 P_MM memCtl;
ericebert 0:57690853989a 108 #if CFG_PAR_CHECKOUT_EN >0 /* Check validity of parameter */
ericebert 0:57690853989a 109 if(mmID >= CFG_MAX_MM)
ericebert 0:57690853989a 110 {
ericebert 0:57690853989a 111 return E_INVALID_ID;
ericebert 0:57690853989a 112 }
ericebert 0:57690853989a 113 if( ((1<<mmID)&MemoryIDVessel) == 0)
ericebert 0:57690853989a 114 {
ericebert 0:57690853989a 115 return E_INVALID_ID;
ericebert 0:57690853989a 116 }
ericebert 0:57690853989a 117 #endif
ericebert 0:57690853989a 118 OsSchedLock(); /* Lock schedule */
ericebert 0:57690853989a 119 memCtl = &MemoryTbl[mmID]; /* Release memory control block */
ericebert 0:57690853989a 120 MemoryIDVessel &= ~(1<<mmID);
ericebert 0:57690853989a 121 OsSchedUnlock(); /* Unlock schedule */
ericebert 0:57690853989a 122
ericebert 0:57690853989a 123 memCtl->memAddr = 0;
ericebert 0:57690853989a 124 memCtl->freeBlock = 0;
ericebert 0:57690853989a 125 memCtl->blockSize = 0;
ericebert 0:57690853989a 126 memCtl->blockNum = 0;
ericebert 0:57690853989a 127 return E_OK; /* Return OK */
ericebert 0:57690853989a 128 }
ericebert 0:57690853989a 129
ericebert 0:57690853989a 130
ericebert 0:57690853989a 131 /**
ericebert 0:57690853989a 132 *******************************************************************************
ericebert 0:57690853989a 133 * @brief Get free block number in a memory partition
ericebert 0:57690853989a 134 * @param[in] mmID Specify memory partition.
ericebert 0:57690853989a 135 *
ericebert 0:57690853989a 136 * @param[out] E_INVALID_ID Invalid ID was passed and get counter failure.
ericebert 0:57690853989a 137 * @param[out] E_OK Get current counter successful.
ericebert 0:57690853989a 138 * @retval fbNum The number of free block.
ericebert 0:57690853989a 139 *
ericebert 0:57690853989a 140 * @par Description
ericebert 0:57690853989a 141 * @details This function is called to get free block number in a memory
ericebert 0:57690853989a 142 * partition.
ericebert 0:57690853989a 143 *******************************************************************************
ericebert 0:57690853989a 144 */
ericebert 0:57690853989a 145 U32 CoGetFreeBlockNum(OS_MMID mmID,StatusType* perr)
ericebert 0:57690853989a 146 {
ericebert 0:57690853989a 147 U32 fbNum;
ericebert 0:57690853989a 148 P_MM memCtl;
ericebert 0:57690853989a 149 P_MemBlk memBlk;
ericebert 0:57690853989a 150 #if CFG_PAR_CHECKOUT_EN >0 /* Check validity of parameter */
ericebert 0:57690853989a 151 if(mmID >= CFG_MAX_MM)
ericebert 0:57690853989a 152 {
ericebert 0:57690853989a 153 *perr = E_INVALID_ID;
ericebert 0:57690853989a 154 return 0;
ericebert 0:57690853989a 155 }
ericebert 0:57690853989a 156 if( ((1<<mmID)&MemoryIDVessel) == 0)
ericebert 0:57690853989a 157 {
ericebert 0:57690853989a 158 *perr = E_INVALID_ID; /* Invalid memory id,return 0 */
ericebert 0:57690853989a 159 return 0;
ericebert 0:57690853989a 160 }
ericebert 0:57690853989a 161 #endif
ericebert 0:57690853989a 162 memCtl = &MemoryTbl[mmID];
ericebert 0:57690853989a 163 OsSchedLock(); /* Lock schedule */
ericebert 0:57690853989a 164 memBlk = (P_MemBlk)(memCtl->freeBlock);/* Get the free item in memory list*/
ericebert 0:57690853989a 165 fbNum = 0;
ericebert 0:57690853989a 166 while(memBlk != 0) /* Get counter of free item */
ericebert 0:57690853989a 167 {
ericebert 0:57690853989a 168 fbNum++;
ericebert 0:57690853989a 169 memBlk = memBlk->nextBlock; /* Get next free iterm */
ericebert 0:57690853989a 170 }
ericebert 0:57690853989a 171 OsSchedUnlock(); /* Unlock schedul */
ericebert 0:57690853989a 172 *perr = E_OK;
ericebert 0:57690853989a 173 return fbNum; /* Return the counter of free item */
ericebert 0:57690853989a 174 }
ericebert 0:57690853989a 175
ericebert 0:57690853989a 176
ericebert 0:57690853989a 177 /**
ericebert 0:57690853989a 178 *******************************************************************************
ericebert 0:57690853989a 179 * @brief Get a memory buffer from memory partition
ericebert 0:57690853989a 180 * @param[in] mmID Specify memory partition that want to assign buffer.
ericebert 0:57690853989a 181 * @param[out] None
ericebert 0:57690853989a 182 * @retval 0 Assign buffer fail.
ericebert 0:57690853989a 183 * @retval others Assign buffer successful,and return the buffer pointer.
ericebert 0:57690853989a 184 *
ericebert 0:57690853989a 185 * @par Description
ericebert 0:57690853989a 186 * @details This function is called to Delete a memory partition.
ericebert 0:57690853989a 187 *******************************************************************************
ericebert 0:57690853989a 188 */
ericebert 0:57690853989a 189 void* CoGetMemoryBuffer(OS_MMID mmID)
ericebert 0:57690853989a 190 {
ericebert 0:57690853989a 191 P_MM memCtl;
ericebert 0:57690853989a 192 P_MemBlk memBlk;
ericebert 0:57690853989a 193 #if CFG_PAR_CHECKOUT_EN >0 /* Check validity of parameter */
ericebert 0:57690853989a 194 if(mmID >= CFG_MAX_MM)
ericebert 0:57690853989a 195 {
ericebert 0:57690853989a 196 return 0;
ericebert 0:57690853989a 197 }
ericebert 0:57690853989a 198 if( ((1<<mmID)&MemoryIDVessel) == 0)
ericebert 0:57690853989a 199 {
ericebert 0:57690853989a 200 return 0;
ericebert 0:57690853989a 201 }
ericebert 0:57690853989a 202 #endif
ericebert 0:57690853989a 203 memCtl = &MemoryTbl[mmID];
ericebert 0:57690853989a 204 OsSchedLock(); /* Lock schedule */
ericebert 0:57690853989a 205 if(memCtl->freeBlock == 0 ) /* Is there no free item in memory list */
ericebert 0:57690853989a 206 {
ericebert 0:57690853989a 207 OsSchedUnlock(); /* Unlock schedule */
ericebert 0:57690853989a 208 return 0; /* Yes,error return */
ericebert 0:57690853989a 209 }
ericebert 0:57690853989a 210 memBlk = (P_MemBlk)memCtl->freeBlock; /* Get free memory block */
ericebert 0:57690853989a 211 memCtl->freeBlock = (U8*)memBlk->nextBlock; /* Reset the first free item */
ericebert 0:57690853989a 212 OsSchedUnlock(); /* Unlock schedule */
ericebert 0:57690853989a 213 return memBlk; /* Return free memory block address */
ericebert 0:57690853989a 214 }
ericebert 0:57690853989a 215
ericebert 0:57690853989a 216
ericebert 0:57690853989a 217
ericebert 0:57690853989a 218 /**
ericebert 0:57690853989a 219 *******************************************************************************
ericebert 0:57690853989a 220 * @brief Free a memory buffer to memory partition
ericebert 0:57690853989a 221 * @param[in] mmID Specify memory partition.
ericebert 0:57690853989a 222 * @param[in] buf Specify memory buffer that want to free.
ericebert 0:57690853989a 223 * @param[out] None
ericebert 0:57690853989a 224 * @retval E_INVALID_ID The memory partition id passed was invalid.
ericebert 0:57690853989a 225 * @retval E_INVALID_PARAMETER The parameter passed was invalid.
ericebert 0:57690853989a 226 * @retval E_OK Free successful.
ericebert 0:57690853989a 227 *
ericebert 0:57690853989a 228 * @par Description
ericebert 0:57690853989a 229 * @details This function is called to Delete a memory partition.
ericebert 0:57690853989a 230 *******************************************************************************
ericebert 0:57690853989a 231 */
ericebert 0:57690853989a 232 StatusType CoFreeMemoryBuffer(OS_MMID mmID,void* buf)
ericebert 0:57690853989a 233 {
ericebert 0:57690853989a 234 P_MM memCtl;
ericebert 0:57690853989a 235 P_MemBlk memBlk;
ericebert 0:57690853989a 236 #if CFG_PAR_CHECKOUT_EN >0 /* Check validity of parameter */
ericebert 0:57690853989a 237 if(mmID >= CFG_MAX_MM)
ericebert 0:57690853989a 238 {
ericebert 0:57690853989a 239 return E_INVALID_ID;
ericebert 0:57690853989a 240 }
ericebert 0:57690853989a 241 if( ((1<<mmID)&MemoryIDVessel) == 0)
ericebert 0:57690853989a 242 {
ericebert 0:57690853989a 243 return E_INVALID_ID;
ericebert 0:57690853989a 244 }
ericebert 0:57690853989a 245 if(buf == 0)
ericebert 0:57690853989a 246 {
ericebert 0:57690853989a 247 return E_INVALID_PARAMETER;
ericebert 0:57690853989a 248 }
ericebert 0:57690853989a 249 #endif
ericebert 0:57690853989a 250
ericebert 0:57690853989a 251 memCtl = &MemoryTbl[mmID];
ericebert 0:57690853989a 252 #if CFG_PAR_CHECKOUT_EN >0 /* Check validity of parameter */
ericebert 0:57690853989a 253 if((U32)buf < (U32)(memCtl->memAddr))
ericebert 0:57690853989a 254 {
ericebert 0:57690853989a 255 return E_INVALID_PARAMETER;
ericebert 0:57690853989a 256 }
ericebert 0:57690853989a 257 if((U32)buf > (U32)(memCtl->memAddr + memCtl->blockSize*memCtl->blockNum))
ericebert 0:57690853989a 258 {
ericebert 0:57690853989a 259 return E_INVALID_PARAMETER;
ericebert 0:57690853989a 260 }
ericebert 0:57690853989a 261 if(((U32)buf - (U32)(memCtl->memAddr))%(memCtl->blockSize) != 0)
ericebert 0:57690853989a 262 {
ericebert 0:57690853989a 263 return E_INVALID_PARAMETER;
ericebert 0:57690853989a 264 }
ericebert 0:57690853989a 265 #endif
ericebert 0:57690853989a 266 memBlk = (P_MemBlk)buf; /* Reset the first free item */
ericebert 0:57690853989a 267 OsSchedLock();
ericebert 0:57690853989a 268 memBlk->nextBlock = (P_MemBlk)memCtl->freeBlock;
ericebert 0:57690853989a 269 memCtl->freeBlock = (U8 *) buf;
ericebert 0:57690853989a 270 OsSchedUnlock();
ericebert 0:57690853989a 271 return E_OK; /* Return OK */
ericebert 0:57690853989a 272 }
ericebert 0:57690853989a 273
ericebert 0:57690853989a 274 #endif
ericebert 0:57690853989a 275