CooCox 1.1.4 on mbed with simple blinky example

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers queue.c Source File

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>&copy; 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