Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
event.c
00001 /** 00002 ******************************************************************************* 00003 * @file event.c 00004 * @version V1.1.3 00005 * @date 2010.04.26 00006 * @brief event management implementation code of CooCox CoOS kernel. 00007 ******************************************************************************* 00008 * @copy 00009 * 00010 * INTERNAL FILE,DON'T PUBLIC. 00011 * 00012 * <h2><center>© COPYRIGHT 2009 CooCox </center></h2> 00013 ******************************************************************************* 00014 */ 00015 00016 00017 /*---------------------------- Include ---------------------------------------*/ 00018 #include <coocox.h> 00019 00020 00021 /*---------------------------- Variable Define -------------------------------*/ 00022 #if CFG_EVENT_EN > 0 00023 00024 ECB EventTbl [CFG_MAX_EVENT]= {{0}};/*!< Table which save event control block.*/ 00025 P_ECB FreeEventList = 0; /*!< Pointer to free event control block. */ 00026 00027 00028 /** 00029 ******************************************************************************* 00030 * @brief Create a empty list of event control block 00031 * @param[in] None 00032 * @param[out] None 00033 * @retval None 00034 * 00035 * @par Description 00036 * @details This function is called by OSInit() API to create a ECB list,supply 00037 * a pointer to next event control block that not used. 00038 ******************************************************************************* 00039 */ 00040 void CreateEventList(void) 00041 { 00042 U8 i; 00043 P_ECB pecb1; 00044 #if CFG_MAX_EVENT > 1 00045 P_ECB pecb2; 00046 #endif 00047 i=0; 00048 pecb1 = &EventTbl[0]; /* Get first item */ 00049 #if CFG_MAX_EVENT == 1 /* Build event list for only one item */ 00050 pecb1->eventPtr = 0; 00051 pecb1->id = i; /* Assign ID. */ 00052 pecb1->eventType = EVENT_TYPE_INVALID; /* Sign that not to use. */ 00053 #endif 00054 00055 #if CFG_MAX_EVENT > 1 /* Build event list for more than one item */ 00056 pecb2 = &EventTbl[1]; 00057 for(;i< (CFG_MAX_EVENT-1);i++ ) 00058 { 00059 pecb1->eventPtr = (void*)pecb2; /* Set link for list */ 00060 pecb1->id = i; /* Assign ID. */ 00061 pecb1->eventType = EVENT_TYPE_INVALID;/* Sign that not to use. */ 00062 pecb1++; /* Get next item */ 00063 pecb2++; 00064 } 00065 pecb1->eventType = EVENT_TYPE_INVALID; /* Sign that not to use. */ 00066 pecb1->eventPtr = 0; /* Set link for last item */ 00067 pecb1->id = i; 00068 #endif 00069 00070 FreeEventList = &EventTbl[0]; /* Set free event item */ 00071 } 00072 00073 00074 00075 /** 00076 ******************************************************************************* 00077 * @brief Release a ECB 00078 * @param[in] pecb A pointer to event control block which be released. 00079 * @param[out] None 00080 * @retval None 00081 * 00082 * @par Description 00083 * @details This function is called to release a event control block when a 00084 * event be deleted. 00085 ******************************************************************************* 00086 */ 00087 static void ReleaseECB(P_ECB pecb) 00088 { 00089 pecb->eventType = EVENT_TYPE_INVALID; /* Sign that not to use. */ 00090 OsSchedLock(); /* Lock schedule */ 00091 pecb->eventPtr = FreeEventList ; /* Release ECB that event hold */ 00092 FreeEventList = pecb; /* Reset free event item */ 00093 OsSchedUnlock(); /* Unlock schedule */ 00094 } 00095 00096 00097 00098 /** 00099 ******************************************************************************* 00100 * @brief Create a event 00101 * @param[in] eventType The type of event which being created. 00102 * @param[in] eventSortType Event sort type. 00103 * @param[in] eventCounter Event counter,ONLY for EVENT_TYPE_SEM. 00104 * @param[in] eventPtr Event struct pointer,ONLY for Queue.0 for other 00105 * event type. 00106 * @param[out] None 00107 * @retval 0 Invalid pointer,create event fail. 00108 * @retval others Pointer to event control block which had assigned right now. 00109 * 00110 * @par Description 00111 * @details This function is called by CreateSem(),... 00112 * to get a event control block and initial the event content. 00113 * 00114 * @note This is a internal function of CooCox CoOS,User can't call. 00115 ******************************************************************************* 00116 */ 00117 P_ECB CreatEvent(U8 eventType,U8 eventSortType,void* eventPtr) 00118 { 00119 P_ECB pecb; 00120 00121 OsSchedLock(); /* Lock schedule */ 00122 if(FreeEventList == 0) /* Is there no free evnet item */ 00123 { 00124 OsSchedUnlock(); /* Yes,unlock schedule */ 00125 return 0; /* Return error */ 00126 } 00127 pecb = FreeEventList ;/* Assign the free event item to this event */ 00128 FreeEventList = (P_ECB)FreeEventList->eventPtr ; /* Reset free event item */ 00129 OsSchedUnlock(); /* Unlock schedul */ 00130 00131 pecb->eventType = eventType; /* Initialize event item as user set */ 00132 pecb->eventSortType = eventSortType; 00133 pecb->eventPtr = eventPtr; 00134 pecb->eventTCBList = 0; 00135 return pecb; /* Return event item pointer */ 00136 } 00137 00138 00139 /** 00140 ******************************************************************************* 00141 * @brief Delete a event 00142 * @param[in] pecb Pointer to event control block which will be deleted. 00143 * @param[in] opt Delete option. 00144 * @arg == OPT_DEL_ANYWAY Delete event always 00145 * @arg == OPT_DEL_NO_PEND Delete event only when no task pending on. 00146 * @param[out] None 00147 * @retval E_INVALID_PARAMETER Parameter passed is invalid,deleted fail. 00148 * @retval E_TASK_WAITTING These are one more tasks waitting event. 00149 * @retval E_OK Delete event control block successful. 00150 * 00151 * @par Description 00152 * @details This function is called to delete a event from the event wait list 00153 * use specify option. 00154 * 00155 * @note This is a internal function of Coocox CoOS,user can't call. 00156 ******************************************************************************* 00157 */ 00158 StatusType DeleteEvent(P_ECB pecb,U8 opt) 00159 { 00160 P_OSTCB ptcb; 00161 if(opt == OPT_DEL_NO_PEND) /* Do delete event when no task pend? */ 00162 { 00163 if(pecb->eventTCBList != 0) /* Yes,is there task pend this event? */ 00164 { 00165 return E_TASK_WAITING; /* Yes,error return */ 00166 } 00167 else 00168 { 00169 ReleaseECB(pecb); /* No,release resource that event hold*/ 00170 } 00171 } 00172 else if(opt == OPT_DEL_ANYWAY) /* Do delete event anyway? */ 00173 { 00174 OsSchedLock(); /* Lock schedule */ 00175 while(pecb->eventTCBList != 0) /* Is there task pend this event? */ 00176 { /* Yes,remove it */ 00177 ptcb = pecb->eventTCBList ;/* Get first task in event waiting list */ 00178 if(ptcb->delayTick != INVALID_VALUE) /* Is task in delay list? */ 00179 { 00180 RemoveDelayList(ptcb); /* Yes,remove task from delay list */ 00181 } 00182 00183 /* Set next item as event waiting list head */ 00184 pecb->eventTCBList = ptcb->waitNext ; 00185 ptcb->waitNext = 0; /* Clear link for event waiting list */ 00186 ptcb->eventID = INVALID_ID; /* Sign that not to use. */ 00187 00188 InsertToTCBRdyList(ptcb); /* Insert task into ready list */ 00189 } 00190 OsSchedUnlock(); /* Unlock schedule */ 00191 ReleaseECB(pecb); /* Release resource that event hold */ 00192 } 00193 return E_OK; /* Return OK */ 00194 } 00195 00196 00197 /** 00198 ******************************************************************************* 00199 * @brief Insert a task to event wait list 00200 * @param[in] pecb Pointer to event control block corresponding to the event. 00201 * @param[in] ptcb Pointer to task that will be insert to event wait list. 00202 * @param[out] None 00203 * @retval None 00204 * 00205 * @par Description 00206 * @details This function is called to insert a task by fllowing manner: 00207 * opt == EVENT_SORT_TYPE_FIFO By FIFO. 00208 * opt == EVENT_SORT_TYPE_PRIO By priority order,hghest priority 00209 * as head,lowest priority as end. 00210 * (Highest-->...-->Lowest-->0) 00211 ******************************************************************************* 00212 */ 00213 void EventTaskToWait(P_ECB pecb,P_OSTCB ptcb) 00214 { 00215 P_OSTCB ptcb1; 00216 #if (CFG_EVENT_SORT == 2) || (CFG_EVENT_SORT == 3) 00217 P_OSTCB ptcb2; 00218 #endif 00219 00220 OsSchedLock(); /* Lock schedule */ 00221 ptcb1 = pecb->eventTCBList ; /* Get first task in event waiting list */ 00222 ptcb->eventID = pecb->id ; /* Set event ID for task */ 00223 00224 #if CFG_EVENT_SORT == 3 /* Does event waiting list sort as FIFO? */ 00225 00226 if(pecb->eventSortType == EVENT_SORT_TYPE_FIFO) 00227 #endif 00228 00229 #if (CFG_EVENT_SORT == 1) || (CFG_EVENT_SORT == 3) 00230 { 00231 if(ptcb1 == 0) /* Is no item in event waiting list?*/ 00232 { 00233 pecb->eventTCBList = ptcb; /* Yes,set task as first item */ 00234 } 00235 else 00236 { 00237 while(ptcb1->waitNext != 0)/* No,insert task in last */ 00238 { 00239 ptcb1 = ptcb1->waitNext ; 00240 } 00241 ptcb1->waitNext = ptcb; /* Set link for list */ 00242 ptcb->waitPrev = ptcb1; 00243 } 00244 } 00245 #endif 00246 00247 #if CFG_EVENT_SORT ==3 /* Does event waiting list sort as preemptive priority?*/ 00248 else if(pecb->eventSortType == EVENT_SORT_TYPE_PRIO) 00249 #endif 00250 #if (CFG_EVENT_SORT == 2) || (CFG_EVENT_SORT == 3) 00251 { 00252 if(ptcb1 == 0) /* Is no item in event waiting list? */ 00253 { 00254 pecb->eventTCBList = ptcb; /* Yes,set task as first item */ 00255 } 00256 /* Is PRI of task higher than list first item? */ 00257 else if(ptcb1->prio > ptcb->prio ) 00258 { 00259 pecb->eventTCBList = ptcb; /* Reset task as first item */ 00260 ptcb->waitNext = ptcb1; /* Set link for list */ 00261 ptcb1->waitPrev = ptcb; 00262 } 00263 else /* No,find correct place to insert */ 00264 { 00265 ptcb2 = ptcb1->waitNext ; 00266 while(ptcb2 != 0) /* Is last item? */ 00267 { 00268 if(ptcb2->prio > ptcb->prio ) /* No,is correct place? */ 00269 { 00270 break; /* Yes,break Circulation */ 00271 } 00272 ptcb1 = ptcb2; /* Save current item */ 00273 ptcb2 = ptcb2->waitNext ; /* Get next item */ 00274 } 00275 ptcb1->waitNext = ptcb; /* Set link for list */ 00276 ptcb->waitPrev = ptcb1; 00277 ptcb->waitNext = ptcb2; 00278 if(ptcb2 != 0) 00279 { 00280 ptcb2->waitPrev = ptcb; 00281 } 00282 } 00283 } 00284 #endif 00285 ptcb->state = TASK_WAITING; /* Set task status to TASK_WAITING state */ 00286 TaskSchedReq = TRUE; 00287 OsSchedUnlock(); /* Unlock schedule,and call task schedule */ 00288 } 00289 00290 00291 /** 00292 ******************************************************************************* 00293 * @brief Move a task from event WAITING list to the DELAY list 00294 * @param[in] pecb Pointer to event control block corresponding to the event. 00295 * @param[out] None 00296 * @retval None 00297 * 00298 * @par Description 00299 * @details This function is called to remove a task from event wait list,and 00300 * then insert it into the READY list. 00301 ******************************************************************************* 00302 */ 00303 void EventTaskToRdy(P_ECB pecb) 00304 { 00305 P_OSTCB ptcb; 00306 #if CFG_QUEUE_EN >0 00307 P_QCB pqcb; 00308 #endif 00309 ptcb = pecb->eventTCBList ; 00310 if(ptcb == 0) 00311 return; 00312 00313 pecb->eventTCBList = ptcb->waitNext ;/* Get first task in event waiting list*/ 00314 if(pecb->eventTCBList != 0) /* Is no item in event waiting list? */ 00315 { 00316 pecb->eventTCBList ->waitPrev = 0; /* No,clear link for first item */ 00317 } 00318 00319 ptcb->waitNext = 0; /* Clear event waiting link for task*/ 00320 ptcb->eventID = INVALID_ID; /* Sign that not to use. */ 00321 00322 if(ptcb->delayTick != INVALID_VALUE) /* Is task in delay list? */ 00323 { 00324 RemoveDelayList(ptcb); /* Yes,remove task from DELAY list */ 00325 } 00326 if(pecb->eventType == EVENT_TYPE_MBOX)/* Is it a mailbox event? */ 00327 { 00328 ptcb->pmail = pecb->eventPtr ; /* Yes,send mail to task */ 00329 pecb->eventPtr = 0; /* Clear event sign */ 00330 pecb->eventCounter --; 00331 } 00332 #if CFG_QUEUE_EN >0 00333 else if(pecb->eventType == EVENT_TYPE_QUEUE) /* Is it a queue event? */ 00334 { 00335 pqcb = (P_QCB)pecb->eventPtr ; /* Yes,get queue pointer */ 00336 ptcb->pmail = *(pqcb->qStart + pqcb->head ); /* Send mail to task */ 00337 pqcb->head ++; /* Clear event sign */ 00338 pqcb->qSize --; 00339 if(pqcb->head == pqcb->qMaxSize ) 00340 { 00341 pqcb->head = 0; 00342 } 00343 } 00344 #endif 00345 00346 #if CFG_MAILBOX_EN >0 00347 else if(pecb->eventType == EVENT_TYPE_SEM)/* Is it a semaphore event? */ 00348 { 00349 pecb->eventCounter --; /* Yes,clear event sign */ 00350 ptcb->pmail = (void*)0xffffffff; /* Indicate task woke by event */ 00351 } 00352 #endif 00353 if(ptcb == TCBRunning ) 00354 { 00355 ptcb->state = TASK_RUNNING; 00356 } 00357 else 00358 { 00359 InsertToTCBRdyList(ptcb); /* Insert task into ready list */ 00360 } 00361 } 00362 00363 00364 00365 /** 00366 ******************************************************************************* 00367 * @brief Move a task from event wait list to the ready list 00368 * @param[in] pecb Pointer to event control block corresponding to the event. 00369 * @param[out] None 00370 * @retval None 00371 * 00372 * @par Description 00373 * @details This function is called to remove a task from event wait list,and 00374 * then insert it to the ready list. 00375 ******************************************************************************* 00376 */ 00377 void RemoveEventWaittingList(P_OSTCB ptcb) 00378 { 00379 P_ECB pecb; 00380 pecb = &EventTbl[ptcb->eventID ]; /* Get event control block */ 00381 00382 /* Is there only one item in event waiting list? */ 00383 if((ptcb->waitNext == 0) && (ptcb->waitPrev == 0)) 00384 { 00385 pecb->eventTCBList = 0; /* Yes,set event waiting list as 0 */ 00386 } 00387 else if(ptcb->waitPrev == 0)/* Is the first item in event waiting list?*/ 00388 { 00389 /* Yes,remove task from list,and reset event waiting list */ 00390 ptcb->waitNext ->waitPrev = 0; 00391 pecb->eventTCBList = ptcb->waitNext ; 00392 ptcb->waitNext = 0; 00393 } 00394 else if(ptcb->waitNext == 0)/* Is the last item in event waiting list? */ 00395 { 00396 ptcb->waitPrev ->waitNext = 0; /* Yes,remove task form list */ 00397 ptcb->waitPrev = 0; 00398 } 00399 else /* No, remove task from list */ 00400 { 00401 ptcb->waitPrev ->waitNext = ptcb->waitNext ; 00402 ptcb->waitNext ->waitPrev = ptcb->waitPrev ; 00403 ptcb->waitPrev = 0; 00404 ptcb->waitNext = 0; 00405 } 00406 ptcb->eventID = INVALID_ID; /* Sign that not to use. */ 00407 } 00408 00409 #endif //CFG_EVENT_EN 00410
Generated on Tue Jul 12 2022 15:09:51 by
 1.7.2
 1.7.2