CoOS Demonstrator adapted to mbed Hardware.

Dependencies:   mbed

Committer:
ericebert
Date:
Fri Dec 03 19:45:30 2010 +0000
Revision:
0:57690853989a
Some basic LED-Flashing works in the CoOS-RTOS using Tasks

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ericebert 0:57690853989a 1 /**
ericebert 0:57690853989a 2 *******************************************************************************
ericebert 0:57690853989a 3 * @file sem.c
ericebert 0:57690853989a 4 * @version V1.1.3
ericebert 0:57690853989a 5 * @date 2010.04.26
ericebert 0:57690853989a 6 * @brief Semaphore management implementation code of CooCox CoOS kernel.
ericebert 0:57690853989a 7 *******************************************************************************
ericebert 0:57690853989a 8 * @copy
ericebert 0:57690853989a 9 *
ericebert 0:57690853989a 10 * INTERNAL FILE,DON'T PUBLIC.
ericebert 0:57690853989a 11 *
ericebert 0:57690853989a 12 * <h2><center>&copy; COPYRIGHT 2009 CooCox </center></h2>
ericebert 0:57690853989a 13 *******************************************************************************
ericebert 0:57690853989a 14 */
ericebert 0:57690853989a 15
ericebert 0:57690853989a 16
ericebert 0:57690853989a 17 /*---------------------------- Include ---------------------------------------*/
ericebert 0:57690853989a 18 #include <coocox.h>
ericebert 0:57690853989a 19
ericebert 0:57690853989a 20 #if CFG_SEM_EN >0
ericebert 0:57690853989a 21
ericebert 0:57690853989a 22 /**
ericebert 0:57690853989a 23 *******************************************************************************
ericebert 0:57690853989a 24 * @brief Create a semaphore
ericebert 0:57690853989a 25 * @param[in] initCnt Semaphore valid counter.
ericebert 0:57690853989a 26 * @param[in] maxCnt Semaphore max initialize counter.
ericebert 0:57690853989a 27 * @param[in] sortType Semaphore sort type.
ericebert 0:57690853989a 28 * @param[out] None
ericebert 0:57690853989a 29 * @retval E_CREATE_FAIL Create semaphore fail.
ericebert 0:57690853989a 30 * @retval others Create semaphore successful.
ericebert 0:57690853989a 31 *
ericebert 0:57690853989a 32 * @par Description
ericebert 0:57690853989a 33 * @details This function is called to create a semaphore.
ericebert 0:57690853989a 34 *******************************************************************************
ericebert 0:57690853989a 35 */
ericebert 0:57690853989a 36 OS_EventID CoCreateSem(U16 initCnt,U16 maxCnt,U8 sortType)
ericebert 0:57690853989a 37 {
ericebert 0:57690853989a 38 P_ECB pecb;
ericebert 0:57690853989a 39 #if CFG_PAR_CHECKOUT_EN >0
ericebert 0:57690853989a 40 if(initCnt > maxCnt)
ericebert 0:57690853989a 41 {
ericebert 0:57690853989a 42 return E_CREATE_FAIL; /* Invalid 'initCnt' or 'maxCnt' */
ericebert 0:57690853989a 43 }
ericebert 0:57690853989a 44
ericebert 0:57690853989a 45 if ((sortType != EVENT_SORT_TYPE_FIFO) && (sortType != EVENT_SORT_TYPE_PRIO))
ericebert 0:57690853989a 46 {
ericebert 0:57690853989a 47 return E_CREATE_FAIL; /* Illegal sort type,return error */
ericebert 0:57690853989a 48 }
ericebert 0:57690853989a 49 #endif
ericebert 0:57690853989a 50
ericebert 0:57690853989a 51 /* Create a semaphore type event control block */
ericebert 0:57690853989a 52 pecb = CreatEvent(EVENT_TYPE_SEM,sortType,0);
ericebert 0:57690853989a 53 if(pecb == 0) /* If failed to create event block */
ericebert 0:57690853989a 54 {
ericebert 0:57690853989a 55 return E_CREATE_FAIL;
ericebert 0:57690853989a 56 }
ericebert 0:57690853989a 57 pecb->eventCounter = initCnt;/* Initialize event block */
ericebert 0:57690853989a 58 pecb->initialEventCounter = maxCnt;
ericebert 0:57690853989a 59 return (pecb->id); /* Return event id */
ericebert 0:57690853989a 60 }
ericebert 0:57690853989a 61
ericebert 0:57690853989a 62
ericebert 0:57690853989a 63 /**
ericebert 0:57690853989a 64 *******************************************************************************
ericebert 0:57690853989a 65 * @brief Delete a semaphore
ericebert 0:57690853989a 66 * @param[in] id Event ID which to be deleted.
ericebert 0:57690853989a 67 * @param[in] opt Delete option.
ericebert 0:57690853989a 68 * @arg == OPT_DEL_ANYWAY Delete semaphore always
ericebert 0:57690853989a 69 * @arg == OPT_DEL_NO_PEND Delete semaphore only when no task pending on.
ericebert 0:57690853989a 70 * @param[out] None
ericebert 0:57690853989a 71 * @retval E_INVALID_ID Invalid event ID.
ericebert 0:57690853989a 72 * @retval E_INVALID_PARAMETER Invalid parameter.
ericebert 0:57690853989a 73 * @retval E_TASK_WAITTING Tasks waitting for the event,delete fail.
ericebert 0:57690853989a 74 * @retval E_OK Event deleted successful.
ericebert 0:57690853989a 75 *
ericebert 0:57690853989a 76 * @par Description
ericebert 0:57690853989a 77 * @details This function is called to delete a semaphore.
ericebert 0:57690853989a 78 *
ericebert 0:57690853989a 79 * @note
ericebert 0:57690853989a 80 *******************************************************************************
ericebert 0:57690853989a 81 */
ericebert 0:57690853989a 82 StatusType CoDelSem(OS_EventID id,U8 opt)
ericebert 0:57690853989a 83 {
ericebert 0:57690853989a 84 P_ECB pecb;
ericebert 0:57690853989a 85
ericebert 0:57690853989a 86 #if CFG_PAR_CHECKOUT_EN >0
ericebert 0:57690853989a 87 if(id >= CFG_MAX_EVENT)
ericebert 0:57690853989a 88 {
ericebert 0:57690853989a 89 return E_INVALID_ID;
ericebert 0:57690853989a 90 }
ericebert 0:57690853989a 91 #endif
ericebert 0:57690853989a 92
ericebert 0:57690853989a 93 pecb = &EventTbl[id];
ericebert 0:57690853989a 94
ericebert 0:57690853989a 95 #if CFG_PAR_CHECKOUT_EN >0
ericebert 0:57690853989a 96 if(pecb->eventType != EVENT_TYPE_SEM)
ericebert 0:57690853989a 97 {
ericebert 0:57690853989a 98 return E_INVALID_ID; /* The event type is not semaphore */
ericebert 0:57690853989a 99 }
ericebert 0:57690853989a 100 #endif
ericebert 0:57690853989a 101
ericebert 0:57690853989a 102 return (DeleteEvent(pecb,opt));/* Delete the semaphore event control block*/
ericebert 0:57690853989a 103 }
ericebert 0:57690853989a 104
ericebert 0:57690853989a 105
ericebert 0:57690853989a 106 /**
ericebert 0:57690853989a 107 *******************************************************************************
ericebert 0:57690853989a 108 * @brief Accept a semaphore without waitting
ericebert 0:57690853989a 109 * @param[in] id Event ID
ericebert 0:57690853989a 110 * @param[out] None
ericebert 0:57690853989a 111 * @retval E_INVALID_ID Invalid event ID.
ericebert 0:57690853989a 112 * @retval E_SEM_EMPTY No semaphore exist.
ericebert 0:57690853989a 113 * @retval E_OK Get semaphore successful.
ericebert 0:57690853989a 114 *
ericebert 0:57690853989a 115 * @par Description
ericebert 0:57690853989a 116 * @details This function is called accept a semaphore without waitting.
ericebert 0:57690853989a 117 *******************************************************************************
ericebert 0:57690853989a 118 */
ericebert 0:57690853989a 119 StatusType CoAcceptSem(OS_EventID id)
ericebert 0:57690853989a 120 {
ericebert 0:57690853989a 121 P_ECB pecb;
ericebert 0:57690853989a 122 #if CFG_PAR_CHECKOUT_EN >0
ericebert 0:57690853989a 123 if(id >= CFG_MAX_EVENT)
ericebert 0:57690853989a 124 {
ericebert 0:57690853989a 125 return E_INVALID_ID;
ericebert 0:57690853989a 126 }
ericebert 0:57690853989a 127 #endif
ericebert 0:57690853989a 128
ericebert 0:57690853989a 129 pecb = &EventTbl[id];
ericebert 0:57690853989a 130 #if CFG_PAR_CHECKOUT_EN >0
ericebert 0:57690853989a 131 if( pecb->eventType != EVENT_TYPE_SEM)
ericebert 0:57690853989a 132 {
ericebert 0:57690853989a 133 return E_INVALID_ID;
ericebert 0:57690853989a 134 }
ericebert 0:57690853989a 135 #endif
ericebert 0:57690853989a 136 OsSchedLock();
ericebert 0:57690853989a 137 if(pecb->eventCounter > 0) /* If semaphore is positive,resource available */
ericebert 0:57690853989a 138 {
ericebert 0:57690853989a 139 OsSchedUnlock();
ericebert 0:57690853989a 140 pecb->eventCounter--; /* Decrement semaphore only if positive */
ericebert 0:57690853989a 141 return E_OK;
ericebert 0:57690853989a 142 }
ericebert 0:57690853989a 143 else /* Resource is not available */
ericebert 0:57690853989a 144 {
ericebert 0:57690853989a 145 OsSchedUnlock();
ericebert 0:57690853989a 146 return E_SEM_EMPTY;
ericebert 0:57690853989a 147 }
ericebert 0:57690853989a 148 }
ericebert 0:57690853989a 149
ericebert 0:57690853989a 150
ericebert 0:57690853989a 151 /**
ericebert 0:57690853989a 152 *******************************************************************************
ericebert 0:57690853989a 153 * @brief wait for a semaphore
ericebert 0:57690853989a 154 * @param[in] id Event ID.
ericebert 0:57690853989a 155 * @param[in] timeout The longest time for writting semaphore.
ericebert 0:57690853989a 156 * @para 0
ericebert 0:57690853989a 157 * @para 0x1~0xff
ericebert 0:57690853989a 158 * @param[out] None
ericebert 0:57690853989a 159 * @retval E_CALL Error call in ISR.
ericebert 0:57690853989a 160 * @retval E_INVALID_ID Invalid event ID.
ericebert 0:57690853989a 161 * @retval E_TIMEOUT Semaphore was not received within the specified
ericebert 0:57690853989a 162 * 'timeout' time.
ericebert 0:57690853989a 163 * @retval E_OK The call was successful and your task owns the
ericebert 0:57690853989a 164 * resource,or the event you are waiting for occurred.
ericebert 0:57690853989a 165 *
ericebert 0:57690853989a 166 * @par Description
ericebert 0:57690853989a 167 * @details This function is called to waits for a semaphore.
ericebert 0:57690853989a 168 * @note IF this function is called in ISR,nothing to do and return immediately.
ericebert 0:57690853989a 169 *******************************************************************************
ericebert 0:57690853989a 170 */
ericebert 0:57690853989a 171 StatusType CoPendSem(OS_EventID id,U32 timeout)
ericebert 0:57690853989a 172 {
ericebert 0:57690853989a 173 P_ECB pecb;
ericebert 0:57690853989a 174 P_OSTCB curTCB;
ericebert 0:57690853989a 175 if(OSIntNesting > 0) /* If the caller is ISR */
ericebert 0:57690853989a 176 {
ericebert 0:57690853989a 177 return E_CALL;
ericebert 0:57690853989a 178 }
ericebert 0:57690853989a 179 #if CFG_PAR_CHECKOUT_EN >0
ericebert 0:57690853989a 180 if(id >= CFG_MAX_EVENT)
ericebert 0:57690853989a 181 {
ericebert 0:57690853989a 182 return E_INVALID_ID;
ericebert 0:57690853989a 183 }
ericebert 0:57690853989a 184 #endif
ericebert 0:57690853989a 185
ericebert 0:57690853989a 186 pecb = &EventTbl[id];
ericebert 0:57690853989a 187 #if CFG_PAR_CHECKOUT_EN >0
ericebert 0:57690853989a 188 if(pecb->eventType != EVENT_TYPE_SEM)
ericebert 0:57690853989a 189 {
ericebert 0:57690853989a 190 return E_INVALID_ID;
ericebert 0:57690853989a 191 }
ericebert 0:57690853989a 192 #endif
ericebert 0:57690853989a 193 if(OSSchedLock != 0) /* Schdule is locked? */
ericebert 0:57690853989a 194 {
ericebert 0:57690853989a 195 return E_OS_IN_LOCK; /* Yes,error return */
ericebert 0:57690853989a 196 }
ericebert 0:57690853989a 197 if(pecb->eventCounter > 0) /* If semaphore is positive,resource available */
ericebert 0:57690853989a 198 {
ericebert 0:57690853989a 199 pecb->eventCounter--; /* Decrement semaphore only if positive */
ericebert 0:57690853989a 200 return E_OK;
ericebert 0:57690853989a 201 }
ericebert 0:57690853989a 202 else /* Resource is not available */
ericebert 0:57690853989a 203 {
ericebert 0:57690853989a 204 curTCB = TCBRunning;
ericebert 0:57690853989a 205 if(timeout == 0) /* If time-out is not configured */
ericebert 0:57690853989a 206 {
ericebert 0:57690853989a 207 EventTaskToWait(pecb,curTCB); /* Block task until event occurs */
ericebert 0:57690853989a 208 curTCB->pmail = 0;
ericebert 0:57690853989a 209 return E_OK;
ericebert 0:57690853989a 210 }
ericebert 0:57690853989a 211 else /* If time-out is configured */
ericebert 0:57690853989a 212 {
ericebert 0:57690853989a 213 OsSchedLock();
ericebert 0:57690853989a 214
ericebert 0:57690853989a 215 /* Block task until event or timeout occurs */
ericebert 0:57690853989a 216 EventTaskToWait(pecb,curTCB);
ericebert 0:57690853989a 217 InsertDelayList(curTCB,timeout);
ericebert 0:57690853989a 218
ericebert 0:57690853989a 219 OsSchedUnlock();
ericebert 0:57690853989a 220 if (curTCB->pmail == 0) /* If pmail is 0, time-out occurred*/
ericebert 0:57690853989a 221 {
ericebert 0:57690853989a 222 return E_TIMEOUT;
ericebert 0:57690853989a 223 }
ericebert 0:57690853989a 224 else /* Event occurred or event have been deleted*/
ericebert 0:57690853989a 225 {
ericebert 0:57690853989a 226 curTCB->pmail = 0;
ericebert 0:57690853989a 227 return E_OK;
ericebert 0:57690853989a 228 }
ericebert 0:57690853989a 229 }
ericebert 0:57690853989a 230 }
ericebert 0:57690853989a 231 }
ericebert 0:57690853989a 232
ericebert 0:57690853989a 233
ericebert 0:57690853989a 234 /**
ericebert 0:57690853989a 235 *******************************************************************************
ericebert 0:57690853989a 236 * @brief Post a semaphore
ericebert 0:57690853989a 237 * @param[in] id id of event control block associated with the desired semaphore.
ericebert 0:57690853989a 238 * @param[out] None
ericebert 0:57690853989a 239 * @retval E_INVALID_ID Parameter id passed was invalid event ID.
ericebert 0:57690853989a 240 * @retval E_SEM_FULL Semaphore full.
ericebert 0:57690853989a 241 * @retval E_OK Semaphore had post successful.
ericebert 0:57690853989a 242 *
ericebert 0:57690853989a 243 * @par Description
ericebert 0:57690853989a 244 * @details This function is called to post a semaphore to corresponding event.
ericebert 0:57690853989a 245 *
ericebert 0:57690853989a 246 * @note
ericebert 0:57690853989a 247 *******************************************************************************
ericebert 0:57690853989a 248 */
ericebert 0:57690853989a 249 StatusType CoPostSem(OS_EventID id)
ericebert 0:57690853989a 250 {
ericebert 0:57690853989a 251 P_ECB pecb;
ericebert 0:57690853989a 252 #if CFG_PAR_CHECKOUT_EN >0
ericebert 0:57690853989a 253 if(id >= CFG_MAX_EVENT)
ericebert 0:57690853989a 254 {
ericebert 0:57690853989a 255 return E_INVALID_ID;
ericebert 0:57690853989a 256 }
ericebert 0:57690853989a 257 #endif
ericebert 0:57690853989a 258
ericebert 0:57690853989a 259 pecb = &EventTbl[id];
ericebert 0:57690853989a 260 #if CFG_PAR_CHECKOUT_EN >0
ericebert 0:57690853989a 261 if(pecb->eventType != EVENT_TYPE_SEM) /* Invalid event control block type */
ericebert 0:57690853989a 262 {
ericebert 0:57690853989a 263 return E_INVALID_ID;
ericebert 0:57690853989a 264 }
ericebert 0:57690853989a 265 #endif
ericebert 0:57690853989a 266
ericebert 0:57690853989a 267 /* Make sure semaphore will not overflow */
ericebert 0:57690853989a 268 if(pecb->eventCounter == pecb->initialEventCounter)
ericebert 0:57690853989a 269 {
ericebert 0:57690853989a 270 return E_SEM_FULL; /* The counter of Semaphore reach the max number*/
ericebert 0:57690853989a 271 }
ericebert 0:57690853989a 272 OsSchedLock();
ericebert 0:57690853989a 273 pecb->eventCounter++; /* Increment semaphore count to register event */
ericebert 0:57690853989a 274 EventTaskToRdy(pecb); /* Check semaphore event waiting list */
ericebert 0:57690853989a 275 OsSchedUnlock();
ericebert 0:57690853989a 276 return E_OK;
ericebert 0:57690853989a 277
ericebert 0:57690853989a 278 }
ericebert 0:57690853989a 279
ericebert 0:57690853989a 280
ericebert 0:57690853989a 281 /**
ericebert 0:57690853989a 282 *******************************************************************************
ericebert 0:57690853989a 283 * @brief Post a semaphore in ISR
ericebert 0:57690853989a 284 * @param[in] id identifier of event control block associated with the
ericebert 0:57690853989a 285 * desired semaphore.
ericebert 0:57690853989a 286 * @param[out] None
ericebert 0:57690853989a 287 * @retval E_INVALID_ID Parameter id passed was invalid event ID.
ericebert 0:57690853989a 288 * @retval E_NO_TASK_WAITTING There are one more tasks waitting for the event.
ericebert 0:57690853989a 289 * @retval E_OK Semaphore had signaled successful.
ericebert 0:57690853989a 290 *
ericebert 0:57690853989a 291 * @par Description
ericebert 0:57690853989a 292 * @details This function is called in ISR to post a semaphore to corresponding
ericebert 0:57690853989a 293 * event.
ericebert 0:57690853989a 294 * @note
ericebert 0:57690853989a 295 *******************************************************************************
ericebert 0:57690853989a 296 */
ericebert 0:57690853989a 297 #if CFG_MAX_SERVICE_REQUEST > 0
ericebert 0:57690853989a 298 StatusType isr_PostSem(OS_EventID id)
ericebert 0:57690853989a 299 {
ericebert 0:57690853989a 300 if(OSSchedLock > 0) /* If scheduler is locked,(the caller is ISR) */
ericebert 0:57690853989a 301 {
ericebert 0:57690853989a 302 /* Initiate a post service handling request */
ericebert 0:57690853989a 303 if(InsertInSRQ(SEM_REQ,id,0) == FALSE)
ericebert 0:57690853989a 304 {
ericebert 0:57690853989a 305 return E_SEV_REQ_FULL; /* If service request queue is full */
ericebert 0:57690853989a 306 }
ericebert 0:57690853989a 307 else /* Operate successfully */
ericebert 0:57690853989a 308 {
ericebert 0:57690853989a 309 return E_OK;
ericebert 0:57690853989a 310 }
ericebert 0:57690853989a 311 }
ericebert 0:57690853989a 312 else
ericebert 0:57690853989a 313 {
ericebert 0:57690853989a 314 return(CoPostSem(id)); /* Post semaphore */
ericebert 0:57690853989a 315 }
ericebert 0:57690853989a 316 }
ericebert 0:57690853989a 317 #endif
ericebert 0:57690853989a 318
ericebert 0:57690853989a 319 #endif