Quick and dirty CoOS + LWIP ( Webserver )

Dependencies:   mbed lwip

Committer:
astroboy
Date:
Sat Sep 10 22:41:10 2011 +0000
Revision:
0:94897d537b31

        

Who changed what in which revision?

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