CooCox 1.1.4 on mbed with simple blinky example

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers sem.c Source File

sem.c

Go to the documentation of this file.
00001 /**
00002  *******************************************************************************
00003  * @file       sem.c
00004  * @version    V1.1.4    
00005  * @date       2011.04.20
00006  * @brief      Semaphore 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 
00017 /*---------------------------- Include ---------------------------------------*/
00018 #include <coocox.h>
00019 
00020 #if CFG_SEM_EN >0
00021 
00022 /**
00023  *******************************************************************************
00024  * @brief      Create a semaphore     
00025  * @param[in]  initCnt   Semaphore valid counter.
00026  * @param[in]  maxCnt    Semaphore max initialize counter.
00027  * @param[in]  sortType  Semaphore sort type.        
00028  * @param[out] None
00029  * @retval     E_CREATE_FAIL   Create semaphore fail.
00030  * @retval     others          Create semaphore successful.
00031  *
00032  * @par Description
00033  * @details    This function is called to create a semaphore. 
00034  *******************************************************************************
00035  */
00036 OS_EventID CoCreateSem(U16 initCnt,U16 maxCnt,U8 sortType)
00037 {
00038     P_ECB pecb;
00039 #if CFG_PAR_CHECKOUT_EN >0
00040     if(initCnt > maxCnt)    
00041     {
00042         return E_CREATE_FAIL;           /* Invalid 'initCnt' or 'maxCnt'      */    
00043     }
00044     
00045     if ((sortType != EVENT_SORT_TYPE_FIFO) && (sortType != EVENT_SORT_TYPE_PRIO))
00046     {
00047         return E_CREATE_FAIL;           /* Illegal sort type,return error     */
00048     }
00049 #endif  
00050     
00051     /* Create a semaphore type event control block                            */
00052     pecb = CreatEvent(EVENT_TYPE_SEM,sortType,Co_NULL);
00053     if(pecb == Co_NULL)                    /* If failed to create event block    */
00054     {
00055         return E_CREATE_FAIL;
00056     }
00057     pecb->eventCounter         = initCnt;/* Initialize event block             */
00058     pecb->initialEventCounter  = maxCnt;
00059     return (pecb->id );                  /* Return event id                    */
00060 }
00061 
00062  
00063 /**
00064  *******************************************************************************
00065  * @brief      Delete a semaphore      
00066  * @param[in]  id    Event ID which to be deleted.
00067  * @param[in]  opt   Delete option.  
00068  * @arg        == OPT_DEL_ANYWAY    Delete semaphore always   
00069  * @arg        == OPT_DEL_NO_PEND   Delete semaphore only when no task pending on.
00070  * @param[out] None   
00071  * @retval     E_INVALID_ID         Invalid event ID.
00072  * @retval     E_INVALID_PARAMETER  Invalid parameter.
00073  * @retval     E_TASK_WAITTING      Tasks waitting for the event,delete fail.
00074  * @retval     E_OK                 Event deleted successful.    
00075  *
00076  * @par Description
00077  * @details    This function is called to delete a semaphore. 
00078  *
00079  * @note 
00080  *******************************************************************************
00081  */
00082 StatusType CoDelSem(OS_EventID id,U8 opt)
00083 {
00084     P_ECB pecb;
00085 
00086 #if CFG_PAR_CHECKOUT_EN >0
00087     if(id >= CFG_MAX_EVENT)                  
00088     {
00089         return E_INVALID_ID;
00090     }
00091 #endif
00092 
00093     pecb = &EventTbl [id];
00094 
00095 #if CFG_PAR_CHECKOUT_EN >0
00096     if(pecb->eventType  != EVENT_TYPE_SEM)  
00097     {
00098         return E_INVALID_ID;             /* The event type is not semaphore   */    
00099     }   
00100 #endif
00101 
00102     return (DeleteEvent(pecb,opt));/* Delete the semaphore event control block*/
00103 }
00104 
00105 
00106 /**
00107  *******************************************************************************
00108  * @brief      Accept a semaphore without waitting    
00109  * @param[in]  id      Event ID      
00110  * @param[out] None  
00111  * @retval     E_INVALID_ID    Invalid event ID.
00112  * @retval     E_SEM_EMPTY     No semaphore exist.
00113  * @retval     E_OK            Get semaphore successful.    
00114  *
00115  * @par Description
00116  * @details    This function is called accept a semaphore without waitting. 
00117  *******************************************************************************
00118  */
00119 StatusType CoAcceptSem(OS_EventID id)
00120 {
00121     P_ECB pecb;
00122 #if CFG_PAR_CHECKOUT_EN >0
00123     if(id >= CFG_MAX_EVENT)                  
00124     {
00125         return E_INVALID_ID;
00126     }
00127 #endif
00128 
00129     pecb = &EventTbl [id];
00130 #if CFG_PAR_CHECKOUT_EN >0
00131     if( pecb->eventType  != EVENT_TYPE_SEM)   
00132     {
00133         return E_INVALID_ID;    
00134     }
00135 #endif
00136     OsSchedLock();
00137     if(pecb->eventCounter  > 0) /* If semaphore is positive,resource available */
00138     {   
00139         OsSchedUnlock();
00140         pecb->eventCounter --;         /* Decrement semaphore only if positive */
00141         return E_OK;    
00142     }
00143     else                                /* Resource is not available          */
00144     {   
00145         OsSchedUnlock();
00146         return E_SEM_EMPTY;
00147     }   
00148 }
00149 
00150  
00151 /**
00152  *******************************************************************************
00153  * @brief       wait for a semaphore       
00154  * @param[in]   id       Event ID.  
00155  * @param[in]   timeout  The longest time for writting semaphore.
00156  * @para        0        
00157  * @para        0x1~0xff     
00158  * @param[out]  None  
00159  * @retval      E_CALL         Error call in ISR.   
00160  * @retval      E_INVALID_ID   Invalid event ID.    
00161  * @retval      E_TIMEOUT      Semaphore was not received within the specified 
00162  *                             'timeout' time.
00163  * @retval      E_OK           The call was successful and your task owns the 
00164  *                             resource,or the event you are waiting for occurred.  
00165  * 
00166  * @par Description
00167  * @details    This function is called to waits for a semaphore. 
00168  * @note       IF this function is called in ISR,nothing to do and return immediately.
00169  *******************************************************************************
00170  */
00171 StatusType CoPendSem(OS_EventID id,U32 timeout)
00172 {
00173     P_ECB    pecb;
00174     P_OSTCB  curTCB;
00175     if(OSIntNesting  > 0)                /* If the caller is ISR               */
00176     {
00177         return E_CALL;
00178     }
00179 #if CFG_PAR_CHECKOUT_EN >0
00180     if(id >= CFG_MAX_EVENT)             
00181     {
00182         return E_INVALID_ID;
00183     }
00184 #endif
00185 
00186       pecb = &EventTbl [id];
00187 #if CFG_PAR_CHECKOUT_EN >0
00188     if(pecb->eventType  != EVENT_TYPE_SEM)     
00189     {
00190        return E_INVALID_ID; 
00191     }
00192 #endif
00193     if(OSSchedLock  != 0)                /* Schdule is locked?                 */
00194     {
00195         return E_OS_IN_LOCK;            /* Yes,error return                   */
00196     }
00197     OsSchedLock();
00198     if(pecb->eventCounter  > 0) /* If semaphore is positive,resource available */       
00199     {   
00200         pecb->eventCounter --;         /* Decrement semaphore only if positive */
00201         OsSchedUnlock();
00202         return E_OK;    
00203     }
00204     else                                /* Resource is not available          */
00205     {
00206         OsSchedUnlock();
00207         curTCB = TCBRunning ;
00208         if(timeout == 0)                /* If time-out is not configured      */
00209         {
00210             EventTaskToWait(pecb,curTCB); /* Block task until event occurs    */
00211             curTCB->pmail  = Co_NULL;
00212             return E_OK;
00213         }
00214         else                            /* If time-out is configured          */
00215         {
00216             OsSchedLock();
00217             
00218             /* Block task until event or timeout occurs                       */
00219             EventTaskToWait(pecb,curTCB);
00220             InsertDelayList(curTCB,timeout);
00221             
00222             OsSchedUnlock();
00223             if (curTCB->pmail  == Co_NULL)  /* If pmail is Co_NULL, time-out occurred*/
00224             {
00225               return E_TIMEOUT; 
00226             }                               
00227             else                  /* Event occurred or event have been deleted*/    
00228             {
00229                 curTCB->pmail  = Co_NULL;
00230                 return E_OK;    
00231             }               
00232         }       
00233     }
00234 }
00235 
00236 
00237 /**
00238  *******************************************************************************
00239  * @brief       Post a semaphore     
00240  * @param[in]   id   id of event control block associated with the desired semaphore.        
00241  * @param[out]  None   
00242  * @retval      E_INVALID_ID   Parameter id passed was invalid event ID.
00243  * @retval      E_SEM_FULL     Semaphore full. 
00244  * @retval      E_OK           Semaphore had post successful.
00245  *
00246  * @par Description
00247  * @details    This function is called to post a semaphore to corresponding event. 
00248  *
00249  * @note 
00250  *******************************************************************************
00251  */
00252 StatusType CoPostSem(OS_EventID id)
00253 {
00254     P_ECB pecb;
00255 #if CFG_PAR_CHECKOUT_EN >0
00256     if(id >= CFG_MAX_EVENT)                   
00257     {
00258         return E_INVALID_ID;
00259     }
00260 #endif
00261 
00262     pecb = &EventTbl [id];
00263 #if CFG_PAR_CHECKOUT_EN >0
00264     if(pecb->eventType  != EVENT_TYPE_SEM) /* Invalid event control block type */
00265     {
00266         return E_INVALID_ID;    
00267     }
00268 #endif
00269 
00270     /* Make sure semaphore will not overflow */
00271     if(pecb->eventCounter  == pecb->initialEventCounter ) 
00272     {
00273         return E_SEM_FULL;    /* The counter of Semaphore reach the max number*/
00274     }
00275     OsSchedLock();
00276     pecb->eventCounter ++;     /* Increment semaphore count to register event  */
00277     EventTaskToRdy(pecb);     /* Check semaphore event waiting list           */
00278     OsSchedUnlock();
00279     return E_OK;
00280         
00281 }
00282 
00283 
00284 /**
00285  *******************************************************************************
00286  * @brief       Post a semaphore in ISR  
00287  * @param[in]   id    identifier of event control block associated with the 
00288  *                    desired semaphore.         
00289  * @param[out]  None  
00290  * @retval      E_INVALID_ID        Parameter id passed was invalid event ID.
00291  * @retval      E_NO_TASK_WAITTING  There are one more tasks waitting for the event. 
00292  * @retval      E_OK                Semaphore had signaled successful.
00293  *
00294  * @par Description
00295  * @details    This function is called in ISR to post a semaphore to corresponding
00296  *             event. 
00297  * @note 
00298  *******************************************************************************
00299  */
00300 #if CFG_MAX_SERVICE_REQUEST > 0
00301 StatusType isr_PostSem(OS_EventID id)
00302 {
00303     if(OSSchedLock  > 0)         /* If scheduler is locked,(the caller is ISR) */      
00304     {
00305         /* Initiate a post service handling request */
00306         if(InsertInSRQ(SEM_REQ,id,Co_NULL) == Co_FALSE)
00307         {
00308             return E_SEV_REQ_FULL;        /* If service request queue is full */
00309         }           
00310         else                              /* Operate successfully             */
00311         {
00312             return E_OK;                        
00313         }
00314     }
00315     else
00316     {
00317         return(CoPostSem(id));            /* Post semaphore                   */
00318     }
00319 }
00320 #endif
00321 
00322 #endif