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 mbox.c
ericebert 0:57690853989a 4 * @version V1.1.3
ericebert 0:57690853989a 5 * @date 2010.04.26
ericebert 0:57690853989a 6 * @brief Mailbox 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 /*---------------------------- Include ---------------------------------------*/
ericebert 0:57690853989a 17 #include <coocox.h>
ericebert 0:57690853989a 18
ericebert 0:57690853989a 19
ericebert 0:57690853989a 20 #if CFG_MAILBOX_EN > 0
ericebert 0:57690853989a 21
ericebert 0:57690853989a 22
ericebert 0:57690853989a 23 /**
ericebert 0:57690853989a 24 *******************************************************************************
ericebert 0:57690853989a 25 * @brief Create a mailbox
ericebert 0:57690853989a 26 * @param[in] sortType Mail box waiting list sort type.
ericebert 0:57690853989a 27 * @param[out] None
ericebert 0:57690853989a 28 * @retval E_CREATE_FAIL Create mailbox fail.
ericebert 0:57690853989a 29 * @retval others Create mailbox successful.
ericebert 0:57690853989a 30 *
ericebert 0:57690853989a 31 * @par Description
ericebert 0:57690853989a 32 * @details This function is called to create a mailbox.
ericebert 0:57690853989a 33 * @note
ericebert 0:57690853989a 34 *******************************************************************************
ericebert 0:57690853989a 35 */
ericebert 0:57690853989a 36 OS_EventID CoCreateMbox(U8 sortType)
ericebert 0:57690853989a 37 {
ericebert 0:57690853989a 38 P_ECB pecb;
ericebert 0:57690853989a 39
ericebert 0:57690853989a 40 /* Create a mailbox type event control block */
ericebert 0:57690853989a 41 pecb = CreatEvent(EVENT_TYPE_MBOX,sortType,0);
ericebert 0:57690853989a 42 if(pecb == 0) /* If failed to create event block */
ericebert 0:57690853989a 43 {
ericebert 0:57690853989a 44 return E_CREATE_FAIL;
ericebert 0:57690853989a 45 }
ericebert 0:57690853989a 46 pecb->eventCounter = 0;
ericebert 0:57690853989a 47 return (pecb->id); /* Create a mailbox successfully, return event ID */
ericebert 0:57690853989a 48 }
ericebert 0:57690853989a 49
ericebert 0:57690853989a 50
ericebert 0:57690853989a 51
ericebert 0:57690853989a 52 /**
ericebert 0:57690853989a 53 *******************************************************************************
ericebert 0:57690853989a 54 * @brief Delete a mailbox
ericebert 0:57690853989a 55 * @param[in] id Event ID.
ericebert 0:57690853989a 56 * @param[in] opt Delete option.
ericebert 0:57690853989a 57 * @param[out] None
ericebert 0:57690853989a 58 * @retval E_INVALID_ID Invalid event ID.
ericebert 0:57690853989a 59 * @retval E_INVALID_PARAMETER Invalid parameter.
ericebert 0:57690853989a 60 * @retval E_TASK_WAITTING Tasks waitting for the event,delete fail.
ericebert 0:57690853989a 61 * @retval E_OK Event deleted successful.
ericebert 0:57690853989a 62 *
ericebert 0:57690853989a 63 * @par Description
ericebert 0:57690853989a 64 * @details This function is called to delete a mailbox.
ericebert 0:57690853989a 65 * @note
ericebert 0:57690853989a 66 *******************************************************************************
ericebert 0:57690853989a 67 */
ericebert 0:57690853989a 68 StatusType CoDelMbox(OS_EventID id,U8 opt)
ericebert 0:57690853989a 69 {
ericebert 0:57690853989a 70 P_ECB pecb;
ericebert 0:57690853989a 71
ericebert 0:57690853989a 72 #if CFG_PAR_CHECKOUT_EN >0
ericebert 0:57690853989a 73 if(id >= CFG_MAX_EVENT) /* Judge id is valid or not? */
ericebert 0:57690853989a 74 {
ericebert 0:57690853989a 75 return E_INVALID_ID; /* Id is invalid ,return error */
ericebert 0:57690853989a 76 }
ericebert 0:57690853989a 77 #endif
ericebert 0:57690853989a 78 pecb = &EventTbl[id];
ericebert 0:57690853989a 79 #if CFG_PAR_CHECKOUT_EN >0
ericebert 0:57690853989a 80 if(pecb->eventType != EVENT_TYPE_MBOX)/* Validate event control block type*/
ericebert 0:57690853989a 81 {
ericebert 0:57690853989a 82 return E_INVALID_ID; /* The event is not mailbox */
ericebert 0:57690853989a 83 }
ericebert 0:57690853989a 84 #endif
ericebert 0:57690853989a 85 return (DeleteEvent(pecb,opt)); /* Delete the mailbox event control block */
ericebert 0:57690853989a 86 }
ericebert 0:57690853989a 87
ericebert 0:57690853989a 88
ericebert 0:57690853989a 89
ericebert 0:57690853989a 90 /**
ericebert 0:57690853989a 91 *******************************************************************************
ericebert 0:57690853989a 92 * @brief Accept a mailbox
ericebert 0:57690853989a 93 * @param[in] id Event ID.
ericebert 0:57690853989a 94 * @param[out] perr A pointer to error code.
ericebert 0:57690853989a 95 * @retval 0
ericebert 0:57690853989a 96 * @retval A pointer to mailbox accepted.
ericebert 0:57690853989a 97 *
ericebert 0:57690853989a 98 * @par Description
ericebert 0:57690853989a 99 * @details This function is called to accept a mailbox.
ericebert 0:57690853989a 100 * @note
ericebert 0:57690853989a 101 *******************************************************************************
ericebert 0:57690853989a 102 */
ericebert 0:57690853989a 103 void* CoAcceptMail(OS_EventID id,StatusType* perr)
ericebert 0:57690853989a 104 {
ericebert 0:57690853989a 105 P_ECB pecb;
ericebert 0:57690853989a 106 void* pmail;
ericebert 0:57690853989a 107 #if CFG_PAR_CHECKOUT_EN >0
ericebert 0:57690853989a 108 if(id >= CFG_MAX_EVENT)
ericebert 0:57690853989a 109 {
ericebert 0:57690853989a 110 *perr = E_INVALID_ID; /* Invalid 'id' */
ericebert 0:57690853989a 111 return 0;
ericebert 0:57690853989a 112 }
ericebert 0:57690853989a 113 #endif
ericebert 0:57690853989a 114 pecb = &EventTbl[id];
ericebert 0:57690853989a 115
ericebert 0:57690853989a 116 #if CFG_PAR_CHECKOUT_EN >0
ericebert 0:57690853989a 117 if(pecb->eventType != EVENT_TYPE_MBOX)/* Invalid event control block type */
ericebert 0:57690853989a 118 {
ericebert 0:57690853989a 119 *perr = E_INVALID_ID;
ericebert 0:57690853989a 120 return 0;
ericebert 0:57690853989a 121 }
ericebert 0:57690853989a 122 #endif
ericebert 0:57690853989a 123 OsSchedLock();
ericebert 0:57690853989a 124 if(pecb->eventCounter == 1) /* If there is already a message */
ericebert 0:57690853989a 125 {
ericebert 0:57690853989a 126 *perr = E_OK;
ericebert 0:57690853989a 127 pmail = pecb->eventPtr; /* Get the message */
ericebert 0:57690853989a 128 pecb->eventPtr = 0; /* Clear the mailbox */
ericebert 0:57690853989a 129 pecb->eventCounter = 0;
ericebert 0:57690853989a 130 OsSchedUnlock();
ericebert 0:57690853989a 131 return pmail; /* Return the message received */
ericebert 0:57690853989a 132 }
ericebert 0:57690853989a 133 else /* If the mailbox is empty */
ericebert 0:57690853989a 134 {
ericebert 0:57690853989a 135 OsSchedUnlock();
ericebert 0:57690853989a 136 *perr = E_MBOX_EMPTY; /* Mailbox is empty,return 0 */
ericebert 0:57690853989a 137 return 0;
ericebert 0:57690853989a 138 }
ericebert 0:57690853989a 139 }
ericebert 0:57690853989a 140
ericebert 0:57690853989a 141
ericebert 0:57690853989a 142
ericebert 0:57690853989a 143 /**
ericebert 0:57690853989a 144 *******************************************************************************
ericebert 0:57690853989a 145 * @brief Wait for a mailbox
ericebert 0:57690853989a 146 * @param[in] id Event ID.
ericebert 0:57690853989a 147 * @param[in] timeout The longest time for writting mail.
ericebert 0:57690853989a 148 * @param[out] perr A pointer to error code.
ericebert 0:57690853989a 149 * @retval 0
ericebert 0:57690853989a 150 * @retval A pointer to mailbox accept.
ericebert 0:57690853989a 151 *
ericebert 0:57690853989a 152 * @par Description
ericebert 0:57690853989a 153 * @details This function is called to wait a mailbox.
ericebert 0:57690853989a 154 * @note
ericebert 0:57690853989a 155 *******************************************************************************
ericebert 0:57690853989a 156 */
ericebert 0:57690853989a 157 void* CoPendMail(OS_EventID id,U32 timeout,StatusType* perr)
ericebert 0:57690853989a 158 {
ericebert 0:57690853989a 159 P_ECB pecb;
ericebert 0:57690853989a 160 void* pmail;
ericebert 0:57690853989a 161 P_OSTCB curTCB;
ericebert 0:57690853989a 162
ericebert 0:57690853989a 163 if(OSIntNesting > 0) /* If the caller is ISR */
ericebert 0:57690853989a 164 {
ericebert 0:57690853989a 165 *perr = E_CALL;
ericebert 0:57690853989a 166 return 0;
ericebert 0:57690853989a 167 }
ericebert 0:57690853989a 168
ericebert 0:57690853989a 169 #if CFG_PAR_CHECKOUT_EN >0
ericebert 0:57690853989a 170 if(id >= CFG_MAX_EVENT)
ericebert 0:57690853989a 171 {
ericebert 0:57690853989a 172 *perr = E_INVALID_ID; /* Invalid 'id',retrun error */
ericebert 0:57690853989a 173 return 0;
ericebert 0:57690853989a 174 }
ericebert 0:57690853989a 175 #endif
ericebert 0:57690853989a 176
ericebert 0:57690853989a 177 pecb = &EventTbl[id];
ericebert 0:57690853989a 178 #if CFG_PAR_CHECKOUT_EN >0
ericebert 0:57690853989a 179 if(pecb->eventType != EVENT_TYPE_MBOX)
ericebert 0:57690853989a 180 {
ericebert 0:57690853989a 181 *perr = E_INVALID_ID; /* Invalid event type,not EVENT_TYPE_MBOX */
ericebert 0:57690853989a 182 return 0;
ericebert 0:57690853989a 183 }
ericebert 0:57690853989a 184 #endif
ericebert 0:57690853989a 185
ericebert 0:57690853989a 186 if(OSSchedLock != 0) /* Judge schedule is locked or not? */
ericebert 0:57690853989a 187 {
ericebert 0:57690853989a 188 *perr = E_OS_IN_LOCK; /* Schedule is locked */
ericebert 0:57690853989a 189 return 0; /* return 0 */
ericebert 0:57690853989a 190 }
ericebert 0:57690853989a 191 if( pecb->eventCounter == 1) /* If there is already a message */
ericebert 0:57690853989a 192 {
ericebert 0:57690853989a 193 *perr = E_OK;
ericebert 0:57690853989a 194 pmail = pecb->eventPtr; /* Get the message */
ericebert 0:57690853989a 195 pecb->eventPtr = 0; /* Clear the mailbox */
ericebert 0:57690853989a 196 pecb->eventCounter = 0;
ericebert 0:57690853989a 197 return pmail; /* Return the message received */
ericebert 0:57690853989a 198 }
ericebert 0:57690853989a 199 else /* If message is not available, task will pend */
ericebert 0:57690853989a 200 {
ericebert 0:57690853989a 201 curTCB = TCBRunning;
ericebert 0:57690853989a 202 if(timeout == 0) /* If time-out is not configured */
ericebert 0:57690853989a 203 {
ericebert 0:57690853989a 204 EventTaskToWait(pecb,curTCB); /* Block task until event occurs */
ericebert 0:57690853989a 205 *perr = E_OK;
ericebert 0:57690853989a 206
ericebert 0:57690853989a 207 /* Have recived a message or the mailbox have been deleted */
ericebert 0:57690853989a 208 pmail = curTCB->pmail;
ericebert 0:57690853989a 209 curTCB->pmail = 0;
ericebert 0:57690853989a 210 return pmail; /* Return received message or 0 */
ericebert 0:57690853989a 211 }
ericebert 0:57690853989a 212 else /* If time-out is configured */
ericebert 0:57690853989a 213 {
ericebert 0:57690853989a 214 OsSchedLock();
ericebert 0:57690853989a 215
ericebert 0:57690853989a 216 /* Block task until event or timeout occurs */
ericebert 0:57690853989a 217 EventTaskToWait(pecb,curTCB);
ericebert 0:57690853989a 218 InsertDelayList(curTCB,timeout);
ericebert 0:57690853989a 219 OsSchedUnlock();
ericebert 0:57690853989a 220 if( curTCB->pmail == 0) /* Time-out occurred */
ericebert 0:57690853989a 221 {
ericebert 0:57690853989a 222 *perr = E_TIMEOUT;
ericebert 0:57690853989a 223 return 0;
ericebert 0:57690853989a 224 }
ericebert 0:57690853989a 225 else /* Have recived a message or the mailbox have been deleted*/
ericebert 0:57690853989a 226 {
ericebert 0:57690853989a 227 *perr = E_OK;
ericebert 0:57690853989a 228 pmail = curTCB->pmail;
ericebert 0:57690853989a 229 curTCB->pmail = 0;
ericebert 0:57690853989a 230 return pmail; /* Return received message or 0 */
ericebert 0:57690853989a 231 }
ericebert 0:57690853989a 232 }
ericebert 0:57690853989a 233 }
ericebert 0:57690853989a 234 }
ericebert 0:57690853989a 235
ericebert 0:57690853989a 236
ericebert 0:57690853989a 237 /**
ericebert 0:57690853989a 238 *******************************************************************************
ericebert 0:57690853989a 239 * @brief Post a mailbox
ericebert 0:57690853989a 240 * @param[in] id Event ID.
ericebert 0:57690853989a 241 * @param[in] pmail Pointer to mail that want to send.
ericebert 0:57690853989a 242 * @param[out] None
ericebert 0:57690853989a 243 * @retval E_INVALID_ID
ericebert 0:57690853989a 244 * @retval E_OK
ericebert 0:57690853989a 245 *
ericebert 0:57690853989a 246 * @par Description
ericebert 0:57690853989a 247 * @details This function is called to post a mail.
ericebert 0:57690853989a 248 * @note
ericebert 0:57690853989a 249 *******************************************************************************
ericebert 0:57690853989a 250 */
ericebert 0:57690853989a 251 StatusType CoPostMail(OS_EventID id,void* pmail)
ericebert 0:57690853989a 252 {
ericebert 0:57690853989a 253 P_ECB pecb;
ericebert 0:57690853989a 254 #if CFG_PAR_CHECKOUT_EN >0
ericebert 0:57690853989a 255 if(id >= CFG_MAX_EVENT)
ericebert 0:57690853989a 256 {
ericebert 0:57690853989a 257 return E_INVALID_ID; /* Invalid id,return error */
ericebert 0:57690853989a 258 }
ericebert 0:57690853989a 259 #endif
ericebert 0:57690853989a 260
ericebert 0:57690853989a 261 pecb = &EventTbl[id];
ericebert 0:57690853989a 262 #if CFG_PAR_CHECKOUT_EN >0
ericebert 0:57690853989a 263 if(pecb->eventType != EVENT_TYPE_MBOX)/* Validate event control block type*/
ericebert 0:57690853989a 264 {
ericebert 0:57690853989a 265 return E_INVALID_ID; /* Event is not mailbox,return error*/
ericebert 0:57690853989a 266 }
ericebert 0:57690853989a 267 #endif
ericebert 0:57690853989a 268
ericebert 0:57690853989a 269 if(pecb->eventCounter == 0) /* If mailbox doesn't already have a message*/
ericebert 0:57690853989a 270 {
ericebert 0:57690853989a 271 OsSchedLock();
ericebert 0:57690853989a 272 pecb->eventPtr = pmail; /* Place message in mailbox */
ericebert 0:57690853989a 273 pecb->eventCounter = 1;
ericebert 0:57690853989a 274 EventTaskToRdy(pecb); /* Check waiting list */
ericebert 0:57690853989a 275 OsSchedUnlock();
ericebert 0:57690853989a 276 return E_OK;
ericebert 0:57690853989a 277 }
ericebert 0:57690853989a 278 else /* If there is already a message in mailbox */
ericebert 0:57690853989a 279 {
ericebert 0:57690853989a 280 return E_MBOX_FULL; /* Mailbox is full,and return "E_MBOX_FULL" */
ericebert 0:57690853989a 281 }
ericebert 0:57690853989a 282 }
ericebert 0:57690853989a 283
ericebert 0:57690853989a 284 /**
ericebert 0:57690853989a 285 *******************************************************************************
ericebert 0:57690853989a 286 * @brief Post a mailbox in ISR
ericebert 0:57690853989a 287 * @param[in] id Event ID.
ericebert 0:57690853989a 288 * @param[in] pmail Pointer to mail that want to send.
ericebert 0:57690853989a 289 * @param[out] None
ericebert 0:57690853989a 290 * @retval E_INVALID_ID
ericebert 0:57690853989a 291 * @retval E_OK
ericebert 0:57690853989a 292 *
ericebert 0:57690853989a 293 * @par Description
ericebert 0:57690853989a 294 * @details This function is called to post a mail in ISR.
ericebert 0:57690853989a 295 * @note
ericebert 0:57690853989a 296 *******************************************************************************
ericebert 0:57690853989a 297 */
ericebert 0:57690853989a 298 #if CFG_MAX_SERVICE_REQUEST > 0
ericebert 0:57690853989a 299 StatusType isr_PostMail(OS_EventID id,void* pmail)
ericebert 0:57690853989a 300 {
ericebert 0:57690853989a 301 if(OSSchedLock > 0) /* If scheduler is locked,(the caller is ISR) */
ericebert 0:57690853989a 302 {
ericebert 0:57690853989a 303 /* Insert the request into service request queue */
ericebert 0:57690853989a 304 if(InsertInSRQ(MBOX_REQ,id,pmail) == FALSE)
ericebert 0:57690853989a 305 {
ericebert 0:57690853989a 306 return E_SEV_REQ_FULL; /* If service request queue is full */
ericebert 0:57690853989a 307 }
ericebert 0:57690853989a 308 else /* Operate successfully */
ericebert 0:57690853989a 309 {
ericebert 0:57690853989a 310 return E_OK;
ericebert 0:57690853989a 311 }
ericebert 0:57690853989a 312 }
ericebert 0:57690853989a 313 else
ericebert 0:57690853989a 314 {
ericebert 0:57690853989a 315 return(CoPostMail(id,pmail)); /* Sends the message to the mailbox */
ericebert 0:57690853989a 316 }
ericebert 0:57690853989a 317 }
ericebert 0:57690853989a 318 #endif
ericebert 0:57690853989a 319
ericebert 0:57690853989a 320 #endif
ericebert 0:57690853989a 321
ericebert 0:57690853989a 322