Quick and dirty CoOS + LWIP ( Webserver )

Dependencies:   mbed lwip

Committer:
astroboy
Date:
Sat Sep 10 22:41:10 2011 +0000
Revision:
0:94897d537b31

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
astroboy 0:94897d537b31 1 /**
astroboy 0:94897d537b31 2 *******************************************************************************
astroboy 0:94897d537b31 3 * @file mutex.c
astroboy 0:94897d537b31 4 * @version V1.1.4
astroboy 0:94897d537b31 5 * @date 2011.04.20
astroboy 0:94897d537b31 6 * @brief Mutex management implementation code of CooCox CoOS kernel.
astroboy 0:94897d537b31 7 *******************************************************************************
astroboy 0:94897d537b31 8 * @copy
astroboy 0:94897d537b31 9 *
astroboy 0:94897d537b31 10 * INTERNAL FILE,DON'T PUBLIC.
astroboy 0:94897d537b31 11 *
astroboy 0:94897d537b31 12 * <h2><center>&copy; COPYRIGHT 2009 CooCox </center></h2>
astroboy 0:94897d537b31 13 *******************************************************************************
astroboy 0:94897d537b31 14 */
astroboy 0:94897d537b31 15
astroboy 0:94897d537b31 16
astroboy 0:94897d537b31 17
astroboy 0:94897d537b31 18 /*---------------------------- Include ---------------------------------------*/
astroboy 0:94897d537b31 19 #include <coocox.h>
astroboy 0:94897d537b31 20
astroboy 0:94897d537b31 21
astroboy 0:94897d537b31 22 /*---------------------------- Variable Define -------------------------------*/
astroboy 0:94897d537b31 23 #if CFG_MUTEX_EN > 0
astroboy 0:94897d537b31 24
astroboy 0:94897d537b31 25 OS_MutexID MutexFreeID = 0; /*!< Point to next vliad mutex ID. */
astroboy 0:94897d537b31 26 MUTEX MutexTbl[CFG_MAX_MUTEX] = {{0}}; /*!< Mutex struct array */
astroboy 0:94897d537b31 27
astroboy 0:94897d537b31 28
astroboy 0:94897d537b31 29
astroboy 0:94897d537b31 30 /**
astroboy 0:94897d537b31 31 *******************************************************************************
astroboy 0:94897d537b31 32 * @brief Create a mutex
astroboy 0:94897d537b31 33 * @param[in] None
astroboy 0:94897d537b31 34 * @param[out] None
astroboy 0:94897d537b31 35 * @retval E_CREATE_FAIL Create mutex fail.
astroboy 0:94897d537b31 36 * @retval others Create mutex successful.
astroboy 0:94897d537b31 37 *
astroboy 0:94897d537b31 38 * @par Description
astroboy 0:94897d537b31 39 * @details This function is called to create a mutex.
astroboy 0:94897d537b31 40 * @note
astroboy 0:94897d537b31 41 *******************************************************************************
astroboy 0:94897d537b31 42 */
astroboy 0:94897d537b31 43 OS_MutexID CoCreateMutex(void)
astroboy 0:94897d537b31 44 {
astroboy 0:94897d537b31 45 OS_MutexID id;
astroboy 0:94897d537b31 46 P_MUTEX pMutex;
astroboy 0:94897d537b31 47 OsSchedLock();
astroboy 0:94897d537b31 48
astroboy 0:94897d537b31 49 /* Assign a free mutex control block */
astroboy 0:94897d537b31 50 if(MutexFreeID < CFG_MAX_MUTEX )
astroboy 0:94897d537b31 51 {
astroboy 0:94897d537b31 52 id = MutexFreeID++;
astroboy 0:94897d537b31 53 OsSchedUnlock();
astroboy 0:94897d537b31 54 pMutex = &MutexTbl[id];
astroboy 0:94897d537b31 55 pMutex->hipriTaskID = INVALID_ID;
astroboy 0:94897d537b31 56 pMutex->originalPrio = 0xff;
astroboy 0:94897d537b31 57 pMutex->mutexFlag = MUTEX_FREE; /* Mutex is free,not was occupied */
astroboy 0:94897d537b31 58 pMutex->taskID = INVALID_ID;
astroboy 0:94897d537b31 59 pMutex->waittingList = 0;
astroboy 0:94897d537b31 60 return id; /* Return mutex ID */
astroboy 0:94897d537b31 61 }
astroboy 0:94897d537b31 62
astroboy 0:94897d537b31 63 OsSchedUnlock();
astroboy 0:94897d537b31 64 return E_CREATE_FAIL; /* No free mutex control block */
astroboy 0:94897d537b31 65 }
astroboy 0:94897d537b31 66
astroboy 0:94897d537b31 67
astroboy 0:94897d537b31 68
astroboy 0:94897d537b31 69 /**
astroboy 0:94897d537b31 70 *******************************************************************************
astroboy 0:94897d537b31 71 * @brief Enter a critical area
astroboy 0:94897d537b31 72 * @param[in] mutexID Specify mutex.
astroboy 0:94897d537b31 73 * @param[out] None
astroboy 0:94897d537b31 74 * @retval E_INVALID_ID Invalid mutex id.
astroboy 0:94897d537b31 75 * @retval E_CALL Error call in ISR.
astroboy 0:94897d537b31 76 * @retval E_OK Enter critical area successful.
astroboy 0:94897d537b31 77 *
astroboy 0:94897d537b31 78 * @par Description
astroboy 0:94897d537b31 79 * @details This function is called when entering a critical area.
astroboy 0:94897d537b31 80 * @note
astroboy 0:94897d537b31 81 *******************************************************************************
astroboy 0:94897d537b31 82 */
astroboy 0:94897d537b31 83 StatusType CoEnterMutexSection(OS_MutexID mutexID)
astroboy 0:94897d537b31 84 {
astroboy 0:94897d537b31 85 P_OSTCB ptcb,pCurTcb;
astroboy 0:94897d537b31 86 P_MUTEX pMutex;
astroboy 0:94897d537b31 87
astroboy 0:94897d537b31 88 #if CFG_EVENT_EN >0
astroboy 0:94897d537b31 89 P_ECB pecb;
astroboy 0:94897d537b31 90 #endif
astroboy 0:94897d537b31 91
astroboy 0:94897d537b31 92 if(OSIntNesting > 0) /* If the caller is ISR */
astroboy 0:94897d537b31 93 {
astroboy 0:94897d537b31 94 return E_CALL;
astroboy 0:94897d537b31 95 }
astroboy 0:94897d537b31 96 if(OSSchedLock != 0) /* Is OS lock? */
astroboy 0:94897d537b31 97 {
astroboy 0:94897d537b31 98 return E_OS_IN_LOCK; /* Yes,error return */
astroboy 0:94897d537b31 99 }
astroboy 0:94897d537b31 100
astroboy 0:94897d537b31 101 #if CFG_PAR_CHECKOUT_EN >0
astroboy 0:94897d537b31 102 if(mutexID >= MutexFreeID) /* Invalid 'mutexID' */
astroboy 0:94897d537b31 103 {
astroboy 0:94897d537b31 104 return E_INVALID_ID;
astroboy 0:94897d537b31 105 }
astroboy 0:94897d537b31 106 #endif
astroboy 0:94897d537b31 107
astroboy 0:94897d537b31 108 OsSchedLock();
astroboy 0:94897d537b31 109 pCurTcb = TCBRunning;
astroboy 0:94897d537b31 110 pMutex = &MutexTbl[mutexID];
astroboy 0:94897d537b31 111
astroboy 0:94897d537b31 112 pCurTcb->mutexID = mutexID;
astroboy 0:94897d537b31 113 if(pMutex->mutexFlag == MUTEX_FREE) /* If mutex is available */
astroboy 0:94897d537b31 114 {
astroboy 0:94897d537b31 115 pMutex->originalPrio = pCurTcb->prio; /* Save priority of owning task */
astroboy 0:94897d537b31 116 pMutex->taskID = pCurTcb->taskID; /* Acquire the resource */
astroboy 0:94897d537b31 117 pMutex->hipriTaskID = pCurTcb->taskID;
astroboy 0:94897d537b31 118 pMutex->mutexFlag = MUTEX_OCCUPY; /* Occupy the mutex resource*/
astroboy 0:94897d537b31 119 }
astroboy 0:94897d537b31 120 /* If the mutex resource had been occupied */
astroboy 0:94897d537b31 121 else if(pMutex->mutexFlag == MUTEX_OCCUPY)
astroboy 0:94897d537b31 122 {
astroboy 0:94897d537b31 123 ptcb = &TCBTbl[pMutex->taskID];
astroboy 0:94897d537b31 124 if(ptcb->prio > pCurTcb->prio) /* Need to promote priority of owner? */
astroboy 0:94897d537b31 125 {
astroboy 0:94897d537b31 126 #if CFG_ORDER_LIST_SCHEDULE_EN ==0
astroboy 0:94897d537b31 127 DeleteTaskPri(ptcb->prio);
astroboy 0:94897d537b31 128 ActiveTaskPri(pCurTcb->prio);
astroboy 0:94897d537b31 129 #endif
astroboy 0:94897d537b31 130 ptcb->prio = pCurTcb->prio; /* Promote prio of owner */
astroboy 0:94897d537b31 131
astroboy 0:94897d537b31 132 /* Upgarde the highest priority about the mutex */
astroboy 0:94897d537b31 133 pMutex->hipriTaskID = pCurTcb->taskID;
astroboy 0:94897d537b31 134 if(ptcb->state == TASK_READY) /* If the task is ready to run */
astroboy 0:94897d537b31 135 {
astroboy 0:94897d537b31 136 RemoveFromTCBRdyList(ptcb); /* Remove the task from READY list*/
astroboy 0:94897d537b31 137 InsertToTCBRdyList(ptcb); /* Insert the task into READY list*/
astroboy 0:94897d537b31 138 }
astroboy 0:94897d537b31 139 #if CFG_EVENT_EN >0
astroboy 0:94897d537b31 140 /* If the task is waiting on a event */
astroboy 0:94897d537b31 141 else if(ptcb->eventID != INVALID_ID)
astroboy 0:94897d537b31 142 {
astroboy 0:94897d537b31 143 pecb = &EventTbl[ptcb->eventID];
astroboy 0:94897d537b31 144
astroboy 0:94897d537b31 145 /* If the event waiting type is preemptive Priority */
astroboy 0:94897d537b31 146 if(pecb->eventSortType == EVENT_SORT_TYPE_PRIO)
astroboy 0:94897d537b31 147 {
astroboy 0:94897d537b31 148 /* Remove the task from event waiting list */
astroboy 0:94897d537b31 149 RemoveEventWaittingList(ptcb);
astroboy 0:94897d537b31 150
astroboy 0:94897d537b31 151 /* Insert the task into event waiting list */
astroboy 0:94897d537b31 152 EventTaskToWait(pecb,ptcb);
astroboy 0:94897d537b31 153 }
astroboy 0:94897d537b31 154 }
astroboy 0:94897d537b31 155 #endif
astroboy 0:94897d537b31 156 }
astroboy 0:94897d537b31 157
astroboy 0:94897d537b31 158 pCurTcb->state = TASK_WAITING; /* Block current task */
astroboy 0:94897d537b31 159 TaskSchedReq = Co_TRUE;
astroboy 0:94897d537b31 160 pCurTcb->TCBnext = 0;
astroboy 0:94897d537b31 161 pCurTcb->TCBprev = 0;
astroboy 0:94897d537b31 162
astroboy 0:94897d537b31 163 ptcb = pMutex->waittingList;
astroboy 0:94897d537b31 164 if(ptcb == 0) /* If the event waiting list is empty */
astroboy 0:94897d537b31 165 {
astroboy 0:94897d537b31 166 pMutex->waittingList = pCurTcb; /* Insert the task to head */
astroboy 0:94897d537b31 167 }
astroboy 0:94897d537b31 168 else /* If the event waiting list is not empty */
astroboy 0:94897d537b31 169 {
astroboy 0:94897d537b31 170 while(ptcb->TCBnext != 0) /* Insert the task to tail */
astroboy 0:94897d537b31 171 {
astroboy 0:94897d537b31 172 ptcb = ptcb->TCBnext;
astroboy 0:94897d537b31 173 }
astroboy 0:94897d537b31 174 ptcb->TCBnext = pCurTcb;
astroboy 0:94897d537b31 175 pCurTcb->TCBprev = ptcb;
astroboy 0:94897d537b31 176 pCurTcb->TCBnext = 0;
astroboy 0:94897d537b31 177 }
astroboy 0:94897d537b31 178 }
astroboy 0:94897d537b31 179 OsSchedUnlock();
astroboy 0:94897d537b31 180 return E_OK;
astroboy 0:94897d537b31 181 }
astroboy 0:94897d537b31 182
astroboy 0:94897d537b31 183
astroboy 0:94897d537b31 184 /**
astroboy 0:94897d537b31 185 *******************************************************************************
astroboy 0:94897d537b31 186 * @brief Leave from a critical area
astroboy 0:94897d537b31 187 * @param[in] mutexID Specify mutex id.
astroboy 0:94897d537b31 188 * @param[out] None
astroboy 0:94897d537b31 189 * @retval E_INVALID_ID Invalid mutex id.
astroboy 0:94897d537b31 190 * @retval E_CALL Error call in ISR.
astroboy 0:94897d537b31 191 * @retval E_OK Exit a critical area successful.
astroboy 0:94897d537b31 192 *
astroboy 0:94897d537b31 193 * @par Description
astroboy 0:94897d537b31 194 * @details This function must be called when exiting from a critical area.
astroboy 0:94897d537b31 195 * @note
astroboy 0:94897d537b31 196 *******************************************************************************
astroboy 0:94897d537b31 197 */
astroboy 0:94897d537b31 198 StatusType CoLeaveMutexSection(OS_MutexID mutexID)
astroboy 0:94897d537b31 199 {
astroboy 0:94897d537b31 200 P_OSTCB ptcb;
astroboy 0:94897d537b31 201 P_MUTEX pMutex;
astroboy 0:94897d537b31 202 U8 prio;
astroboy 0:94897d537b31 203 U8 taskID;
astroboy 0:94897d537b31 204
astroboy 0:94897d537b31 205 if(OSIntNesting > 0) /* If the caller is ISR */
astroboy 0:94897d537b31 206 {
astroboy 0:94897d537b31 207 return E_CALL;
astroboy 0:94897d537b31 208 }
astroboy 0:94897d537b31 209
astroboy 0:94897d537b31 210 #if CFG_PAR_CHECKOUT_EN >0
astroboy 0:94897d537b31 211 if(mutexID >= MutexFreeID)
astroboy 0:94897d537b31 212 {
astroboy 0:94897d537b31 213 return E_INVALID_ID; /* Invalid mutex id, return error */
astroboy 0:94897d537b31 214 }
astroboy 0:94897d537b31 215 #endif
astroboy 0:94897d537b31 216 OsSchedLock();
astroboy 0:94897d537b31 217 pMutex = &MutexTbl[mutexID]; /* Obtain point of mutex control block*/
astroboy 0:94897d537b31 218 ptcb = &TCBTbl[pMutex->taskID];
astroboy 0:94897d537b31 219 ptcb->mutexID = INVALID_ID;
astroboy 0:94897d537b31 220 if(pMutex->waittingList == 0) /* If the mutex waiting list is empty */
astroboy 0:94897d537b31 221 {
astroboy 0:94897d537b31 222 pMutex->mutexFlag = MUTEX_FREE; /* The mutex resource is available */
astroboy 0:94897d537b31 223 pMutex->taskID = INVALID_ID;
astroboy 0:94897d537b31 224 OsSchedUnlock();
astroboy 0:94897d537b31 225 }
astroboy 0:94897d537b31 226 else /* If there is at least one task waitting for the mutex */
astroboy 0:94897d537b31 227 {
astroboy 0:94897d537b31 228 taskID = pMutex->taskID; /* Get task ID of mutex owner */
astroboy 0:94897d537b31 229
astroboy 0:94897d537b31 230 /* we havn't promoted current task's priority */
astroboy 0:94897d537b31 231 if(pMutex->hipriTaskID == taskID)
astroboy 0:94897d537b31 232 {
astroboy 0:94897d537b31 233 ptcb = pMutex->waittingList;/* Point to mutex first waiting task */
astroboy 0:94897d537b31 234 prio = ptcb->prio;
astroboy 0:94897d537b31 235 while(ptcb != 0) /* Find the highest priority task */
astroboy 0:94897d537b31 236 {
astroboy 0:94897d537b31 237 if(ptcb->prio < prio)
astroboy 0:94897d537b31 238 {
astroboy 0:94897d537b31 239 prio = ptcb->prio;
astroboy 0:94897d537b31 240 pMutex->hipriTaskID = ptcb->taskID;
astroboy 0:94897d537b31 241 }
astroboy 0:94897d537b31 242 ptcb = ptcb->TCBnext;
astroboy 0:94897d537b31 243 }
astroboy 0:94897d537b31 244 }
astroboy 0:94897d537b31 245 else /* we have promoted current task's priority */
astroboy 0:94897d537b31 246 {
astroboy 0:94897d537b31 247 prio = TCBTbl[taskID].prio;
astroboy 0:94897d537b31 248 }
astroboy 0:94897d537b31 249
astroboy 0:94897d537b31 250 /* Reset the task priority */
astroboy 0:94897d537b31 251 pMutex->taskID = INVALID_ID;
astroboy 0:94897d537b31 252 CoSetPriority(taskID,pMutex->originalPrio);
astroboy 0:94897d537b31 253
astroboy 0:94897d537b31 254 /* Find first task in waiting list ready to run */
astroboy 0:94897d537b31 255 ptcb = pMutex->waittingList;
astroboy 0:94897d537b31 256 pMutex->waittingList = ptcb->TCBnext;
astroboy 0:94897d537b31 257 pMutex->originalPrio = ptcb->prio;
astroboy 0:94897d537b31 258 pMutex->taskID = ptcb->taskID;
astroboy 0:94897d537b31 259
astroboy 0:94897d537b31 260 #if CFG_ORDER_LIST_SCHEDULE_EN ==0
astroboy 0:94897d537b31 261 if(prio != ptcb->prio)
astroboy 0:94897d537b31 262 {
astroboy 0:94897d537b31 263 DeleteTaskPri(ptcb->prio);
astroboy 0:94897d537b31 264 ActiveTaskPri(prio);
astroboy 0:94897d537b31 265 }
astroboy 0:94897d537b31 266 #endif
astroboy 0:94897d537b31 267
astroboy 0:94897d537b31 268 ptcb->prio = prio; /* Raise the task's priority */
astroboy 0:94897d537b31 269
astroboy 0:94897d537b31 270 /* Insert the task which acquire the mutex into ready list. */
astroboy 0:94897d537b31 271 ptcb->TCBnext = 0;
astroboy 0:94897d537b31 272 ptcb->TCBprev = 0;
astroboy 0:94897d537b31 273
astroboy 0:94897d537b31 274 InsertToTCBRdyList(ptcb); /* Insert the task into the READY list */
astroboy 0:94897d537b31 275 OsSchedUnlock();
astroboy 0:94897d537b31 276 }
astroboy 0:94897d537b31 277 return E_OK;
astroboy 0:94897d537b31 278 }
astroboy 0:94897d537b31 279
astroboy 0:94897d537b31 280 /**
astroboy 0:94897d537b31 281 *******************************************************************************
astroboy 0:94897d537b31 282 * @brief Remove a task from mutex waiting list
astroboy 0:94897d537b31 283 * @param[in] ptcb TCB which will remove out.
astroboy 0:94897d537b31 284 * @param[out] None
astroboy 0:94897d537b31 285 * @retval None
astroboy 0:94897d537b31 286 *
astroboy 0:94897d537b31 287 * @par Description
astroboy 0:94897d537b31 288 * @details This function be called when delete a task.
astroboy 0:94897d537b31 289 * @note
astroboy 0:94897d537b31 290 *******************************************************************************
astroboy 0:94897d537b31 291 */
astroboy 0:94897d537b31 292 void RemoveMutexList(P_OSTCB ptcb)
astroboy 0:94897d537b31 293 {
astroboy 0:94897d537b31 294 U8 prio;
astroboy 0:94897d537b31 295 OS_TID taskID;
astroboy 0:94897d537b31 296 P_MUTEX pMutex;
astroboy 0:94897d537b31 297 pMutex = &MutexTbl[ptcb->mutexID];
astroboy 0:94897d537b31 298
astroboy 0:94897d537b31 299 /* If only one task waiting on mutex */
astroboy 0:94897d537b31 300 if((ptcb->TCBnext ==0) && (ptcb->TCBprev == 0))
astroboy 0:94897d537b31 301 {
astroboy 0:94897d537b31 302 pMutex->waittingList = 0; /* Waiting list is empty */
astroboy 0:94897d537b31 303 }
astroboy 0:94897d537b31 304 else if(ptcb->TCBnext == 0) /* If the task is the last of waiting list*/
astroboy 0:94897d537b31 305 {
astroboy 0:94897d537b31 306 /* Remove task from mutex waiting list */
astroboy 0:94897d537b31 307 ptcb->TCBprev->TCBnext = 0;
astroboy 0:94897d537b31 308 ptcb->TCBprev = 0;
astroboy 0:94897d537b31 309 }
astroboy 0:94897d537b31 310 else if(ptcb->TCBprev == 0)/* If the task is the first of waiting list*/
astroboy 0:94897d537b31 311 {
astroboy 0:94897d537b31 312 /* Remove task from waiting list */
astroboy 0:94897d537b31 313 ptcb->TCBnext->TCBprev = 0;
astroboy 0:94897d537b31 314 ptcb->TCBnext = 0;
astroboy 0:94897d537b31 315 }
astroboy 0:94897d537b31 316 else /* If the task is in the middle of waiting list */
astroboy 0:94897d537b31 317 {
astroboy 0:94897d537b31 318 /* Remove task from wait list */
astroboy 0:94897d537b31 319 ptcb->TCBnext->TCBprev = ptcb->TCBprev;
astroboy 0:94897d537b31 320 ptcb->TCBprev->TCBnext = ptcb->TCBnext;
astroboy 0:94897d537b31 321 ptcb->TCBprev = 0;
astroboy 0:94897d537b31 322 ptcb->TCBnext = 0;
astroboy 0:94897d537b31 323 }
astroboy 0:94897d537b31 324
astroboy 0:94897d537b31 325 ptcb->mutexID = INVALID_ID;
astroboy 0:94897d537b31 326
astroboy 0:94897d537b31 327 /* If the task have highest priority in mutex waiting list */
astroboy 0:94897d537b31 328 if(pMutex->hipriTaskID == ptcb->taskID)
astroboy 0:94897d537b31 329 {
astroboy 0:94897d537b31 330 ptcb = pMutex->waittingList;
astroboy 0:94897d537b31 331 prio = pMutex->originalPrio;
astroboy 0:94897d537b31 332 pMutex->hipriTaskID = pMutex->taskID;
astroboy 0:94897d537b31 333 while(ptcb != 0) /* Find task ID of highest priority task*/
astroboy 0:94897d537b31 334 {
astroboy 0:94897d537b31 335 if(ptcb->prio < prio)
astroboy 0:94897d537b31 336 {
astroboy 0:94897d537b31 337 prio = ptcb->prio;
astroboy 0:94897d537b31 338 pMutex->hipriTaskID = ptcb->taskID;
astroboy 0:94897d537b31 339 }
astroboy 0:94897d537b31 340 ptcb = ptcb->TCBnext;
astroboy 0:94897d537b31 341 }
astroboy 0:94897d537b31 342 taskID = pMutex->taskID;
astroboy 0:94897d537b31 343 pMutex->taskID = INVALID_ID;
astroboy 0:94897d537b31 344 CoSetPriority(taskID,prio); /* Reset the mutex ower priority */
astroboy 0:94897d537b31 345 pMutex->taskID = taskID;
astroboy 0:94897d537b31 346 }
astroboy 0:94897d537b31 347 }
astroboy 0:94897d537b31 348
astroboy 0:94897d537b31 349 #endif