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 flag.c
ericebert 0:57690853989a 4 * @version V1.1.3
ericebert 0:57690853989a 5 * @date 2010.04.26
ericebert 0:57690853989a 6 * @brief Flag 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
ericebert 0:57690853989a 18 /*---------------------------- Include ---------------------------------------*/
ericebert 0:57690853989a 19 #include <coocox.h>
ericebert 0:57690853989a 20
ericebert 0:57690853989a 21 #if CFG_FLAG_EN > 0
ericebert 0:57690853989a 22 /*---------------------------- Variable Define -------------------------------*/
ericebert 0:57690853989a 23 #define FLAG_MAX_NUM 32 /*!< Define max flag number. */
ericebert 0:57690853989a 24 FCB FlagCrl = {0}; /*!< Flags list struct */
ericebert 0:57690853989a 25
ericebert 0:57690853989a 26
ericebert 0:57690853989a 27 /*---------------------------- Function Declare ------------------------------*/
ericebert 0:57690853989a 28 static void FlagBlock(P_FLAG_NODE pnode,U32 flags,U8 waitType);
ericebert 0:57690853989a 29 static P_FLAG_NODE RemoveFromLink(P_FLAG_NODE pnode);
ericebert 0:57690853989a 30
ericebert 0:57690853989a 31 /**
ericebert 0:57690853989a 32 *******************************************************************************
ericebert 0:57690853989a 33 * @brief Create a flag
ericebert 0:57690853989a 34 * @param[in] bAutoReset Reset mode,TRUE(Auto Reset) FLASE(Manual Reset).
ericebert 0:57690853989a 35 * @param[in] bInitialState Initial state.
ericebert 0:57690853989a 36 * @param[out] None
ericebert 0:57690853989a 37 * @retval E_CREATE_FAIL Create flag fail.
ericebert 0:57690853989a 38 * @retval others Create flag successful.
ericebert 0:57690853989a 39 *
ericebert 0:57690853989a 40 * @par Description
ericebert 0:57690853989a 41 * @details This function use to create a event flag.
ericebert 0:57690853989a 42 * @note
ericebert 0:57690853989a 43 *******************************************************************************
ericebert 0:57690853989a 44 */
ericebert 0:57690853989a 45 OS_FlagID CoCreateFlag(BOOL bAutoReset,BOOL bInitialState)
ericebert 0:57690853989a 46 {
ericebert 0:57690853989a 47 U8 i;
ericebert 0:57690853989a 48 OsSchedLock();
ericebert 0:57690853989a 49
ericebert 0:57690853989a 50 for(i=0;i<FLAG_MAX_NUM;i++)
ericebert 0:57690853989a 51 {
ericebert 0:57690853989a 52 /* Assign a free flag control block */
ericebert 0:57690853989a 53 if((FlagCrl.flagActive&(1<<i)) == 0 )
ericebert 0:57690853989a 54 {
ericebert 0:57690853989a 55 FlagCrl.flagActive |= (1<<i); /* Initialize active flag */
ericebert 0:57690853989a 56 FlagCrl.flagRdy |= (bInitialState<<i);/* Initialize ready flag */
ericebert 0:57690853989a 57 FlagCrl.resetOpt |= (bAutoReset<<i);/* Initialize reset option */
ericebert 0:57690853989a 58 OsSchedUnlock();
ericebert 0:57690853989a 59 return i ; /* Return Flag ID */
ericebert 0:57690853989a 60 }
ericebert 0:57690853989a 61 }
ericebert 0:57690853989a 62 OsSchedUnlock();
ericebert 0:57690853989a 63
ericebert 0:57690853989a 64 return E_CREATE_FAIL; /* There is no free flag control block*/
ericebert 0:57690853989a 65 }
ericebert 0:57690853989a 66
ericebert 0:57690853989a 67
ericebert 0:57690853989a 68 /**
ericebert 0:57690853989a 69 *******************************************************************************
ericebert 0:57690853989a 70 * @brief Delete a flag
ericebert 0:57690853989a 71 * @param[in] id Flag ID.
ericebert 0:57690853989a 72 * @param[in] opt Delete option.
ericebert 0:57690853989a 73 * @param[out] None
ericebert 0:57690853989a 74 * @retval E_CALL Error call in ISR.
ericebert 0:57690853989a 75 * @retval E_INVALID_ID Invalid event ID.
ericebert 0:57690853989a 76 * @retval E_TASK_WAITTING Tasks waitting for the event,delete fail.
ericebert 0:57690853989a 77 * @retval E_OK Event deleted successful.
ericebert 0:57690853989a 78 *
ericebert 0:57690853989a 79 * @par Description
ericebert 0:57690853989a 80 * @details This function is called to delete a event flag.
ericebert 0:57690853989a 81 * @note
ericebert 0:57690853989a 82 *******************************************************************************
ericebert 0:57690853989a 83 */
ericebert 0:57690853989a 84 StatusType CoDelFlag(OS_FlagID id,U8 opt)
ericebert 0:57690853989a 85 {
ericebert 0:57690853989a 86 P_FLAG_NODE pnode;
ericebert 0:57690853989a 87 P_FCB pfcb;
ericebert 0:57690853989a 88 pfcb = &FlagCrl;
ericebert 0:57690853989a 89 if(OSIntNesting > 0) /* If be called from ISR */
ericebert 0:57690853989a 90 {
ericebert 0:57690853989a 91 return E_CALL;
ericebert 0:57690853989a 92 }
ericebert 0:57690853989a 93 #if CFG_PAR_CHECKOUT_EN >0
ericebert 0:57690853989a 94 if((pfcb->flagActive&(1<<id)) == 0) /* Flag is valid or not */
ericebert 0:57690853989a 95 {
ericebert 0:57690853989a 96 return E_INVALID_ID;
ericebert 0:57690853989a 97 }
ericebert 0:57690853989a 98 #endif
ericebert 0:57690853989a 99 OsSchedLock();
ericebert 0:57690853989a 100 pnode = pfcb->headNode;
ericebert 0:57690853989a 101
ericebert 0:57690853989a 102 while(pnode != 0) /* Ready all tasks waiting for flags */
ericebert 0:57690853989a 103 {
ericebert 0:57690853989a 104 if((pnode->waitFlags&(1<<id)) != 0) /* If no task is waiting on flags */
ericebert 0:57690853989a 105 {
ericebert 0:57690853989a 106 if(opt == OPT_DEL_NO_PEND) /* Delete flag if no task waiting */
ericebert 0:57690853989a 107 {
ericebert 0:57690853989a 108 OsSchedUnlock();
ericebert 0:57690853989a 109 return E_TASK_WAITING;
ericebert 0:57690853989a 110 }
ericebert 0:57690853989a 111 else if (opt == OPT_DEL_ANYWAY) /* Always delete the flag */
ericebert 0:57690853989a 112 {
ericebert 0:57690853989a 113 if(pnode->waitType == OPT_WAIT_ALL)
ericebert 0:57690853989a 114 {
ericebert 0:57690853989a 115 /* If the flag is only required by NODE */
ericebert 0:57690853989a 116 if( pnode->waitFlags == (1<<id) )
ericebert 0:57690853989a 117 {
ericebert 0:57690853989a 118 /* Remove the NODE from waiting list */
ericebert 0:57690853989a 119 pnode = RemoveFromLink(pnode);
ericebert 0:57690853989a 120 continue;
ericebert 0:57690853989a 121 }
ericebert 0:57690853989a 122 else
ericebert 0:57690853989a 123 {
ericebert 0:57690853989a 124 pnode->waitFlags &= ~(1<<id); /* Update waitflags */
ericebert 0:57690853989a 125 }
ericebert 0:57690853989a 126 }
ericebert 0:57690853989a 127 else
ericebert 0:57690853989a 128 {
ericebert 0:57690853989a 129 pnode = RemoveFromLink(pnode);
ericebert 0:57690853989a 130 continue;
ericebert 0:57690853989a 131 }
ericebert 0:57690853989a 132 }
ericebert 0:57690853989a 133 }
ericebert 0:57690853989a 134 pnode = pnode->nextNode;
ericebert 0:57690853989a 135 }
ericebert 0:57690853989a 136
ericebert 0:57690853989a 137 /* Remove the flag from the flags list */
ericebert 0:57690853989a 138 pfcb->flagActive &= ~(1<<id);
ericebert 0:57690853989a 139 pfcb->flagRdy &= ~(1<<id);
ericebert 0:57690853989a 140 pfcb->resetOpt &= ~(1<<id);
ericebert 0:57690853989a 141 OsSchedUnlock();
ericebert 0:57690853989a 142 return E_OK;
ericebert 0:57690853989a 143 }
ericebert 0:57690853989a 144
ericebert 0:57690853989a 145
ericebert 0:57690853989a 146 /**
ericebert 0:57690853989a 147 *******************************************************************************
ericebert 0:57690853989a 148 * @brief AcceptSingleFlag
ericebert 0:57690853989a 149 * @param[in] id Flag ID.
ericebert 0:57690853989a 150 * @param[out] None
ericebert 0:57690853989a 151 * @retval E_INVALID_ID Invalid event ID.
ericebert 0:57690853989a 152 * @retval E_FLAG_NOT_READY Flag is not in ready state.
ericebert 0:57690853989a 153 * @retval E_OK The call was successful and your task owns the Flag.
ericebert 0:57690853989a 154 *
ericebert 0:57690853989a 155 * @par Description
ericebert 0:57690853989a 156 * @details This fucntion is called to accept single flag
ericebert 0:57690853989a 157 * @note
ericebert 0:57690853989a 158 *******************************************************************************
ericebert 0:57690853989a 159 */
ericebert 0:57690853989a 160 StatusType CoAcceptSingleFlag(OS_FlagID id)
ericebert 0:57690853989a 161 {
ericebert 0:57690853989a 162 P_FCB pfcb;
ericebert 0:57690853989a 163 pfcb = &FlagCrl;
ericebert 0:57690853989a 164 #if CFG_PAR_CHECKOUT_EN >0
ericebert 0:57690853989a 165 if(id >= FLAG_MAX_NUM)
ericebert 0:57690853989a 166 {
ericebert 0:57690853989a 167 return E_INVALID_ID; /* Invalid 'id',return error */
ericebert 0:57690853989a 168 }
ericebert 0:57690853989a 169 if((pfcb->flagActive&(1<<id)) == 0)
ericebert 0:57690853989a 170 {
ericebert 0:57690853989a 171 return E_INVALID_ID; /* Flag is deactive,return error */
ericebert 0:57690853989a 172 }
ericebert 0:57690853989a 173 #endif
ericebert 0:57690853989a 174 if((pfcb->flagRdy&(1<<id)) != 0) /* If the required flag is set */
ericebert 0:57690853989a 175 {
ericebert 0:57690853989a 176 OsSchedLock()
ericebert 0:57690853989a 177 pfcb->flagRdy &= ~((FlagCrl.resetOpt)&(1<<id)); /* Clear the flag */
ericebert 0:57690853989a 178 OsSchedUnlock();
ericebert 0:57690853989a 179 return E_OK;
ericebert 0:57690853989a 180 }
ericebert 0:57690853989a 181 else /* If the required flag is not set */
ericebert 0:57690853989a 182 {
ericebert 0:57690853989a 183 return E_FLAG_NOT_READY;
ericebert 0:57690853989a 184 }
ericebert 0:57690853989a 185 }
ericebert 0:57690853989a 186
ericebert 0:57690853989a 187
ericebert 0:57690853989a 188 /**
ericebert 0:57690853989a 189 *******************************************************************************
ericebert 0:57690853989a 190 * @brief AcceptMultipleFlags
ericebert 0:57690853989a 191 * @param[in] flags Flags that waiting to active task.
ericebert 0:57690853989a 192 * @param[in] waitType Flags wait type.
ericebert 0:57690853989a 193 * @param[out] perr A pointer to error code.
ericebert 0:57690853989a 194 * @retval 0
ericebert 0:57690853989a 195 * @retval springFlag
ericebert 0:57690853989a 196 *
ericebert 0:57690853989a 197 * @par Description
ericebert 0:57690853989a 198 * @details This fucntion is called to accept multiple flags.
ericebert 0:57690853989a 199 * @note
ericebert 0:57690853989a 200 *******************************************************************************
ericebert 0:57690853989a 201 */
ericebert 0:57690853989a 202 U32 CoAcceptMultipleFlags(U32 flags,U8 waitType,StatusType *perr)
ericebert 0:57690853989a 203 {
ericebert 0:57690853989a 204 U32 springFlag;
ericebert 0:57690853989a 205 P_FCB pfcb;
ericebert 0:57690853989a 206 pfcb = &FlagCrl;
ericebert 0:57690853989a 207
ericebert 0:57690853989a 208 #if CFG_PAR_CHECKOUT_EN >0
ericebert 0:57690853989a 209 if((flags&pfcb->flagActive) != flags ) /* Judge flag is active or not? */
ericebert 0:57690853989a 210 {
ericebert 0:57690853989a 211 *perr = E_INVALID_PARAMETER; /* Invalid flags */
ericebert 0:57690853989a 212 return 0;
ericebert 0:57690853989a 213 }
ericebert 0:57690853989a 214 #endif
ericebert 0:57690853989a 215
ericebert 0:57690853989a 216 springFlag = flags & pfcb->flagRdy;
ericebert 0:57690853989a 217
ericebert 0:57690853989a 218 OsSchedLock();
ericebert 0:57690853989a 219 /* If any required flags are set */
ericebert 0:57690853989a 220 if( (springFlag != 0) && (waitType == OPT_WAIT_ANY) )
ericebert 0:57690853989a 221 {
ericebert 0:57690853989a 222
ericebert 0:57690853989a 223 pfcb->flagRdy &= ~(springFlag & pfcb->resetOpt); /* Clear the flags */
ericebert 0:57690853989a 224 OsSchedUnlock();
ericebert 0:57690853989a 225 *perr = E_OK;
ericebert 0:57690853989a 226 return springFlag;
ericebert 0:57690853989a 227 }
ericebert 0:57690853989a 228
ericebert 0:57690853989a 229 /* If all required flags are set */
ericebert 0:57690853989a 230 if((springFlag == flags) && (waitType == OPT_WAIT_ALL))
ericebert 0:57690853989a 231 {
ericebert 0:57690853989a 232 pfcb->flagRdy &= ~(springFlag&pfcb->resetOpt); /* Clear the flags */
ericebert 0:57690853989a 233 OsSchedUnlock();
ericebert 0:57690853989a 234 *perr = E_OK;
ericebert 0:57690853989a 235 return springFlag;
ericebert 0:57690853989a 236 }
ericebert 0:57690853989a 237 OsSchedUnlock();
ericebert 0:57690853989a 238 *perr = E_FLAG_NOT_READY;
ericebert 0:57690853989a 239 return 0;
ericebert 0:57690853989a 240 }
ericebert 0:57690853989a 241
ericebert 0:57690853989a 242
ericebert 0:57690853989a 243
ericebert 0:57690853989a 244
ericebert 0:57690853989a 245 /**
ericebert 0:57690853989a 246 *******************************************************************************
ericebert 0:57690853989a 247 * @brief WaitForSingleFlag
ericebert 0:57690853989a 248 * @param[in] id Flag ID.
ericebert 0:57690853989a 249 * @param[in] timeout The longest time for writting flag.
ericebert 0:57690853989a 250 * @param[out] None
ericebert 0:57690853989a 251 * @retval E_CALL Error call in ISR.
ericebert 0:57690853989a 252 * @retval E_INVALID_ID Invalid event ID.
ericebert 0:57690853989a 253 * @retval E_TIMEOUT Flag wasn't received within 'timeout' time.
ericebert 0:57690853989a 254 * @retval E_OK The call was successful and your task owns the Flag,
ericebert 0:57690853989a 255 * or the event you are waiting for occurred.
ericebert 0:57690853989a 256 *
ericebert 0:57690853989a 257 * @par Description
ericebert 0:57690853989a 258 * @details This function is called to wait for only one flag,
ericebert 0:57690853989a 259 * (1) if parameter "timeout" == 0,waiting until flag be set;
ericebert 0:57690853989a 260 * (2) when "timeout" != 0,if flag was set or wasn't set but timeout
ericebert 0:57690853989a 261 * occured,the task will exit the waiting list,convert to READY
ericebert 0:57690853989a 262 * or RUNNING state.
ericebert 0:57690853989a 263 * @note
ericebert 0:57690853989a 264 *******************************************************************************
ericebert 0:57690853989a 265 */
ericebert 0:57690853989a 266 StatusType CoWaitForSingleFlag(OS_FlagID id,U32 timeout)
ericebert 0:57690853989a 267 {
ericebert 0:57690853989a 268 FLAG_NODE flagNode;
ericebert 0:57690853989a 269 P_FCB pfcb;
ericebert 0:57690853989a 270 P_OSTCB curTCB;
ericebert 0:57690853989a 271
ericebert 0:57690853989a 272 if(OSIntNesting > 0) /* See if the caller is ISR */
ericebert 0:57690853989a 273 {
ericebert 0:57690853989a 274 return E_CALL;
ericebert 0:57690853989a 275 }
ericebert 0:57690853989a 276 if(OSSchedLock != 0) /* Schedule is lock? */
ericebert 0:57690853989a 277 {
ericebert 0:57690853989a 278 return E_OS_IN_LOCK; /* Yes,error return */
ericebert 0:57690853989a 279 }
ericebert 0:57690853989a 280
ericebert 0:57690853989a 281 #if CFG_PAR_CHECKOUT_EN >0
ericebert 0:57690853989a 282 if(id >= FLAG_MAX_NUM) /* Judge id is valid or not? */
ericebert 0:57690853989a 283 {
ericebert 0:57690853989a 284 return E_INVALID_ID; /* Invalid 'id' */
ericebert 0:57690853989a 285 }
ericebert 0:57690853989a 286 if((FlagCrl.flagActive&(1<<id)) == 0 )/* Judge flag is active or not? */
ericebert 0:57690853989a 287 {
ericebert 0:57690853989a 288 return E_INVALID_ID; /* Flag is deactive ,return error */
ericebert 0:57690853989a 289 }
ericebert 0:57690853989a 290 #endif
ericebert 0:57690853989a 291
ericebert 0:57690853989a 292 OsSchedLock();
ericebert 0:57690853989a 293 pfcb = &FlagCrl;
ericebert 0:57690853989a 294 /* See if the required flag is set */
ericebert 0:57690853989a 295 if((pfcb->flagRdy&(1<<id)) != 0) /* If the required flag is set */
ericebert 0:57690853989a 296 {
ericebert 0:57690853989a 297 pfcb->flagRdy &= ~((pfcb->resetOpt&(1<<id))); /* Clear the flag */
ericebert 0:57690853989a 298 OsSchedUnlock();
ericebert 0:57690853989a 299 }
ericebert 0:57690853989a 300 else /* If the required flag is not set */
ericebert 0:57690853989a 301 {
ericebert 0:57690853989a 302 curTCB = TCBRunning;
ericebert 0:57690853989a 303 if(timeout == 0) /* If time-out is not configured */
ericebert 0:57690853989a 304 {
ericebert 0:57690853989a 305 /* Block task until the required flag is set */
ericebert 0:57690853989a 306 FlagBlock (&flagNode,(1<<id),OPT_WAIT_ONE);
ericebert 0:57690853989a 307 curTCB->state = TASK_WAITING;
ericebert 0:57690853989a 308 TaskSchedReq = TRUE;
ericebert 0:57690853989a 309 OsSchedUnlock();
ericebert 0:57690853989a 310
ericebert 0:57690853989a 311 /* The required flag is set and the task is in running state */
ericebert 0:57690853989a 312 curTCB->pnode = 0;
ericebert 0:57690853989a 313 OsSchedLock();
ericebert 0:57690853989a 314
ericebert 0:57690853989a 315 /* Clear the required flag or not */
ericebert 0:57690853989a 316 pfcb->flagRdy &= ~((1<<id)&(pfcb->resetOpt));
ericebert 0:57690853989a 317 OsSchedUnlock();
ericebert 0:57690853989a 318 }
ericebert 0:57690853989a 319 else /* If time-out is configured */
ericebert 0:57690853989a 320 {
ericebert 0:57690853989a 321 /* Block task until the required flag is set or time-out occurs */
ericebert 0:57690853989a 322 FlagBlock(&flagNode,(1<<id),OPT_WAIT_ONE);
ericebert 0:57690853989a 323 InsertDelayList(curTCB,timeout);
ericebert 0:57690853989a 324
ericebert 0:57690853989a 325 OsSchedUnlock();
ericebert 0:57690853989a 326 if(curTCB->pnode == 0) /* If time-out occurred */
ericebert 0:57690853989a 327 {
ericebert 0:57690853989a 328 return E_TIMEOUT;
ericebert 0:57690853989a 329 }
ericebert 0:57690853989a 330 else /* If flag is set */
ericebert 0:57690853989a 331 {
ericebert 0:57690853989a 332 curTCB->pnode = 0;
ericebert 0:57690853989a 333 OsSchedLock();
ericebert 0:57690853989a 334
ericebert 0:57690853989a 335 /* Clear the required flag or not */
ericebert 0:57690853989a 336 pfcb->flagRdy &= ~((1<<id)&(pfcb->resetOpt));
ericebert 0:57690853989a 337 OsSchedUnlock();
ericebert 0:57690853989a 338 }
ericebert 0:57690853989a 339 }
ericebert 0:57690853989a 340 }
ericebert 0:57690853989a 341 return E_OK;
ericebert 0:57690853989a 342 }
ericebert 0:57690853989a 343
ericebert 0:57690853989a 344
ericebert 0:57690853989a 345 /**
ericebert 0:57690853989a 346 *******************************************************************************
ericebert 0:57690853989a 347 * @brief WaitForMultipleFlags
ericebert 0:57690853989a 348 * @param[in] flags Flags that waiting to active task.
ericebert 0:57690853989a 349 * @param[in] waitType Flags wait type.
ericebert 0:57690853989a 350 * @param[in] timeout The longest time for writting flag.
ericebert 0:57690853989a 351 * @param[out] perr A pointer to error code.
ericebert 0:57690853989a 352 * @retval 0
ericebert 0:57690853989a 353 * @retval springFlag
ericebert 0:57690853989a 354 *
ericebert 0:57690853989a 355 * @par Description
ericebert 0:57690853989a 356 * @details This function is called to pend a task for waitting multiple flag.
ericebert 0:57690853989a 357 * @note
ericebert 0:57690853989a 358 *******************************************************************************
ericebert 0:57690853989a 359 */
ericebert 0:57690853989a 360 U32 CoWaitForMultipleFlags(U32 flags,U8 waitType,U32 timeout,StatusType *perr)
ericebert 0:57690853989a 361 {
ericebert 0:57690853989a 362 U32 springFlag;
ericebert 0:57690853989a 363 P_FCB pfcb;
ericebert 0:57690853989a 364 FLAG_NODE flagNode;
ericebert 0:57690853989a 365 P_OSTCB curTCB;
ericebert 0:57690853989a 366
ericebert 0:57690853989a 367
ericebert 0:57690853989a 368 if(OSIntNesting > 0) /* If the caller is ISR */
ericebert 0:57690853989a 369 {
ericebert 0:57690853989a 370 *perr = E_CALL;
ericebert 0:57690853989a 371 return 0;
ericebert 0:57690853989a 372 }
ericebert 0:57690853989a 373 if(OSSchedLock != 0) /* Schedule is lock? */
ericebert 0:57690853989a 374 {
ericebert 0:57690853989a 375 *perr = E_OS_IN_LOCK;
ericebert 0:57690853989a 376 return 0; /* Yes,error return */
ericebert 0:57690853989a 377 }
ericebert 0:57690853989a 378 #if CFG_PAR_CHECKOUT_EN >0
ericebert 0:57690853989a 379 if( (flags&FlagCrl.flagActive) != flags )
ericebert 0:57690853989a 380 {
ericebert 0:57690853989a 381 *perr = E_INVALID_PARAMETER; /* Invalid 'flags' */
ericebert 0:57690853989a 382 return 0;
ericebert 0:57690853989a 383 }
ericebert 0:57690853989a 384 #endif
ericebert 0:57690853989a 385 OsSchedLock();
ericebert 0:57690853989a 386 pfcb = &FlagCrl;
ericebert 0:57690853989a 387 springFlag = flags & pfcb->flagRdy;
ericebert 0:57690853989a 388
ericebert 0:57690853989a 389 /* If any required flags are set */
ericebert 0:57690853989a 390 if((springFlag != 0) && (waitType == OPT_WAIT_ANY))
ericebert 0:57690853989a 391 {
ericebert 0:57690853989a 392 pfcb->flagRdy &= ~(springFlag & pfcb->resetOpt); /* Clear the flag */
ericebert 0:57690853989a 393 OsSchedUnlock();
ericebert 0:57690853989a 394 *perr = E_OK;
ericebert 0:57690853989a 395 return springFlag;
ericebert 0:57690853989a 396 }
ericebert 0:57690853989a 397
ericebert 0:57690853989a 398 /* If all required flags are set */
ericebert 0:57690853989a 399 if( (springFlag == flags) && (waitType == OPT_WAIT_ALL) )
ericebert 0:57690853989a 400 {
ericebert 0:57690853989a 401 pfcb->flagRdy &= ~(springFlag & pfcb->resetOpt); /* Clear the flags */
ericebert 0:57690853989a 402 OsSchedUnlock();
ericebert 0:57690853989a 403 *perr = E_OK;
ericebert 0:57690853989a 404 return springFlag;
ericebert 0:57690853989a 405 }
ericebert 0:57690853989a 406
ericebert 0:57690853989a 407 curTCB = TCBRunning;
ericebert 0:57690853989a 408 if(timeout == 0) /* If time-out is not configured */
ericebert 0:57690853989a 409 {
ericebert 0:57690853989a 410 /* Block task until the required flag are set */
ericebert 0:57690853989a 411 FlagBlock(&flagNode,flags,waitType);
ericebert 0:57690853989a 412 curTCB->state = TASK_WAITING;
ericebert 0:57690853989a 413 TaskSchedReq = TRUE;
ericebert 0:57690853989a 414 OsSchedUnlock();
ericebert 0:57690853989a 415
ericebert 0:57690853989a 416 curTCB->pnode = 0;
ericebert 0:57690853989a 417 OsSchedLock();
ericebert 0:57690853989a 418 springFlag = flags & pfcb->flagRdy;
ericebert 0:57690853989a 419 pfcb->flagRdy &= ~(springFlag & pfcb->resetOpt);/* Clear the flags */
ericebert 0:57690853989a 420 OsSchedUnlock();
ericebert 0:57690853989a 421 *perr = E_OK;
ericebert 0:57690853989a 422 return springFlag;
ericebert 0:57690853989a 423 }
ericebert 0:57690853989a 424 else /* If time-out is configured */
ericebert 0:57690853989a 425 {
ericebert 0:57690853989a 426 /* Block task until the required flag are set or time-out occurred */
ericebert 0:57690853989a 427 FlagBlock(&flagNode,flags,waitType);
ericebert 0:57690853989a 428 InsertDelayList(curTCB,timeout);
ericebert 0:57690853989a 429
ericebert 0:57690853989a 430 OsSchedUnlock();
ericebert 0:57690853989a 431 if(curTCB->pnode == 0) /* If time-out occurred */
ericebert 0:57690853989a 432 {
ericebert 0:57690853989a 433 *perr = E_TIMEOUT;
ericebert 0:57690853989a 434 return 0;
ericebert 0:57690853989a 435 }
ericebert 0:57690853989a 436 else /* If the required flags are set */
ericebert 0:57690853989a 437 {
ericebert 0:57690853989a 438 curTCB->pnode = 0;
ericebert 0:57690853989a 439 OsSchedLock();
ericebert 0:57690853989a 440 springFlag = flags & FlagCrl.flagRdy;
ericebert 0:57690853989a 441
ericebert 0:57690853989a 442 /* Clear the required ready flags or not */
ericebert 0:57690853989a 443 pfcb->flagRdy &= ~(springFlag & pfcb->resetOpt);
ericebert 0:57690853989a 444 OsSchedUnlock();
ericebert 0:57690853989a 445 *perr = E_OK;
ericebert 0:57690853989a 446 return springFlag;
ericebert 0:57690853989a 447 }
ericebert 0:57690853989a 448 }
ericebert 0:57690853989a 449 }
ericebert 0:57690853989a 450
ericebert 0:57690853989a 451
ericebert 0:57690853989a 452 /**
ericebert 0:57690853989a 453 *******************************************************************************
ericebert 0:57690853989a 454 * @brief Clear a Flag
ericebert 0:57690853989a 455 * @param[in] id Flag ID.
ericebert 0:57690853989a 456 * @param[out] None
ericebert 0:57690853989a 457 * @retval E_OK Event deleted successful.
ericebert 0:57690853989a 458 * @retval E_INVALID_ID Invalid event ID.
ericebert 0:57690853989a 459 *
ericebert 0:57690853989a 460 * @par Description
ericebert 0:57690853989a 461 * @details This function is called to clear a flag.
ericebert 0:57690853989a 462 *
ericebert 0:57690853989a 463 * @note
ericebert 0:57690853989a 464 *******************************************************************************
ericebert 0:57690853989a 465 */
ericebert 0:57690853989a 466 StatusType CoClearFlag(OS_FlagID id)
ericebert 0:57690853989a 467 {
ericebert 0:57690853989a 468 P_FCB pfcb;
ericebert 0:57690853989a 469 pfcb = &FlagCrl;
ericebert 0:57690853989a 470 #if CFG_PAR_CHECKOUT_EN >0
ericebert 0:57690853989a 471 if(id >= FLAG_MAX_NUM)
ericebert 0:57690853989a 472 {
ericebert 0:57690853989a 473 return E_INVALID_ID; /* Invalid id */
ericebert 0:57690853989a 474 }
ericebert 0:57690853989a 475 if((pfcb->flagActive&(1<<id)) == 0)
ericebert 0:57690853989a 476 {
ericebert 0:57690853989a 477 return E_INVALID_ID; /* Invalid flag */
ericebert 0:57690853989a 478 }
ericebert 0:57690853989a 479 #endif
ericebert 0:57690853989a 480
ericebert 0:57690853989a 481 pfcb->flagRdy &= ~(1<<id); /* Clear the flag */
ericebert 0:57690853989a 482 return E_OK;
ericebert 0:57690853989a 483 }
ericebert 0:57690853989a 484
ericebert 0:57690853989a 485
ericebert 0:57690853989a 486 /**
ericebert 0:57690853989a 487 *******************************************************************************
ericebert 0:57690853989a 488 * @brief Set a flag
ericebert 0:57690853989a 489 * @param[in] id Flag ID.
ericebert 0:57690853989a 490 * @param[out] None
ericebert 0:57690853989a 491 * @retval E_INVALID_ID Invalid event ID.
ericebert 0:57690853989a 492 * @retval E_OK Event deleted successful.
ericebert 0:57690853989a 493 *
ericebert 0:57690853989a 494 * @par Description
ericebert 0:57690853989a 495 * @details This function is called to set a flag.
ericebert 0:57690853989a 496 * @note
ericebert 0:57690853989a 497 *******************************************************************************
ericebert 0:57690853989a 498 */
ericebert 0:57690853989a 499 StatusType CoSetFlag(OS_FlagID id)
ericebert 0:57690853989a 500 {
ericebert 0:57690853989a 501 P_FLAG_NODE pnode;
ericebert 0:57690853989a 502 P_FCB pfcb;
ericebert 0:57690853989a 503 pfcb = &FlagCrl;
ericebert 0:57690853989a 504
ericebert 0:57690853989a 505 #if CFG_PAR_CHECKOUT_EN >0
ericebert 0:57690853989a 506 if(id >= FLAG_MAX_NUM) /* Flag is valid or not */
ericebert 0:57690853989a 507 {
ericebert 0:57690853989a 508 return E_INVALID_ID; /* Invalid flag id */
ericebert 0:57690853989a 509 }
ericebert 0:57690853989a 510 if((pfcb->flagActive&(1<<id)) == 0)
ericebert 0:57690853989a 511 {
ericebert 0:57690853989a 512 return E_INVALID_ID; /* Flag is not exist */
ericebert 0:57690853989a 513 }
ericebert 0:57690853989a 514 #endif
ericebert 0:57690853989a 515
ericebert 0:57690853989a 516 if((pfcb->flagRdy&(1<<id)) != 0) /* Flag had already been set */
ericebert 0:57690853989a 517 {
ericebert 0:57690853989a 518 return E_OK;
ericebert 0:57690853989a 519 }
ericebert 0:57690853989a 520
ericebert 0:57690853989a 521 pfcb->flagRdy |= (1<<id); /* Update the flags ready list */
ericebert 0:57690853989a 522
ericebert 0:57690853989a 523 OsSchedLock();
ericebert 0:57690853989a 524 pnode = pfcb->headNode;
ericebert 0:57690853989a 525 while(pnode != 0)
ericebert 0:57690853989a 526 {
ericebert 0:57690853989a 527 if(pnode->waitType == OPT_WAIT_ALL) /* Extract all the bits we want */
ericebert 0:57690853989a 528 {
ericebert 0:57690853989a 529 if((pnode->waitFlags&pfcb->flagRdy) == pnode->waitFlags)
ericebert 0:57690853989a 530 {
ericebert 0:57690853989a 531 /* Remove the flag node from the wait list */
ericebert 0:57690853989a 532 pnode = RemoveFromLink(pnode);
ericebert 0:57690853989a 533 if((pfcb->resetOpt&(1<<id)) != 0)/* If the flags is auto-reset*/
ericebert 0:57690853989a 534 {
ericebert 0:57690853989a 535 break;
ericebert 0:57690853989a 536 }
ericebert 0:57690853989a 537 continue;
ericebert 0:57690853989a 538 }
ericebert 0:57690853989a 539 }
ericebert 0:57690853989a 540 else /* Extract only the bits we want */
ericebert 0:57690853989a 541 {
ericebert 0:57690853989a 542 if( (pnode->waitFlags & pfcb->flagRdy) != 0)
ericebert 0:57690853989a 543 {
ericebert 0:57690853989a 544 /* Remove the flag node from the wait list */
ericebert 0:57690853989a 545 pnode = RemoveFromLink(pnode);
ericebert 0:57690853989a 546 if((pfcb->resetOpt&(1<<id)) != 0)
ericebert 0:57690853989a 547 {
ericebert 0:57690853989a 548 break; /* The flags is auto-reset */
ericebert 0:57690853989a 549 }
ericebert 0:57690853989a 550 continue;
ericebert 0:57690853989a 551 }
ericebert 0:57690853989a 552 }
ericebert 0:57690853989a 553 pnode = pnode->nextNode;
ericebert 0:57690853989a 554 }
ericebert 0:57690853989a 555 OsSchedUnlock();
ericebert 0:57690853989a 556 return E_OK;
ericebert 0:57690853989a 557 }
ericebert 0:57690853989a 558
ericebert 0:57690853989a 559
ericebert 0:57690853989a 560
ericebert 0:57690853989a 561 /**
ericebert 0:57690853989a 562 *******************************************************************************
ericebert 0:57690853989a 563 * @brief Set a flag in ISR
ericebert 0:57690853989a 564 * @param[in] id Flag ID.
ericebert 0:57690853989a 565 * @param[out] None
ericebert 0:57690853989a 566 * @retval E_INVALID_ID Invalid event ID.
ericebert 0:57690853989a 567 * @retval E_OK Event deleted successful.
ericebert 0:57690853989a 568 *
ericebert 0:57690853989a 569 * @par Description
ericebert 0:57690853989a 570 * @details This function is called in ISR to set a flag.
ericebert 0:57690853989a 571 * @note
ericebert 0:57690853989a 572 *******************************************************************************
ericebert 0:57690853989a 573 */
ericebert 0:57690853989a 574 #if CFG_MAX_SERVICE_REQUEST > 0
ericebert 0:57690853989a 575 StatusType isr_SetFlag(OS_FlagID id)
ericebert 0:57690853989a 576 {
ericebert 0:57690853989a 577 if(OSSchedLock > 0) /* If scheduler is locked,(the caller is ISR) */
ericebert 0:57690853989a 578 {
ericebert 0:57690853989a 579 /* Insert the request into service request queue */
ericebert 0:57690853989a 580 if(InsertInSRQ(FLAG_REQ,id,0) == FALSE)
ericebert 0:57690853989a 581 {
ericebert 0:57690853989a 582 return E_SEV_REQ_FULL; /* The service requst queue is full */
ericebert 0:57690853989a 583 }
ericebert 0:57690853989a 584 else
ericebert 0:57690853989a 585 {
ericebert 0:57690853989a 586 return E_OK;
ericebert 0:57690853989a 587 }
ericebert 0:57690853989a 588 }
ericebert 0:57690853989a 589 else
ericebert 0:57690853989a 590 {
ericebert 0:57690853989a 591 return(CoSetFlag(id)); /* The caller is not ISR, set the flag*/
ericebert 0:57690853989a 592 }
ericebert 0:57690853989a 593 }
ericebert 0:57690853989a 594 #endif
ericebert 0:57690853989a 595
ericebert 0:57690853989a 596 /**
ericebert 0:57690853989a 597 *******************************************************************************
ericebert 0:57690853989a 598 * @brief Block a task to wait a flag event
ericebert 0:57690853989a 599 * @param[in] pnode A node that will link into flag waiting list.
ericebert 0:57690853989a 600 * @param[in] flags Flag(s) that the node waiting for.
ericebert 0:57690853989a 601 * @param[in] waitType Waiting type of the node.
ericebert 0:57690853989a 602 * @param[out] None
ericebert 0:57690853989a 603 * @retval None
ericebert 0:57690853989a 604 *
ericebert 0:57690853989a 605 * @par Description
ericebert 0:57690853989a 606 * @details This function is called to block a task to wait a flag event.
ericebert 0:57690853989a 607 * @note
ericebert 0:57690853989a 608 *******************************************************************************
ericebert 0:57690853989a 609 */
ericebert 0:57690853989a 610 static void FlagBlock(P_FLAG_NODE pnode,U32 flags,U8 waitType)
ericebert 0:57690853989a 611 {
ericebert 0:57690853989a 612 P_FCB pfcb;
ericebert 0:57690853989a 613 pfcb = &FlagCrl;
ericebert 0:57690853989a 614
ericebert 0:57690853989a 615 TCBRunning->pnode = pnode;
ericebert 0:57690853989a 616 pnode->waitTask = TCBRunning;
ericebert 0:57690853989a 617 pnode->waitFlags = flags; /* Save the flags that we need to wait for*/
ericebert 0:57690853989a 618 pnode->waitType = waitType; /* Save the type of wait */
ericebert 0:57690853989a 619
ericebert 0:57690853989a 620 if(pfcb->tailNode == 0) /* If this is the first NODE to insert? */
ericebert 0:57690853989a 621 {
ericebert 0:57690853989a 622 pnode->nextNode = 0;
ericebert 0:57690853989a 623 pnode->prevNode = 0;
ericebert 0:57690853989a 624 pfcb->headNode = pnode; /* Insert the NODE to the head */
ericebert 0:57690853989a 625 }
ericebert 0:57690853989a 626 else /* If it is not the first NODE to insert? */
ericebert 0:57690853989a 627 {
ericebert 0:57690853989a 628 pfcb->tailNode->nextNode = pnode; /* Insert the NODE to the tail */
ericebert 0:57690853989a 629 pnode->prevNode = pfcb->tailNode;
ericebert 0:57690853989a 630 pnode->nextNode = 0;
ericebert 0:57690853989a 631 }
ericebert 0:57690853989a 632 pfcb->tailNode = pnode;
ericebert 0:57690853989a 633 }
ericebert 0:57690853989a 634
ericebert 0:57690853989a 635
ericebert 0:57690853989a 636 /**
ericebert 0:57690853989a 637 *******************************************************************************
ericebert 0:57690853989a 638 * @brief Remove a flag node from list
ericebert 0:57690853989a 639 * @param[in] pnode A node that will remove from flag waiting list.
ericebert 0:57690853989a 640 * @param[out] None
ericebert 0:57690853989a 641 * @retval pnode Next node of the node that have removed out.
ericebert 0:57690853989a 642 *
ericebert 0:57690853989a 643 * @par Description
ericebert 0:57690853989a 644 * @details This function is called to remove a flag node from the wait list.
ericebert 0:57690853989a 645 * @note
ericebert 0:57690853989a 646 *******************************************************************************
ericebert 0:57690853989a 647 */
ericebert 0:57690853989a 648 static P_FLAG_NODE RemoveFromLink(P_FLAG_NODE pnode)
ericebert 0:57690853989a 649 {
ericebert 0:57690853989a 650 P_OSTCB ptcb;
ericebert 0:57690853989a 651
ericebert 0:57690853989a 652 RemoveLinkNode(pnode); /* Remove the flag node from wait list. */
ericebert 0:57690853989a 653 ptcb = pnode->waitTask;
ericebert 0:57690853989a 654
ericebert 0:57690853989a 655 /* The task in the delay list */
ericebert 0:57690853989a 656 if(ptcb->delayTick != INVALID_VALUE)/* If the task is in tick delay list */
ericebert 0:57690853989a 657 {
ericebert 0:57690853989a 658 RemoveDelayList(ptcb); /* Remove the task from tick delay list */
ericebert 0:57690853989a 659 }
ericebert 0:57690853989a 660
ericebert 0:57690853989a 661 ptcb->pnode = (void*)0xffffffff;
ericebert 0:57690853989a 662
ericebert 0:57690853989a 663 if(ptcb == TCBRunning)
ericebert 0:57690853989a 664 {
ericebert 0:57690853989a 665 ptcb->state = TASK_RUNNING;
ericebert 0:57690853989a 666 }
ericebert 0:57690853989a 667 else
ericebert 0:57690853989a 668 {
ericebert 0:57690853989a 669 InsertToTCBRdyList(ptcb); /* Insert the task to ready list */
ericebert 0:57690853989a 670 }
ericebert 0:57690853989a 671 return (pnode->nextNode);
ericebert 0:57690853989a 672 }
ericebert 0:57690853989a 673
ericebert 0:57690853989a 674 /**
ericebert 0:57690853989a 675 *******************************************************************************
ericebert 0:57690853989a 676 * @brief Remove a flag node from list
ericebert 0:57690853989a 677 * @param[in] pnode A node that will remove from flag waiting list.
ericebert 0:57690853989a 678 * @param[out] None
ericebert 0:57690853989a 679 * @retval None
ericebert 0:57690853989a 680 *
ericebert 0:57690853989a 681 * @par Description
ericebert 0:57690853989a 682 * @details This function is called to remove a flag node from the wait list.
ericebert 0:57690853989a 683 * @note
ericebert 0:57690853989a 684 *******************************************************************************
ericebert 0:57690853989a 685 */
ericebert 0:57690853989a 686 void RemoveLinkNode(P_FLAG_NODE pnode)
ericebert 0:57690853989a 687 {
ericebert 0:57690853989a 688 /* If only one NODE in the list*/
ericebert 0:57690853989a 689 if((pnode->nextNode == 0) && (pnode->prevNode == 0))
ericebert 0:57690853989a 690 {
ericebert 0:57690853989a 691 FlagCrl.headNode = 0;
ericebert 0:57690853989a 692 FlagCrl.tailNode = 0;
ericebert 0:57690853989a 693 }
ericebert 0:57690853989a 694 else if(pnode->nextNode == 0) /* If the NODE is tail */
ericebert 0:57690853989a 695 {
ericebert 0:57690853989a 696 FlagCrl.tailNode = pnode->prevNode;
ericebert 0:57690853989a 697 pnode->prevNode->nextNode = 0;
ericebert 0:57690853989a 698 }
ericebert 0:57690853989a 699 else if(pnode->prevNode == 0) /* If the NODE is head */
ericebert 0:57690853989a 700 {
ericebert 0:57690853989a 701 FlagCrl.headNode = pnode->nextNode;
ericebert 0:57690853989a 702 pnode->nextNode->prevNode = 0;
ericebert 0:57690853989a 703 }
ericebert 0:57690853989a 704 else /* The NODE is in the middle */
ericebert 0:57690853989a 705 {
ericebert 0:57690853989a 706 pnode->nextNode->prevNode = pnode->prevNode;
ericebert 0:57690853989a 707 pnode->prevNode->nextNode = pnode->nextNode;
ericebert 0:57690853989a 708 }
ericebert 0:57690853989a 709 pnode->waitTask->pnode = 0;
ericebert 0:57690853989a 710 }
ericebert 0:57690853989a 711
ericebert 0:57690853989a 712 #endif