electronix79
/
CoOS_mbed
CooCox 1.1.4 on mbed with simple blinky example
Embed:
(wiki syntax)
Show/hide line numbers
queue.c
Go to the documentation of this file.
00001 /** 00002 ******************************************************************************* 00003 * @file queue.c 00004 * @version V1.1.4 00005 * @date 2011.04.20 00006 * @brief Queue 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 /*---------------------------- Include ---------------------------------------*/ 00017 #include <coocox.h> 00018 00019 00020 #if CFG_QUEUE_EN > 0 00021 /*---------------------------- Variable Define -------------------------------*/ 00022 QCB QueueTbl [CFG_MAX_QUEUE] = {{0}}; /*!< Queue control block table */ 00023 U32 QueueIDVessel = 0; /*!< Queue list mask */ 00024 00025 00026 00027 /** 00028 ******************************************************************************* 00029 * @brief Create a queue 00030 * @param[in] qStart Pointer to mail pointer buffer. 00031 * @param[in] size The length of queue. 00032 * @param[in] sortType Mail queue waiting list sort type. 00033 * @param[out] None 00034 * @retval E_CREATE_FAIL Create queue fail. 00035 * @retval others Create queue successful. 00036 * 00037 * @par Description 00038 * @details This function is called to create a queue. 00039 * @note 00040 ******************************************************************************* 00041 */ 00042 OS_EventID CoCreateQueue(void **qStart, U16 size ,U8 sortType) 00043 { 00044 U8 i; 00045 P_ECB pecb; 00046 00047 #if CFG_PAR_CHECKOUT_EN >0 00048 if((qStart == Co_NULL) || (size == 0)) 00049 { 00050 return E_CREATE_FAIL; 00051 } 00052 #endif 00053 00054 OsSchedLock(); 00055 for(i = 0; i < CFG_MAX_QUEUE; i++) 00056 { 00057 /* Assign a free QUEUE control block */ 00058 if((QueueIDVessel & (1 << i)) == 0) 00059 { 00060 QueueIDVessel |= (1<<i); 00061 OsSchedUnlock(); 00062 00063 QueueTbl[i].qStart = qStart; /* Initialize the queue */ 00064 QueueTbl[i].id = i; 00065 QueueTbl[i].head = 0; 00066 QueueTbl[i].tail = 0; 00067 QueueTbl[i].qMaxSize = size; 00068 QueueTbl[i].qSize = 0; 00069 00070 /* Get a event control block and initial the event content */ 00071 pecb = CreatEvent(EVENT_TYPE_QUEUE,sortType,&QueueTbl[i]); 00072 00073 if(pecb == Co_NULL ) /* If there is no free EVENT control block*/ 00074 { 00075 return E_CREATE_FAIL; 00076 } 00077 return (pecb->id ); 00078 } 00079 } 00080 00081 OsSchedUnlock(); 00082 return E_CREATE_FAIL; /* There is no free QUEUE control block */ 00083 } 00084 00085 00086 /** 00087 ******************************************************************************* 00088 * @brief Delete a queue 00089 * @param[in] id Event ID. 00090 * @param[in] opt Delete option. 00091 * @param[out] None 00092 * @retval E_INVALID_ID Invalid event ID. 00093 * @retval E_INVALID_PARAMETER Invalid parameter. 00094 * @retval E_TASK_WAITTING Tasks waitting for the event,delete fail. 00095 * @retval E_OK Event deleted successful. 00096 * 00097 * @par Description 00098 * @details This function is called to delete a queue. 00099 * @note 00100 ******************************************************************************* 00101 */ 00102 StatusType CoDelQueue(OS_EventID id,U8 opt) 00103 { 00104 P_ECB pecb; 00105 P_QCB pqcb; 00106 StatusType err; 00107 #if CFG_PAR_CHECKOUT_EN >0 00108 if(id >= CFG_MAX_EVENT) 00109 { 00110 return E_INVALID_ID; /* Invalid id,return error */ 00111 } 00112 #endif 00113 00114 pecb = &EventTbl [id]; 00115 #if CFG_PAR_CHECKOUT_EN >0 00116 if( pecb->eventType != EVENT_TYPE_QUEUE) 00117 { 00118 return E_INVALID_ID; /* The event is not queue,return error*/ 00119 } 00120 #endif 00121 pqcb = (P_QCB)pecb->eventPtr ; /* Point at queue control block */ 00122 err = DeleteEvent(pecb,opt); /* Delete the event control block */ 00123 if(err == E_OK) /* If the event block have been deleted */ 00124 { 00125 QueueIDVessel &= ~((U32)(1<<(pqcb->id ))); /* Update free queue list */ 00126 pqcb->qStart = Co_NULL; 00127 pqcb->id = 0; 00128 pqcb->head = 0; 00129 pqcb->tail = 0; 00130 pqcb->qMaxSize = 0; 00131 pqcb->qSize = 0; 00132 } 00133 return err; 00134 } 00135 00136 00137 00138 /** 00139 ******************************************************************************* 00140 * @brief Accept a mail from queue 00141 * @param[in] id Event ID. 00142 * @param[out] perr A pointer to error code. 00143 * @retval Co_NULL 00144 * @retval A pointer to mail accepted. 00145 * 00146 * @par Description 00147 * @details This function is called to accept a mail from queue. 00148 * @note 00149 ******************************************************************************* 00150 */ 00151 void* CoAcceptQueueMail(OS_EventID id,StatusType* perr) 00152 { 00153 P_ECB pecb; 00154 P_QCB pqcb; 00155 void* pmail; 00156 #if CFG_PAR_CHECKOUT_EN >0 00157 if(id >= CFG_MAX_EVENT) 00158 { 00159 *perr = E_INVALID_ID; /* Invalid id,return error */ 00160 return Co_NULL; 00161 } 00162 #endif 00163 00164 pecb = &EventTbl [id]; 00165 #if CFG_PAR_CHECKOUT_EN >0 00166 if(pecb->eventType != EVENT_TYPE_QUEUE)/* Invalid event control block type*/ 00167 { 00168 *perr = E_INVALID_ID; 00169 return Co_NULL; 00170 } 00171 #endif 00172 pqcb = (P_QCB)pecb->eventPtr ; /* Point at queue control block */ 00173 OsSchedLock(); 00174 if(pqcb->qSize != 0) /* If there are any messages in the queue */ 00175 { 00176 /* Extract oldest message from the queue */ 00177 pmail = *(pqcb->qStart + pqcb->head ); 00178 pqcb->head ++; /* Update the queue head */ 00179 pqcb->qSize --; /* Update the number of messages in the queue */ 00180 if(pqcb->head == pqcb->qMaxSize ) 00181 { 00182 pqcb->head = 0; 00183 } 00184 OsSchedUnlock(); 00185 *perr = E_OK; 00186 return pmail; /* Return message received */ 00187 } 00188 else /* If there is no message in the queue*/ 00189 { 00190 OsSchedUnlock(); 00191 *perr = E_QUEUE_EMPTY; 00192 return Co_NULL; /* Return Co_NULL */ 00193 } 00194 } 00195 00196 00197 00198 /** 00199 ******************************************************************************* 00200 * @brief Pend for a mail 00201 * @param[in] id Event ID. 00202 * @param[in] timeout The longest time for writting mail. 00203 * @param[out] perr A pointer to error code. 00204 * @retval Co_NULL 00205 * @retval A pointer to mail accept. 00206 * 00207 * @par Description 00208 * @details This function is called to wait for a mail. 00209 * @note 00210 ******************************************************************************* 00211 */ 00212 void* CoPendQueueMail(OS_EventID id,U32 timeout,StatusType* perr) 00213 { 00214 P_ECB pecb; 00215 P_QCB pqcb; 00216 P_OSTCB curTCB; 00217 void* pmail; 00218 if(OSIntNesting > 0) /* If the caller is ISR */ 00219 { 00220 *perr = E_CALL; 00221 return Co_NULL; 00222 } 00223 #if CFG_PAR_CHECKOUT_EN >0 00224 if(id >= CFG_MAX_EVENT) 00225 { 00226 *perr = E_INVALID_ID; /* Invalid event id,return error */ 00227 return Co_NULL; 00228 } 00229 #endif 00230 00231 pecb = &EventTbl [id]; 00232 #if CFG_PAR_CHECKOUT_EN >0 00233 if(pecb->eventType != EVENT_TYPE_QUEUE) /* The event type is not queue */ 00234 { 00235 *perr = E_INVALID_ID; 00236 return Co_NULL; 00237 } 00238 #endif 00239 if(OSSchedLock != 0) /* Judge schedule is locked or not? */ 00240 { 00241 *perr = E_OS_IN_LOCK; /* Schedule is locked,return error */ 00242 return Co_NULL; 00243 } 00244 pqcb = (P_QCB)pecb->eventPtr ; /* Point at queue control block */ 00245 OsSchedLock(); 00246 if(pqcb->qSize != 0) /* If there are any messages in the queue */ 00247 { 00248 /* Extract oldest message from the queue */ 00249 pmail = *(pqcb->qStart + pqcb->head ); 00250 pqcb->head ++; /* Update the queue head */ 00251 pqcb->qSize --; /* Update the number of messages in the queue */ 00252 if(pqcb->head == pqcb->qMaxSize )/* Check queue head */ 00253 { 00254 pqcb->head = 0; 00255 } 00256 OsSchedUnlock(); 00257 *perr = E_OK; 00258 return pmail; /* Return message received */ 00259 } 00260 else /* If there is no message in the queue*/ 00261 { 00262 OsSchedUnlock(); 00263 curTCB = TCBRunning ; 00264 if(timeout == 0) /* If time-out is not configured */ 00265 { 00266 /* Block current task until the event occur */ 00267 EventTaskToWait(pecb,curTCB); 00268 00269 /* Have recived message or the queue have been deleted */ 00270 pmail = curTCB->pmail ; 00271 curTCB->pmail = Co_NULL; 00272 *perr = E_OK; 00273 return pmail; /* Return message received or Co_NULL */ 00274 } 00275 else /* If time-out is configured */ 00276 { 00277 OsSchedLock(); 00278 00279 /* Block current task until event or timeout occurs */ 00280 EventTaskToWait(pecb,curTCB); 00281 InsertDelayList(curTCB,timeout); 00282 OsSchedUnlock(); 00283 if(curTCB->pmail == Co_NULL) /* If time-out occurred */ 00284 { 00285 *perr = E_TIMEOUT; 00286 return Co_NULL; 00287 } 00288 else /* If event occured */ 00289 { 00290 pmail = curTCB->pmail ; 00291 curTCB->pmail = Co_NULL; 00292 *perr = E_OK; 00293 return pmail; /* Return message received or Co_NULL */ 00294 } 00295 } 00296 } 00297 } 00298 00299 00300 00301 /** 00302 ******************************************************************************* 00303 * @brief Post a mail to queue 00304 * @param[in] id Event ID. 00305 * @param[in] pmail Pointer to mail that want to send. 00306 * @param[out] None 00307 * @retval E_OK 00308 * @retval E_INVALID_ID 00309 * @retval E_QUEUE_FULL 00310 * 00311 * @par Description 00312 * @details This function is called to post a mail to queue. 00313 * @note 00314 ******************************************************************************* 00315 */ 00316 StatusType CoPostQueueMail(OS_EventID id,void* pmail) 00317 { 00318 P_ECB pecb; 00319 P_QCB pqcb; 00320 #if CFG_PAR_CHECKOUT_EN >0 00321 if(id >= CFG_MAX_EVENT) 00322 { 00323 return E_INVALID_ID; 00324 } 00325 #endif 00326 00327 pecb = &EventTbl [id]; 00328 #if CFG_PAR_CHECKOUT_EN >0 00329 if(pecb->eventType != EVENT_TYPE_QUEUE) 00330 { 00331 return E_INVALID_ID; /* The event type isn't queue,return */ 00332 } 00333 #endif 00334 pqcb = (P_QCB)pecb->eventPtr ; 00335 if(pqcb->qSize == pqcb->qMaxSize ) /* If queue is full */ 00336 { 00337 return E_QUEUE_FULL; 00338 } 00339 else /* If queue is not full */ 00340 { 00341 OsSchedLock(); 00342 *(pqcb->qStart + pqcb->tail ) = pmail; /* Insert message into queue */ 00343 pqcb->tail ++; /* Update queue tail */ 00344 pqcb->qSize ++; /* Update the number of messages in the queue */ 00345 if(pqcb->tail == pqcb->qMaxSize ) /* Check queue tail */ 00346 { 00347 pqcb->tail = 0; 00348 } 00349 EventTaskToRdy(pecb); /* Check the event waiting list */ 00350 OsSchedUnlock(); 00351 return E_OK; 00352 } 00353 } 00354 00355 00356 /** 00357 ******************************************************************************* 00358 * @brief Post a mail to queue in ISR 00359 * @param[in] id Event ID. 00360 * @param[in] pmail Pointer to mail that want to send. 00361 * @param[out] None 00362 * @retval E_OK 00363 * @retval E_INVALID_ID 00364 * @retval E_QUEUE_FULL 00365 * 00366 * @par Description 00367 * @details This function is called in ISR to post a mail to queue. 00368 * @note 00369 ******************************************************************************* 00370 */ 00371 #if CFG_MAX_SERVICE_REQUEST > 0 00372 StatusType isr_PostQueueMail(OS_EventID id,void* pmail) 00373 { 00374 if(OSSchedLock > 0) /* If scheduler is locked,(the caller is ISR) */ 00375 { 00376 /* Insert the request into service request queue */ 00377 if(InsertInSRQ(QUEUE_REQ,id,pmail) == Co_FALSE) 00378 { 00379 return E_SEV_REQ_FULL; /* If service request queue is full */ 00380 } 00381 else /* If the request have been inserted into service request queue */ 00382 { 00383 return E_OK; 00384 } 00385 } 00386 else /* The scheduler is unlocked */ 00387 { 00388 return(CoPostQueueMail(id,pmail)); /* Send the message to the queue*/ 00389 } 00390 } 00391 #endif 00392 00393 #endif
Generated on Tue Jul 12 2022 18:19:10 by 1.7.2