Search Code
About CoOS

Published 03 Dec 2010.

Last change message: Some basic LED-Flashing works in the CoOS-RTOS using Tasks

Import this program

CoOS

Published 03 Dec 2010, by   user Eric Ebert   tag CoOS, rtos
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers mbox.c Source File

mbox.c

Go to the documentation of this file.
00001 /**
00002  *******************************************************************************
00003  * @file       mbox.c
00004  * @version    V1.1.3    
00005  * @date       2010.04.26
00006  * @brief      Mailbox 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_MAILBOX_EN > 0
00021 
00022 
00023 /**
00024  *******************************************************************************
00025  * @brief      Create a mailbox  
00026  * @param[in]  sortType     Mail box waiting list sort type.             
00027  * @param[out] None  
00028  * @retval     E_CREATE_FAIL   Create mailbox fail.
00029  * @retval     others          Create mailbox successful.        
00030  *
00031  * @par Description
00032  * @details    This function is called to create a mailbox. 
00033  * @note 
00034  *******************************************************************************
00035  */
00036 OS_EventID CoCreateMbox(U8 sortType)
00037 {
00038     P_ECB pecb;
00039     
00040     /* Create a mailbox type event control block                              */
00041     pecb = CreatEvent (EVENT_TYPE_MBOX ,sortType,0);   
00042     if(pecb == 0)                    /* If failed to create event block    */
00043     {
00044         return E_CREATE_FAIL;
00045     }
00046     pecb->eventCounter  = 0;
00047     return (pecb->id );      /* Create a mailbox successfully, return event ID */        
00048 }
00049 
00050 
00051 
00052 /**
00053  *******************************************************************************
00054  * @brief      Delete a mailbox    
00055  * @param[in]  id     Event ID.
00056  * @param[in]  opt    Delete option.     
00057  * @param[out] None      
00058  * @retval     E_INVALID_ID         Invalid event ID.
00059  * @retval     E_INVALID_PARAMETER  Invalid parameter.
00060  * @retval     E_TASK_WAITTING      Tasks waitting for the event,delete fail.
00061  * @retval     E_OK                 Event deleted successful. 
00062  *
00063  * @par Description
00064  * @details    This function is called to delete a mailbox.  
00065  * @note 
00066  *******************************************************************************
00067  */
00068 StatusType CoDelMbox(OS_EventID id,U8 opt)
00069 {
00070     P_ECB pecb;
00071     
00072 #if CFG_PAR_CHECKOUT_EN >0
00073     if(id >= CFG_MAX_EVENT )               /* Judge id is valid or not?        */ 
00074     {
00075         return E_INVALID_ID;              /* Id is invalid ,return error      */
00076     }
00077 #endif
00078     pecb = &EventTbl [id];
00079 #if CFG_PAR_CHECKOUT_EN >0
00080     if(pecb->eventType  != EVENT_TYPE_MBOX )/* Validate event control block type*/    
00081     {
00082         return E_INVALID_ID;              /* The event is not mailbox         */    
00083     }
00084 #endif  
00085     return (DeleteEvent (pecb,opt)); /* Delete the mailbox event control block */
00086 }
00087 
00088 
00089 
00090 /**
00091  *******************************************************************************
00092  * @brief      Accept a mailbox  
00093  * @param[in]  id    Event ID.       
00094  * @param[out] perr  A pointer to error code.  
00095  * @retval     0
00096  * @retval     A pointer to mailbox accepted.            
00097  *
00098  * @par Description
00099  * @details    This function is called to accept a mailbox. 
00100  * @note 
00101  *******************************************************************************
00102  */
00103 void* CoAcceptMail(OS_EventID id,StatusType* perr)
00104 {
00105     P_ECB pecb;
00106     void* pmail;
00107 #if CFG_PAR_CHECKOUT_EN >0
00108     if(id >= CFG_MAX_EVENT )                 
00109     {
00110         *perr = E_INVALID_ID;             /* Invalid 'id'                     */
00111         return 0;
00112     }
00113 #endif
00114     pecb = &EventTbl [id];
00115     
00116 #if CFG_PAR_CHECKOUT_EN >0
00117     if(pecb->eventType  != EVENT_TYPE_MBOX )/* Invalid event control block type */
00118     {
00119         *perr = E_INVALID_ID;   
00120         return 0;
00121     }
00122 #endif
00123     OsSchedLock ();
00124     if(pecb->eventCounter  == 1)             /* If there is already a message  */
00125     {
00126         *perr = E_OK;
00127         pmail = pecb->eventPtr ;             /* Get the message                */
00128         pecb->eventPtr      = 0;          /* Clear the mailbox              */
00129         pecb->eventCounter  = 0;
00130         OsSchedUnlock();
00131         return pmail;                       /* Return the message received    */        
00132     }
00133     else                                    /* If the mailbox is empty        */
00134     {   
00135         OsSchedUnlock();
00136         *perr = E_MBOX_EMPTY;               /* Mailbox is empty,return 0   */
00137         return 0;   
00138     }
00139 }
00140 
00141 
00142 
00143 /**
00144  *******************************************************************************
00145  * @brief      Wait for a mailbox    
00146  * @param[in]  id       Event ID.    
00147  * @param[in]  timeout  The longest time for writting mail.     
00148  * @param[out] perr     A pointer to error code.      
00149  * @retval     0    
00150  * @retval     A pointer to mailbox accept.
00151  *
00152  * @par Description
00153  * @details    This function is called to wait a mailbox.    
00154  * @note 
00155  *******************************************************************************
00156  */
00157 void* CoPendMail(OS_EventID id,U32 timeout,StatusType* perr)
00158 {
00159     P_ECB pecb;
00160     void* pmail;
00161     P_OSTCB  curTCB;
00162      
00163     if(OSIntNesting  > 0)                /* If the caller is ISR               */
00164     {
00165         *perr = E_CALL;
00166         return 0;
00167     }
00168     
00169 #if CFG_PAR_CHECKOUT_EN >0
00170     if(id >= CFG_MAX_EVENT )              
00171     {
00172         *perr = E_INVALID_ID;           /* Invalid 'id',retrun error          */
00173         return 0;
00174     }
00175 #endif
00176 
00177     pecb = &EventTbl [id];
00178 #if CFG_PAR_CHECKOUT_EN >0
00179     if(pecb->eventType  != EVENT_TYPE_MBOX )
00180     {
00181         *perr = E_INVALID_ID;       /* Invalid event type,not EVENT_TYPE_MBOX */
00182         return 0;
00183     }
00184 #endif
00185 
00186     if(OSSchedLock  != 0)                /* Judge schedule is locked or not?   */
00187     {   
00188         *perr = E_OS_IN_LOCK;           /* Schedule is locked                 */                                 
00189         return 0;                    /* return 0                        */
00190     }   
00191     if( pecb->eventCounter  == 1)        /* If there is already a message      */
00192     {
00193         *perr = E_OK;
00194         pmail = pecb->eventPtr ;         /* Get the message                    */
00195         pecb->eventPtr      = 0;      /* Clear the mailbox                  */
00196         pecb->eventCounter  = 0;             
00197         return pmail;                   /* Return the message received        */
00198     }
00199     else                       /* If message is not available, task will pend */ 
00200     {
00201         curTCB = TCBRunning ;
00202         if(timeout == 0)                /* If time-out is not configured      */
00203         {
00204             EventTaskToWait(pecb,curTCB); /* Block task until event occurs    */
00205             *perr = E_OK;
00206             
00207             /* Have recived a message or the mailbox have been deleted        */
00208             pmail = curTCB->pmail;          
00209             curTCB->pmail = 0;
00210             return pmail;               /* Return received message or 0    */
00211         }
00212         else                            /* If time-out is configured          */
00213         {
00214             OsSchedLock ();
00215             
00216             /* Block task until event or timeout occurs                       */
00217             EventTaskToWait(pecb,curTCB);   
00218             InsertDelayList(curTCB,timeout);
00219             OsSchedUnlock();
00220             if( curTCB->pmail == 0)  /* Time-out occurred                  */
00221             {
00222                 *perr = E_TIMEOUT;
00223                 return 0;   
00224             }
00225             else    /* Have recived a message or the mailbox have been deleted*/
00226             {
00227                 *perr = E_OK;
00228                 pmail = curTCB->pmail;
00229                 curTCB->pmail = 0;
00230                 return pmail;           /* Return received message or 0    */   
00231             }           
00232         }   
00233     }
00234 }
00235 
00236  
00237 /**
00238  *******************************************************************************
00239  * @brief      Post a mailbox     
00240  * @param[in]  id      Event ID.
00241  * @param[in]  pmail   Pointer to mail that want to send.        
00242  * @param[out] None   
00243  * @retval     E_INVALID_ID 
00244  * @retval     E_OK      
00245  *
00246  * @par Description
00247  * @details    This function is called to post a mail. 
00248  * @note 
00249  *******************************************************************************
00250  */
00251 StatusType CoPostMail(OS_EventID id,void* pmail)
00252 {
00253     P_ECB pecb;
00254 #if CFG_PAR_CHECKOUT_EN >0
00255     if(id >= CFG_MAX_EVENT )                 
00256     {
00257         return E_INVALID_ID;            /* Invalid id,return error            */
00258     }
00259 #endif
00260 
00261     pecb = &EventTbl [id];
00262 #if CFG_PAR_CHECKOUT_EN >0
00263     if(pecb->eventType  != EVENT_TYPE_MBOX )/* Validate event control block type*/
00264     {
00265         return E_INVALID_ID;              /* Event is not mailbox,return error*/
00266     }
00267 #endif
00268 
00269     if(pecb->eventCounter  == 0)   /* If mailbox doesn't already have a message*/    
00270     {
00271         OsSchedLock ();
00272         pecb->eventPtr      = pmail;       /* Place message in mailbox         */
00273         pecb->eventCounter  = 1;
00274         EventTaskToRdy (pecb);             /* Check waiting list               */
00275         OsSchedUnlock();
00276         return E_OK;    
00277     }
00278     else                          /* If there is already a message in mailbox */              
00279     {
00280         return E_MBOX_FULL;       /* Mailbox is full,and return "E_MBOX_FULL" */
00281     }
00282 }
00283 
00284 /**
00285  *******************************************************************************
00286  * @brief      Post a mailbox in ISR        
00287  * @param[in]  id      Event ID.
00288  * @param[in]  pmail   Pointer to mail that want to send.        
00289  * @param[out] None   
00290  * @retval     E_INVALID_ID 
00291  * @retval     E_OK      
00292  *
00293  * @par Description
00294  * @details    This function is called to post a mail in ISR. 
00295  * @note 
00296  *******************************************************************************
00297  */
00298 #if CFG_MAX_SERVICE_REQUEST > 0
00299 StatusType isr_PostMail(OS_EventID id,void* pmail)
00300 {
00301     if(OSSchedLock  > 0)         /* If scheduler is locked,(the caller is ISR) */
00302     {
00303         /* Insert the request into service request queue                      */
00304         if(InsertInSRQ(MBOX_REQ,id,pmail) == FALSE)  
00305         {
00306             return E_SEV_REQ_FULL;        /* If service request queue is full */
00307         }           
00308         else                              /* Operate successfully             */
00309         {
00310             return E_OK;
00311         }
00312     }
00313     else
00314     {
00315         return(CoPostMail(id,pmail));     /* Sends the message to the mailbox */ 
00316     }
00317 }
00318 #endif
00319 
00320 #endif
00321 
00322