electronix79
/
CoOS_mbed
CooCox 1.1.4 on mbed with simple blinky example
Embed:
(wiki syntax)
Show/hide line numbers
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>© 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
Generated on Tue Jul 12 2022 18:19:10 by 1.7.2