LPCOpen Platform  v1.03
LPCOpen Platform for NXP LPC Microcontrollers
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
os_flag.c
Go to the documentation of this file.
1 /*
2 ************************************************************************************************************************
3 * uC/OS-III
4 * The Real-Time Kernel
5 *
6 * (c) Copyright 2009-2012; Micrium, Inc.; Weston, FL
7 * All rights reserved. Protected by international copyright laws.
8 *
9 * EVENT FLAG MANAGEMENT
10 *
11 * File : OS_FLAG.C
12 * By : JJL
13 * Version : V3.03.00
14 *
15 * LICENSING TERMS:
16 * ---------------
17 * uC/OS-III is provided in source form for FREE short-term evaluation, for educational use or
18 * for peaceful research. If you plan or intend to use uC/OS-III in a commercial application/
19 * product then, you need to contact Micrium to properly license uC/OS-III for its use in your
20 * application/product. We provide ALL the source code for your convenience and to help you
21 * experience uC/OS-III. The fact that the source is provided does NOT mean that you can use
22 * it commercially without paying a licensing fee.
23 *
24 * Knowledge of the source code may NOT be used to develop a similar product.
25 *
26 * Please help us continue to provide the embedded community with the finest software available.
27 * Your honesty is greatly appreciated.
28 *
29 * You can contact us at www.micrium.com, or by phone at +1 (954) 217-2036.
30 ************************************************************************************************************************
31 */
32 
33 #define MICRIUM_SOURCE
34 #include <os.h>
35 
36 #ifdef VSC_INCLUDE_SOURCE_FILE_NAMES
37 const CPU_CHAR *os_flag__c = "$Id: $";
38 #endif
39 
40 
41 #if OS_CFG_FLAG_EN > 0u
42 
43 /*$PAGE*/
44 /*
45 ************************************************************************************************************************
46 * CREATE AN EVENT FLAG
47 *
48 * Description: This function is called to create an event flag group.
49 *
50 * Arguments : p_grp is a pointer to the event flag group to create
51 *
52 * p_name is the name of the event flag group
53 *
54 * flags contains the initial value to store in the event flag group (typically 0).
55 *
56 * p_err is a pointer to an error code which will be returned to your application:
57 *
58 * OS_ERR_NONE if the call was successful.
59 * OS_ERR_CREATE_ISR if you attempted to create an Event Flag from an ISR.
60 * OS_ERR_ILLEGAL_CREATE_RUN_TIME if you are trying to create the Event Flag after you
61 * called OSSafetyCriticalStart().
62 * OS_ERR_NAME if 'p_name' is a NULL pointer
63 * OS_ERR_OBJ_CREATED if the event flag group has already been created
64 * OS_ERR_OBJ_PTR_NULL if 'p_grp' is a NULL pointer
65 *
66 * Returns : none
67 ************************************************************************************************************************
68 */
69 
70 void OSFlagCreate (OS_FLAG_GRP *p_grp,
71  CPU_CHAR *p_name,
72  OS_FLAGS flags,
73  OS_ERR *p_err)
74 {
75  CPU_SR_ALLOC();
76 
77 
78 
79 #ifdef OS_SAFETY_CRITICAL
80  if (p_err == (OS_ERR *)0) {
81  OS_SAFETY_CRITICAL_EXCEPTION();
82  return;
83  }
84 #endif
85 
86 #ifdef OS_SAFETY_CRITICAL_IEC61508
87  if (OSSafetyCriticalStartFlag == DEF_TRUE) {
89  return;
90  }
91 #endif
92 
93 #if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u
94  if (OSIntNestingCtr > (OS_NESTING_CTR)0) { /* See if called from ISR ... */
95  *p_err = OS_ERR_CREATE_ISR; /* ... can't CREATE from an ISR */
96  return;
97  }
98 #endif
99 
100 #if OS_CFG_ARG_CHK_EN > 0u
101  if (p_grp == (OS_FLAG_GRP *)0) { /* Validate 'p_grp' */
102  *p_err = OS_ERR_OBJ_PTR_NULL;
103  return;
104  }
105 #endif
106 
108  p_grp->Type = OS_OBJ_TYPE_FLAG; /* Set to event flag group type */
109  p_grp->NamePtr = p_name;
110  p_grp->Flags = flags; /* Set to desired initial value */
111  p_grp->TS = (CPU_TS)0;
112  OS_PendListInit(&p_grp->PendList);
113 
114 #if OS_CFG_DBG_EN > 0u
115  OS_FlagDbgListAdd(p_grp);
116 #endif
117  OSFlagQty++;
118 
120  *p_err = OS_ERR_NONE;
121 }
122 
123 /*$PAGE*/
124 /*
125 ************************************************************************************************************************
126 * DELETE AN EVENT FLAG GROUP
127 *
128 * Description: This function deletes an event flag group and readies all tasks pending on the event flag group.
129 *
130 * Arguments : p_grp is a pointer to the desired event flag group.
131 *
132 * opt determines delete options as follows:
133 *
134 * OS_OPT_DEL_NO_PEND Deletes the event flag group ONLY if no task pending
135 * OS_OPT_DEL_ALWAYS Deletes the event flag group even if tasks are waiting.
136 * In this case, all the tasks pending will be readied.
137 *
138 * p_err is a pointer to an error code that can contain one of the following values:
139 *
140 * OS_ERR_NONE The call was successful and the event flag group was deleted
141 * OS_ERR_DEL_ISR If you attempted to delete the event flag group from an ISR
142 * OS_ERR_OBJ_PTR_NULL If 'p_grp' is a NULL pointer.
143 * OS_ERR_OBJ_TYPE If you didn't pass a pointer to an event flag group
144 * OS_ERR_OPT_INVALID An invalid option was specified
145 * OS_ERR_TASK_WAITING One or more tasks were waiting on the event flag group.
146 *
147 * Returns : == 0 if no tasks were waiting on the event flag group, or upon error.
148 * > 0 if one or more tasks waiting on the event flag group are now readied and informed.
149 *
150 * Note(s) : 1) This function must be used with care. Tasks that would normally expect the presence of the event flag
151 * group MUST check the return code of OSFlagPost and OSFlagPend().
152 ************************************************************************************************************************
153 */
154 
155 #if OS_CFG_FLAG_DEL_EN > 0u
156 OS_OBJ_QTY OSFlagDel (OS_FLAG_GRP *p_grp,
157  OS_OPT opt,
158  OS_ERR *p_err)
159 {
160  OS_OBJ_QTY cnt;
161  OS_OBJ_QTY nbr_tasks;
162  OS_PEND_DATA *p_pend_data;
163  OS_PEND_LIST *p_pend_list;
164  OS_TCB *p_tcb;
165  CPU_TS ts;
166  CPU_SR_ALLOC();
167 
168 
169 
170 #ifdef OS_SAFETY_CRITICAL
171  if (p_err == (OS_ERR *)0) {
172  OS_SAFETY_CRITICAL_EXCEPTION();
173  return ((OS_OBJ_QTY)0);
174  }
175 #endif
176 
177 #if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u
178  if (OSIntNestingCtr > (OS_NESTING_CTR)0) { /* See if called from ISR ... */
179  *p_err = OS_ERR_DEL_ISR; /* ... can't DELETE from an ISR */
180  return ((OS_OBJ_QTY)0);
181  }
182 #endif
183 
184 #if OS_CFG_ARG_CHK_EN > 0u
185  if (p_grp == (OS_FLAG_GRP *)0) { /* Validate 'p_grp' */
186  *p_err = OS_ERR_OBJ_PTR_NULL;
187  return ((OS_OBJ_QTY)0);
188  }
189  switch (opt) { /* Validate 'opt' */
190  case OS_OPT_DEL_NO_PEND:
191  case OS_OPT_DEL_ALWAYS:
192  break;
193 
194  default:
195  *p_err = OS_ERR_OPT_INVALID;
196  return ((OS_OBJ_QTY)0);
197  }
198 #endif
199 
200 #if OS_CFG_OBJ_TYPE_CHK_EN > 0u
201  if (p_grp->Type != OS_OBJ_TYPE_FLAG) { /* Validate event group object */
202  *p_err = OS_ERR_OBJ_TYPE;
203  return ((OS_OBJ_QTY)0);
204  }
205 #endif
207  p_pend_list = &p_grp->PendList;
208  cnt = p_pend_list->NbrEntries;
209  nbr_tasks = cnt;
210  switch (opt) {
211  case OS_OPT_DEL_NO_PEND: /* Delete group if no task waiting */
212  if (nbr_tasks == (OS_OBJ_QTY)0) {
213 #if OS_CFG_DBG_EN > 0u
214  OS_FlagDbgListRemove(p_grp);
215 #endif
216  OSFlagQty--;
217  OS_FlagClr(p_grp);
218 
220  *p_err = OS_ERR_NONE;
221  } else {
223  *p_err = OS_ERR_TASK_WAITING;
224  }
225  break;
226 
227  case OS_OPT_DEL_ALWAYS: /* Always delete the event flag group */
228  ts = OS_TS_GET(); /* Get local time stamp so all tasks get the same time */
229  while (cnt > 0u) { /* Remove all tasks from the pend list */
230  p_pend_data = p_pend_list->HeadPtr;
231  p_tcb = p_pend_data->TCBPtr;
232  OS_PendObjDel((OS_PEND_OBJ *)((void *)p_grp),
233  p_tcb,
234  ts);
235  cnt--;
236  }
237 #if OS_CFG_DBG_EN > 0u
238  OS_FlagDbgListRemove(p_grp);
239 #endif
240  OSFlagQty--;
241  OS_FlagClr(p_grp);
243  OSSched(); /* Find highest priority task ready to run */
244  *p_err = OS_ERR_NONE;
245  break;
246 
247  default:
249  *p_err = OS_ERR_OPT_INVALID;
250  break;
251  }
252  return (nbr_tasks);
253 }
254 #endif
255 
256 /*
257 ************************************************************************************************************************
258 * WAIT ON AN EVENT FLAG GROUP
259 *
260 * Description: This function is called to wait for a combination of bits to be set in an event flag group. Your
261 * application can wait for ANY bit to be set or ALL bits to be set.
262 *
263 * Arguments : p_grp is a pointer to the desired event flag group.
264 *
265 * flags Is a bit pattern indicating which bit(s) (i.e. flags) you wish to wait for.
266 * The bits you want are specified by setting the corresponding bits in 'flags'.
267 * e.g. if your application wants to wait for bits 0 and 1 then 'flags' would contain 0x03.
268 *
269 * timeout is an optional timeout (in clock ticks) that your task will wait for the
270 * desired bit combination. If you specify 0, however, your task will wait
271 * forever at the specified event flag group or, until a message arrives.
272 *
273 * opt specifies whether you want ALL bits to be set or ANY of the bits to be set.
274 * You can specify the 'ONE' of the following arguments:
275 *
276 * OS_OPT_PEND_FLAG_CLR_ALL You will wait for ALL bits in 'flags' to be clear (0)
277 * OS_OPT_PEND_FLAG_CLR_ANY You will wait for ANY bit in 'flags' to be clear (0)
278 * OS_OPT_PEND_FLAG_SET_ALL You will wait for ALL bits in 'flags' to be set (1)
279 * OS_OPT_PEND_FLAG_SET_ANY You will wait for ANY bit in 'flags' to be set (1)
280 *
281 * You can 'ADD' OS_OPT_PEND_FLAG_CONSUME if you want the event flag to be 'consumed' by
282 * the call. Example, to wait for any flag in a group AND then clear
283 * the flags that are present, set 'wait_opt' to:
284 *
285 * OS_OPT_PEND_FLAG_SET_ANY + OS_OPT_PEND_FLAG_CONSUME
286 *
287 * You can also 'ADD' the type of pend with 'ONE' of the two option:
288 *
289 * OS_OPT_PEND_NON_BLOCKING Task will NOT block if flags are not available
290 * OS_OPT_PEND_BLOCKING Task will block if flags are not available
291 *
292 * p_ts is a pointer to a variable that will receive the timestamp of when the event flag group was
293 * posted, aborted or the event flag group deleted. If you pass a NULL pointer (i.e. (CPU_TS *)0)
294 * then you will not get the timestamp. In other words, passing a NULL pointer is valid and
295 * indicates that you don't need the timestamp.
296 *
297 * p_err is a pointer to an error code and can be:
298 *
299 * OS_ERR_NONE The desired bits have been set within the specified 'timeout'
300 * OS_ERR_OBJ_PTR_NULL If 'p_grp' is a NULL pointer.
301 * OS_ERR_OBJ_TYPE You are not pointing to an event flag group
302 * OS_ERR_OPT_INVALID You didn't specify a proper 'opt' argument.
303 * OS_ERR_PEND_ABORT The wait on the flag was aborted.
304 * OS_ERR_PEND_ISR If you tried to PEND from an ISR
305 * OS_ERR_PEND_WOULD_BLOCK If you specified non-blocking but the flags were not
306 * available.
307 * OS_ERR_SCHED_LOCKED If you called this function when the scheduler is locked
308 * OS_ERR_TIMEOUT The bit(s) have not been set in the specified 'timeout'.
309 *
310 * Returns : The flags in the event flag group that made the task ready or, 0 if a timeout or an error
311 * occurred.
312 ************************************************************************************************************************
313 */
314 
315 OS_FLAGS OSFlagPend (OS_FLAG_GRP *p_grp,
316  OS_FLAGS flags,
317  OS_TICK timeout,
318  OS_OPT opt,
319  CPU_TS *p_ts,
320  OS_ERR *p_err)
321 {
322  CPU_BOOLEAN consume;
323  OS_FLAGS flags_rdy;
324  OS_OPT mode;
325  OS_PEND_DATA pend_data;
326  CPU_SR_ALLOC();
327 
328 
329 
330 #ifdef OS_SAFETY_CRITICAL
331  if (p_err == (OS_ERR *)0) {
332  OS_SAFETY_CRITICAL_EXCEPTION();
333  return ((OS_FLAGS)0);
334  }
335 #endif
336 
337 #if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u
338  if (OSIntNestingCtr > (OS_NESTING_CTR)0) { /* See if called from ISR ... */
339  *p_err = OS_ERR_PEND_ISR; /* ... can't PEND from an ISR */
340  return ((OS_FLAGS)0);
341  }
342 #endif
343 
344 #if OS_CFG_ARG_CHK_EN > 0u
345  if (p_grp == (OS_FLAG_GRP *)0) { /* Validate 'p_grp' */
346  *p_err = OS_ERR_OBJ_PTR_NULL;
347  return ((OS_FLAGS)0);
348  }
349  switch (opt) { /* Validate 'opt' */
366  break;
367 
368  default:
369  *p_err = OS_ERR_OPT_INVALID;
370  return ((OS_OBJ_QTY)0);
371  }
372 #endif
373 
374 #if OS_CFG_OBJ_TYPE_CHK_EN > 0u
375  if (p_grp->Type != OS_OBJ_TYPE_FLAG) { /* Validate that we are pointing at an event flag */
376  *p_err = OS_ERR_OBJ_TYPE;
377  return ((OS_FLAGS)0);
378  }
379 #endif
380 
381  if ((opt & OS_OPT_PEND_FLAG_CONSUME) != (OS_OPT)0) { /* See if we need to consume the flags */
382  consume = DEF_TRUE;
383  } else {
384  consume = DEF_FALSE;
385  }
386 
387  if (p_ts != (CPU_TS *)0) {
388  *p_ts = (CPU_TS)0; /* Initialize the returned timestamp */
389  }
390 
391  mode = opt & OS_OPT_PEND_FLAG_MASK;
393  switch (mode) {
394  case OS_OPT_PEND_FLAG_SET_ALL: /* See if all required flags are set */
395  flags_rdy = (OS_FLAGS)(p_grp->Flags & flags); /* Extract only the bits we want */
396  if (flags_rdy == flags) { /* Must match ALL the bits that we want */
397  if (consume == DEF_TRUE) { /* See if we need to consume the flags */
398  p_grp->Flags &= ~flags_rdy; /* Clear ONLY the flags that we wanted */
399  }
400  OSTCBCurPtr->FlagsRdy = flags_rdy; /* Save flags that were ready */
401  if (p_ts != (CPU_TS *)0) {
402  *p_ts = p_grp->TS;
403  }
404  CPU_CRITICAL_EXIT(); /* Yes, condition met, return to caller */
405  *p_err = OS_ERR_NONE;
406  return (flags_rdy);
407  } else { /* Block task until events occur or timeout */
408  if ((opt & OS_OPT_PEND_NON_BLOCKING) != (OS_OPT)0) {
410  *p_err = OS_ERR_PEND_WOULD_BLOCK; /* Specified non-blocking so task would block */
411  return ((OS_FLAGS)0);
412  } else { /* Specified blocking so check is scheduler is locked */
413  if (OSSchedLockNestingCtr > (OS_NESTING_CTR)0) { /* See if called with scheduler locked ... */
415  *p_err = OS_ERR_SCHED_LOCKED; /* ... can't PEND when locked */
416  return ((OS_FLAGS)0);
417  }
418  }
419 
420  OS_CRITICAL_ENTER_CPU_CRITICAL_EXIT(); /* Lock the scheduler/re-enable interrupts */
421  OS_FlagBlock(&pend_data,
422  p_grp,
423  flags,
424  opt,
425  timeout);
427  }
428  break;
429 
431  flags_rdy = (OS_FLAGS)(p_grp->Flags & flags); /* Extract only the bits we want */
432  if (flags_rdy != (OS_FLAGS)0) { /* See if any flag set */
433  if (consume == DEF_TRUE) { /* See if we need to consume the flags */
434  p_grp->Flags &= ~flags_rdy; /* Clear ONLY the flags that we got */
435  }
436  OSTCBCurPtr->FlagsRdy = flags_rdy; /* Save flags that were ready */
437  if (p_ts != (CPU_TS *)0) {
438  *p_ts = p_grp->TS;
439  }
440  CPU_CRITICAL_EXIT(); /* Yes, condition met, return to caller */
441  *p_err = OS_ERR_NONE;
442  return (flags_rdy);
443  } else { /* Block task until events occur or timeout */
444  if ((opt & OS_OPT_PEND_NON_BLOCKING) != (OS_OPT)0) {
446  *p_err = OS_ERR_PEND_WOULD_BLOCK; /* Specified non-blocking so task would block */
447  return ((OS_FLAGS)0);
448  } else { /* Specified blocking so check is scheduler is locked */
449  if (OSSchedLockNestingCtr > (OS_NESTING_CTR)0) { /* See if called with scheduler locked ... */
451  *p_err = OS_ERR_SCHED_LOCKED; /* ... can't PEND when locked */
452  return ((OS_FLAGS)0);
453  }
454  }
455 
456  OS_CRITICAL_ENTER_CPU_CRITICAL_EXIT(); /* Lock the scheduler/re-enable interrupts */
457  OS_FlagBlock(&pend_data,
458  p_grp,
459  flags,
460  opt,
461  timeout);
463  }
464  break;
465 
466 #if OS_CFG_FLAG_MODE_CLR_EN > 0u
467  case OS_OPT_PEND_FLAG_CLR_ALL: /* See if all required flags are cleared */
468  flags_rdy = (OS_FLAGS)(~p_grp->Flags & flags); /* Extract only the bits we want */
469  if (flags_rdy == flags) { /* Must match ALL the bits that we want */
470  if (consume == DEF_TRUE) { /* See if we need to consume the flags */
471  p_grp->Flags |= flags_rdy; /* Set ONLY the flags that we wanted */
472  }
473  OSTCBCurPtr->FlagsRdy = flags_rdy; /* Save flags that were ready */
474  if (p_ts != (CPU_TS *)0) {
475  *p_ts = p_grp->TS;
476  }
477  CPU_CRITICAL_EXIT(); /* Yes, condition met, return to caller */
478  *p_err = OS_ERR_NONE;
479  return (flags_rdy);
480  } else { /* Block task until events occur or timeout */
481  if ((opt & OS_OPT_PEND_NON_BLOCKING) != (OS_OPT)0) {
483  *p_err = OS_ERR_PEND_WOULD_BLOCK; /* Specified non-blocking so task would block */
484  return ((OS_FLAGS)0);
485  } else { /* Specified blocking so check is scheduler is locked */
486  if (OSSchedLockNestingCtr > (OS_NESTING_CTR)0) { /* See if called with scheduler locked ... */
488  *p_err = OS_ERR_SCHED_LOCKED; /* ... can't PEND when locked */
489  return ((OS_FLAGS)0);
490  }
491  }
492 
493  OS_CRITICAL_ENTER_CPU_CRITICAL_EXIT(); /* Lock the scheduler/re-enable interrupts */
494  OS_FlagBlock(&pend_data,
495  p_grp,
496  flags,
497  opt,
498  timeout);
500  }
501  break;
502 
504  flags_rdy = (OS_FLAGS)(~p_grp->Flags & flags); /* Extract only the bits we want */
505  if (flags_rdy != (OS_FLAGS)0) { /* See if any flag cleared */
506  if (consume == DEF_TRUE) { /* See if we need to consume the flags */
507  p_grp->Flags |= flags_rdy; /* Set ONLY the flags that we got */
508  }
509  OSTCBCurPtr->FlagsRdy = flags_rdy; /* Save flags that were ready */
510  if (p_ts != (CPU_TS *)0) {
511  *p_ts = p_grp->TS;
512  }
513  CPU_CRITICAL_EXIT(); /* Yes, condition met, return to caller */
514  *p_err = OS_ERR_NONE;
515  return (flags_rdy);
516  } else { /* Block task until events occur or timeout */
517  if ((opt & OS_OPT_PEND_NON_BLOCKING) != (OS_OPT)0) {
519  *p_err = OS_ERR_PEND_WOULD_BLOCK; /* Specified non-blocking so task would block */
520  return ((OS_FLAGS)0);
521  } else { /* Specified blocking so check is scheduler is locked */
522  if (OSSchedLockNestingCtr > (OS_NESTING_CTR)0) { /* See if called with scheduler locked ... */
524  *p_err = OS_ERR_SCHED_LOCKED; /* ... can't PEND when locked */
525  return ((OS_FLAGS)0);
526  }
527  }
528 
529  OS_CRITICAL_ENTER_CPU_CRITICAL_EXIT(); /* Lock the scheduler/re-enable interrupts */
530  OS_FlagBlock(&pend_data,
531  p_grp,
532  flags,
533  opt,
534  timeout);
536  }
537  break;
538 #endif
539 
540  default:
542  *p_err = OS_ERR_OPT_INVALID;
543  return ((OS_FLAGS)0);
544  }
545 
546  OSSched(); /* Find next HPT ready to run */
547 
549  switch (OSTCBCurPtr->PendStatus) {
550  case OS_STATUS_PEND_OK: /* We got the vent flags */
551  if (p_ts != (CPU_TS *)0) {
552  *p_ts = OSTCBCurPtr->TS;
553  }
554  *p_err = OS_ERR_NONE;
555  break;
556 
557  case OS_STATUS_PEND_ABORT: /* Indicate that we aborted */
558  if (p_ts != (CPU_TS *)0) {
559  *p_ts = OSTCBCurPtr->TS;
560  }
562  *p_err = OS_ERR_PEND_ABORT;
563  return ((OS_FLAGS)0);
564 
565  case OS_STATUS_PEND_TIMEOUT: /* Indicate that we didn't get semaphore within timeout */
566  if (p_ts != (CPU_TS *)0) {
567  *p_ts = (CPU_TS )0;
568  }
570  *p_err = OS_ERR_TIMEOUT;
571  return ((OS_FLAGS)0);
572 
573  case OS_STATUS_PEND_DEL: /* Indicate that object pended on has been deleted */
574  if (p_ts != (CPU_TS *)0) {
575  *p_ts = OSTCBCurPtr->TS;
576  }
578  *p_err = OS_ERR_OBJ_DEL;
579  return ((OS_FLAGS)0);
580 
581  default:
583  *p_err = OS_ERR_STATUS_INVALID;
584  return ((OS_FLAGS)0);
585  }
586 
587  flags_rdy = OSTCBCurPtr->FlagsRdy;
588  if (consume == DEF_TRUE) { /* See if we need to consume the flags */
589  switch (mode) {
591  case OS_OPT_PEND_FLAG_SET_ANY: /* Clear ONLY the flags we got */
592  p_grp->Flags &= ~flags_rdy;
593  break;
594 
595 #if OS_CFG_FLAG_MODE_CLR_EN > 0u
597  case OS_OPT_PEND_FLAG_CLR_ANY: /* Set ONLY the flags we got */
598  p_grp->Flags |= flags_rdy;
599  break;
600 #endif
601  default:
603  *p_err = OS_ERR_OPT_INVALID;
604  return ((OS_FLAGS)0);
605  }
606  }
608  *p_err = OS_ERR_NONE; /* Event(s) must have occurred */
609  return (flags_rdy);
610 }
611 
612 /*$PAGE*/
613 /*
614 ************************************************************************************************************************
615 * ABORT WAITING ON AN EVENT FLAG GROUP
616 *
617 * Description: This function aborts & readies any tasks currently waiting on an event flag group. This function should
618 * be used to fault-abort the wait on the event flag group, rather than to normally post to the event flag
619 * group OSFlagPost().
620 *
621 * Arguments : p_grp is a pointer to the event flag group
622 *
623 * opt determines the type of ABORT performed:
624 *
625 * OS_OPT_PEND_ABORT_1 ABORT wait for a single task (HPT) waiting on the event flag
626 * OS_OPT_PEND_ABORT_ALL ABORT wait for ALL tasks that are waiting on the event flag
627 * OS_OPT_POST_NO_SCHED Do not call the scheduler
628 *
629 * p_err is a pointer to a variable that will contain an error code returned by this function.
630 *
631 * OS_ERR_NONE At least one task waiting on the event flag group and was
632 * readied and informed of the aborted wait; check return value
633 * for the number of tasks whose wait on the event flag group
634 * was aborted.
635 * OS_ERR_OBJ_PTR_NULL If 'p_grp' is a NULL pointer.
636 * OS_ERR_OBJ_TYPE If 'p_grp' is not pointing at an event flag group
637 * OS_ERR_OPT_INVALID If you specified an invalid option
638 * OS_ERR_PEND_ABORT_ISR If you called this function from an ISR
639 * OS_ERR_PEND_ABORT_NONE No task were pending
640 *
641 * Returns : == 0 if no tasks were waiting on the event flag group, or upon error.
642 * > 0 if one or more tasks waiting on the event flag group are now readied and informed.
643 ************************************************************************************************************************
644 */
645 
646 #if OS_CFG_FLAG_PEND_ABORT_EN > 0u
647 OS_OBJ_QTY OSFlagPendAbort (OS_FLAG_GRP *p_grp,
648  OS_OPT opt,
649  OS_ERR *p_err)
650 {
651  OS_PEND_LIST *p_pend_list;
652  OS_TCB *p_tcb;
653  CPU_TS ts;
654  OS_OBJ_QTY nbr_tasks;
655  CPU_SR_ALLOC();
656 
657 
658 
659 #ifdef OS_SAFETY_CRITICAL
660  if (p_err == (OS_ERR *)0) {
661  OS_SAFETY_CRITICAL_EXCEPTION();
662  return ((OS_OBJ_QTY)0u);
663  }
664 #endif
665 
666 #if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u
667  if (OSIntNestingCtr > (OS_NESTING_CTR)0u) { /* Not allowed to Pend Abort from an ISR */
668  *p_err = OS_ERR_PEND_ABORT_ISR;
669  return ((OS_OBJ_QTY)0u);
670  }
671 #endif
672 
673 #if OS_CFG_ARG_CHK_EN > 0u
674  if (p_grp == (OS_FLAG_GRP *)0) { /* Validate 'p_grp' */
675  *p_err = OS_ERR_OBJ_PTR_NULL;
676  return ((OS_OBJ_QTY)0u);
677  }
678  switch (opt) { /* Validate 'opt' */
679  case OS_OPT_PEND_ABORT_1:
683  break;
684 
685  default:
686  *p_err = OS_ERR_OPT_INVALID;
687  return ((OS_OBJ_QTY)0u);
688  }
689 #endif
690 
691 #if OS_CFG_OBJ_TYPE_CHK_EN > 0u
692  if (p_grp->Type != OS_OBJ_TYPE_FLAG) { /* Make sure event flag group was created */
693  *p_err = OS_ERR_OBJ_TYPE;
694  return ((OS_OBJ_QTY)0u);
695  }
696 #endif
697 
699  p_pend_list = &p_grp->PendList;
700  if (p_pend_list->NbrEntries == (OS_OBJ_QTY)0u) { /* Any task waiting on flag group? */
701  CPU_CRITICAL_EXIT(); /* No */
702  *p_err = OS_ERR_PEND_ABORT_NONE;
703  return ((OS_OBJ_QTY)0u);
704  }
705 
707  nbr_tasks = 0u;
708  ts = OS_TS_GET(); /* Get local time stamp so all tasks get the same time */
709  while (p_pend_list->NbrEntries > (OS_OBJ_QTY)0u) {
710  p_tcb = p_pend_list->HeadPtr->TCBPtr;
711  OS_PendAbort((OS_PEND_OBJ *)((void *)p_grp),
712  p_tcb,
713  ts);
714  nbr_tasks++;
715  if (opt != OS_OPT_PEND_ABORT_ALL) { /* Pend abort all tasks waiting? */
716  break; /* No */
717  }
718  }
720 
721  if ((opt & OS_OPT_POST_NO_SCHED) == (OS_OPT)0u) {
722  OSSched(); /* Run the scheduler */
723  }
724 
725  *p_err = OS_ERR_NONE;
726  return (nbr_tasks);
727 }
728 #endif
729 
730 /*$PAGE*/
731 /*
732 ************************************************************************************************************************
733 * GET FLAGS WHO CAUSED TASK TO BECOME READY
734 *
735 * Description: This function is called to obtain the flags that caused the task to become ready to run.
736 * In other words, this function allows you to tell "Who done it!".
737 *
738 * Arguments : p_err is a pointer to an error code
739 *
740 * OS_ERR_NONE if the call was successful
741 * OS_ERR_PEND_ISR if called from an ISR
742 *
743 * Returns : The flags that caused the task to be ready.
744 ************************************************************************************************************************
745 */
746 
747 OS_FLAGS OSFlagPendGetFlagsRdy (OS_ERR *p_err)
748 {
749  OS_FLAGS flags;
750  CPU_SR_ALLOC();
751 
752 
753 
754 #ifdef OS_SAFETY_CRITICAL
755  if (p_err == (OS_ERR *)0) {
756  OS_SAFETY_CRITICAL_EXCEPTION();
757  return ((OS_FLAGS)0);
758  }
759 #endif
760 
761 #if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u
762  if (OSIntNestingCtr > (OS_NESTING_CTR)0) { /* See if called from ISR ... */
763  *p_err = OS_ERR_PEND_ISR; /* ... can't get from an ISR */
764  return ((OS_FLAGS)0);
765  }
766 #endif
767 
769  flags = OSTCBCurPtr->FlagsRdy;
771  *p_err = OS_ERR_NONE;
772  return (flags);
773 }
774 
775 /*$PAGE*/
776 /*
777 ************************************************************************************************************************
778 * POST EVENT FLAG BIT(S)
779 *
780 * Description: This function is called to set or clear some bits in an event flag group. The bits to set or clear are
781 * specified by a 'bit mask'.
782 *
783 * Arguments : p_grp is a pointer to the desired event flag group.
784 *
785 * flags If 'opt' (see below) is OS_OPT_POST_FLAG_SET, each bit that is set in 'flags' will
786 * set the corresponding bit in the event flag group. e.g. to set bits 0, 4
787 * and 5 you would set 'flags' to:
788 *
789 * 0x31 (note, bit 0 is least significant bit)
790 *
791 * If 'opt' (see below) is OS_OPT_POST_FLAG_CLR, each bit that is set in 'flags' will
792 * CLEAR the corresponding bit in the event flag group. e.g. to clear bits 0,
793 * 4 and 5 you would specify 'flags' as:
794 *
795 * 0x31 (note, bit 0 is least significant bit)
796 *
797 * opt indicates whether the flags will be:
798 *
799 * OS_OPT_POST_FLAG_SET set
800 * OS_OPT_POST_FLAG_CLR cleared
801 *
802 * you can also 'add' OS_OPT_POST_NO_SCHED to prevent the scheduler from being called.
803 *
804 * p_err is a pointer to an error code and can be:
805 *
806 * OS_ERR_NONE The call was successful
807 * OS_ERR_OBJ_PTR_NULL You passed a NULL pointer
808 * OS_ERR_OBJ_TYPE You are not pointing to an event flag group
809 * OS_ERR_OPT_INVALID You specified an invalid option
810 *
811 * Returns : the new value of the event flags bits that are still set.
812 *
813 * Note(s) : 1) The execution time of this function depends on the number of tasks waiting on the event flag group.
814 ************************************************************************************************************************
815 */
816 
817 OS_FLAGS OSFlagPost (OS_FLAG_GRP *p_grp,
818  OS_FLAGS flags,
819  OS_OPT opt,
820  OS_ERR *p_err)
821 {
822  OS_FLAGS flags_cur;
823  CPU_TS ts;
824 
825 
826 
827 #ifdef OS_SAFETY_CRITICAL
828  if (p_err == (OS_ERR *)0) {
829  OS_SAFETY_CRITICAL_EXCEPTION();
830  return ((OS_FLAGS)0);
831  }
832 #endif
833 
834 #if OS_CFG_ARG_CHK_EN > 0u
835  if (p_grp == (OS_FLAG_GRP *)0) { /* Validate 'p_grp' */
836  *p_err = OS_ERR_OBJ_PTR_NULL;
837  return ((OS_FLAGS)0);
838  }
839  switch (opt) { /* Validate 'opt' */
842  case OS_OPT_POST_FLAG_SET | OS_OPT_POST_NO_SCHED:
843  case OS_OPT_POST_FLAG_CLR | OS_OPT_POST_NO_SCHED:
844  break;
845 
846  default:
847  *p_err = OS_ERR_OPT_INVALID;
848  return ((OS_FLAGS)0);
849  }
850 #endif
851 
852 #if OS_CFG_OBJ_TYPE_CHK_EN > 0u
853  if (p_grp->Type != OS_OBJ_TYPE_FLAG) { /* Make sure we are pointing to an event flag grp */
854  *p_err = OS_ERR_OBJ_TYPE;
855  return ((OS_FLAGS)0);
856  }
857 #endif
858 
859  ts = OS_TS_GET(); /* Get timestamp */
860 #if OS_CFG_ISR_POST_DEFERRED_EN > 0u
861  if (OSIntNestingCtr > (OS_NESTING_CTR)0) { /* See if called from an ISR */
862  OS_IntQPost((OS_OBJ_TYPE)OS_OBJ_TYPE_FLAG, /* Post to ISR queue */
863  (void *)p_grp,
864  (void *)0,
865  (OS_MSG_SIZE)0,
866  (OS_FLAGS )flags,
867  (OS_OPT )opt,
868  (CPU_TS )ts,
869  (OS_ERR *)p_err);
870  return ((OS_FLAGS)0);
871  }
872 #endif
873 
874  flags_cur = OS_FlagPost(p_grp,
875  flags,
876  opt,
877  ts,
878  p_err);
879 
880  return (flags_cur);
881 }
882 
883 /*$PAGE*/
884 /*
885 ************************************************************************************************************************
886 * SUSPEND TASK UNTIL EVENT FLAG(s) RECEIVED OR TIMEOUT OCCURS
887 *
888 * Description: This function is internal to uC/OS-III and is used to put a task to sleep until the desired
889 * event flag bit(s) are set.
890 *
891 * Arguments : p_pend_data is a pointer to an object used to link the task being blocked to the list of task(s)
892 * ----------- pending on the desired event flag group.
893 *
894 * p_grp is a pointer to the desired event flag group.
895 * -----
896 *
897 * flags Is a bit pattern indicating which bit(s) (i.e. flags) you wish to check.
898 * The bits you want are specified by setting the corresponding bits in
899 * 'flags'. e.g. if your application wants to wait for bits 0 and 1 then
900 * 'flags' would contain 0x03.
901 *
902 * opt specifies whether you want ALL bits to be set/cleared or ANY of the bits
903 * to be set/cleared.
904 * You can specify the following argument:
905 *
906 * OS_OPT_PEND_FLAG_CLR_ALL You will check ALL bits in 'mask' to be clear (0)
907 * OS_OPT_PEND_FLAG_CLR_ANY You will check ANY bit in 'mask' to be clear (0)
908 * OS_OPT_PEND_FLAG_SET_ALL You will check ALL bits in 'mask' to be set (1)
909 * OS_OPT_PEND_FLAG_SET_ANY You will check ANY bit in 'mask' to be set (1)
910 *
911 * timeout is the desired amount of time that the task will wait for the event flag
912 * bit(s) to be set.
913 *
914 * Returns : none
915 *
916 * Note(s) : This function is INTERNAL to uC/OS-III and your application should not call it.
917 ************************************************************************************************************************
918 */
919 
920 void OS_FlagBlock (OS_PEND_DATA *p_pend_data,
921  OS_FLAG_GRP *p_grp,
922  OS_FLAGS flags,
923  OS_OPT opt,
924  OS_TICK timeout)
925 {
926  OSTCBCurPtr->FlagsPend = flags; /* Save the flags that we need to wait for */
927  OSTCBCurPtr->FlagsOpt = opt; /* Save the type of wait we are doing */
928  OSTCBCurPtr->FlagsRdy = (OS_FLAGS)0;
929 
930  OS_Pend(p_pend_data,
931  (OS_PEND_OBJ *)((void *)p_grp),
933  timeout);
934 }
935 
936 /*$PAGE*/
937 /*
938 ************************************************************************************************************************
939 * CLEAR THE CONTENTS OF AN EVENT FLAG GROUP
940 *
941 * Description: This function is called by OSFlagDel() to clear the contents of an event flag group
942 *
943 
944 * Argument(s): p_grp is a pointer to the event flag group to clear
945 * -----
946 *
947 * Returns : none
948 *
949 * Note(s) : This function is INTERNAL to uC/OS-III and your application should not call it.
950 ************************************************************************************************************************
951 */
952 
953 void OS_FlagClr (OS_FLAG_GRP *p_grp)
954 {
955  OS_PEND_LIST *p_pend_list;
956 
957 
958 
959  p_grp->Type = OS_OBJ_TYPE_NONE;
960  p_grp->NamePtr = (CPU_CHAR *)((void *)"?FLAG"); /* Unknown name */
961  p_grp->Flags = (OS_FLAGS )0;
962  p_pend_list = &p_grp->PendList;
963  OS_PendListInit(p_pend_list);
964 }
965 
966 /*$PAGE*/
967 /*
968 ************************************************************************************************************************
969 * INITIALIZE THE EVENT FLAG MODULE
970 *
971 * Description: This function is called by uC/OS-III to initialize the event flag module. Your application MUST NOT call
972 * this function. In other words, this function is internal to uC/OS-III.
973 *
974 * Arguments : p_err is a pointer to an error code that can contain one of the following values:
975 *
976 * OS_ERR_NONE The call was successful.
977 *
978 * Returns : none
979 *
980 * Note(s) : This function is INTERNAL to uC/OS-III and your application should not call it.
981 ************************************************************************************************************************
982 */
983 
984 void OS_FlagInit (OS_ERR *p_err)
985 {
986 #ifdef OS_SAFETY_CRITICAL
987  if (p_err == (OS_ERR *)0) {
988  OS_SAFETY_CRITICAL_EXCEPTION();
989  return;
990  }
991 #endif
992 
993 #if OS_CFG_DBG_EN > 0u
994  OSFlagDbgListPtr = (OS_FLAG_GRP *)0;
995 #endif
996 
997  OSFlagQty = (OS_OBJ_QTY )0;
998  *p_err = OS_ERR_NONE;
999 }
1000 
1001 /*$PAGE*/
1002 /*
1003 ************************************************************************************************************************
1004 * ADD/REMOVE EVENT FLAG GROUP TO/FROM DEBUG LIST
1005 *
1006 * Description: These functions are called by uC/OS-III to add or remove an event flag group from the event flag debug
1007 * list.
1008 *
1009 * Arguments : p_grp is a pointer to the event flag group to add/remove
1010 *
1011 * Returns : none
1012 *
1013 * Note(s) : These functions are INTERNAL to uC/OS-III and your application should not call it.
1014 ************************************************************************************************************************
1015 */
1016 
1017 #if OS_CFG_DBG_EN > 0u
1018 void OS_FlagDbgListAdd (OS_FLAG_GRP *p_grp)
1019 {
1020  p_grp->DbgNamePtr = (CPU_CHAR *)((void *)" ");
1021  p_grp->DbgPrevPtr = (OS_FLAG_GRP *)0;
1022  if (OSFlagDbgListPtr == (OS_FLAG_GRP *)0) {
1023  p_grp->DbgNextPtr = (OS_FLAG_GRP *)0;
1024  } else {
1025  p_grp->DbgNextPtr = OSFlagDbgListPtr;
1026  OSFlagDbgListPtr->DbgPrevPtr = p_grp;
1027  }
1028  OSFlagDbgListPtr = p_grp;
1029 }
1030 
1031 
1032 
1033 void OS_FlagDbgListRemove (OS_FLAG_GRP *p_grp)
1034 {
1035  OS_FLAG_GRP *p_grp_next;
1036  OS_FLAG_GRP *p_grp_prev;
1037 
1038 
1039  p_grp_prev = p_grp->DbgPrevPtr;
1040  p_grp_next = p_grp->DbgNextPtr;
1041 
1042  if (p_grp_prev == (OS_FLAG_GRP *)0) {
1043  OSFlagDbgListPtr = p_grp_next;
1044  if (p_grp_next != (OS_FLAG_GRP *)0) {
1045  p_grp_next->DbgPrevPtr = (OS_FLAG_GRP *)0;
1046  }
1047  p_grp->DbgNextPtr = (OS_FLAG_GRP *)0;
1048 
1049  } else if (p_grp_next == (OS_FLAG_GRP *)0) {
1050  p_grp_prev->DbgNextPtr = (OS_FLAG_GRP *)0;
1051  p_grp->DbgPrevPtr = (OS_FLAG_GRP *)0;
1052 
1053  } else {
1054  p_grp_prev->DbgNextPtr = p_grp_next;
1055  p_grp_next->DbgPrevPtr = p_grp_prev;
1056  p_grp->DbgNextPtr = (OS_FLAG_GRP *)0;
1057  p_grp->DbgPrevPtr = (OS_FLAG_GRP *)0;
1058  }
1059 }
1060 #endif
1061 
1062 /*$PAGE*/
1063 /*
1064 ************************************************************************************************************************
1065 * POST EVENT FLAG BIT(S)
1066 *
1067 * Description: This function is called to set or clear some bits in an event flag group. The bits to set or clear are
1068 * specified by a 'bit mask'.
1069 *
1070 * Arguments : p_grp is a pointer to the desired event flag group.
1071 *
1072 * flags If 'opt' (see below) is OS_OPT_POST_FLAG_SET, each bit that is set in 'flags' will
1073 * set the corresponding bit in the event flag group. e.g. to set bits 0, 4
1074 * and 5 you would set 'flags' to:
1075 *
1076 * 0x31 (note, bit 0 is least significant bit)
1077 *
1078 * If 'opt' (see below) is OS_OPT_POST_FLAG_CLR, each bit that is set in 'flags' will
1079 * CLEAR the corresponding bit in the event flag group. e.g. to clear bits 0,
1080 * 4 and 5 you would specify 'flags' as:
1081 *
1082 * 0x31 (note, bit 0 is least significant bit)
1083 *
1084 * opt indicates whether the flags will be:
1085 *
1086 * OS_OPT_POST_FLAG_SET set
1087 * OS_OPT_POST_FLAG_CLR cleared
1088 *
1089 * you can also 'add' OS_OPT_POST_NO_SCHED to prevent the scheduler from being called.
1090 *
1091 * ts is the timestamp of the post
1092 *
1093 * p_err is a pointer to an error code and can be:
1094 *
1095 * OS_ERR_NONE The call was successful
1096 * OS_ERR_OBJ_PTR_NULL You passed a NULL pointer
1097 * OS_ERR_OBJ_TYPE You are not pointing to an event flag group
1098 * OS_ERR_OPT_INVALID You specified an invalid option
1099 *
1100 * Returns : the new value of the event flags bits that are still set.
1101 *
1102 * Note(s) : 1) The execution time of this function depends on the number of tasks waiting on the event flag group.
1103 ************************************************************************************************************************
1104 */
1105 
1106 OS_FLAGS OS_FlagPost (OS_FLAG_GRP *p_grp,
1107  OS_FLAGS flags,
1108  OS_OPT opt,
1109  CPU_TS ts,
1110  OS_ERR *p_err)
1111 {
1112  OS_FLAGS flags_cur;
1113  OS_FLAGS flags_rdy;
1114  OS_OPT mode;
1115  OS_PEND_DATA *p_pend_data;
1116  OS_PEND_DATA *p_pend_data_next;
1117  OS_PEND_LIST *p_pend_list;
1118  OS_TCB *p_tcb;
1119  CPU_SR_ALLOC();
1120 
1121 
1122 
1124  switch (opt) {
1125  case OS_OPT_POST_FLAG_SET:
1126  case OS_OPT_POST_FLAG_SET | OS_OPT_POST_NO_SCHED:
1127  p_grp->Flags |= flags; /* Set the flags specified in the group */
1128  break;
1129 
1130  case OS_OPT_POST_FLAG_CLR:
1131  case OS_OPT_POST_FLAG_CLR | OS_OPT_POST_NO_SCHED:
1132  p_grp->Flags &= ~flags; /* Clear the flags specified in the group */
1133  break;
1134 
1135  default:
1136  CPU_CRITICAL_EXIT(); /* INVALID option */
1137  *p_err = OS_ERR_OPT_INVALID;
1138  return ((OS_FLAGS)0);
1139  }
1140  p_grp->TS = ts;
1141  p_pend_list = &p_grp->PendList;
1142  if (p_pend_list->NbrEntries == 0u) { /* Any task waiting on event flag group? */
1143  CPU_CRITICAL_EXIT(); /* No */
1144  *p_err = OS_ERR_NONE;
1145  return (p_grp->Flags);
1146  }
1147 
1149  p_pend_data = p_pend_list->HeadPtr;
1150  p_tcb = p_pend_data->TCBPtr;
1151  while (p_tcb != (OS_TCB *)0) { /* Go through all tasks waiting on event flag(s) */
1152  p_pend_data_next = p_pend_data->NextPtr;
1153  mode = p_tcb->FlagsOpt & OS_OPT_PEND_FLAG_MASK;
1154  switch (mode) {
1155  case OS_OPT_PEND_FLAG_SET_ALL: /* See if all req. flags are set for current node */
1156  flags_rdy = (OS_FLAGS)(p_grp->Flags & p_tcb->FlagsPend);
1157  if (flags_rdy == p_tcb->FlagsPend) {
1158  OS_FlagTaskRdy(p_tcb, /* Make task RTR, event(s) Rx'd */
1159  flags_rdy,
1160  ts);
1161  }
1162  break;
1163 
1164  case OS_OPT_PEND_FLAG_SET_ANY: /* See if any flag set */
1165  flags_rdy = (OS_FLAGS)(p_grp->Flags & p_tcb->FlagsPend);
1166  if (flags_rdy != (OS_FLAGS)0) {
1167  OS_FlagTaskRdy(p_tcb, /* Make task RTR, event(s) Rx'd */
1168  flags_rdy,
1169  ts);
1170  }
1171  break;
1172 
1173 #if OS_CFG_FLAG_MODE_CLR_EN > 0u
1174  case OS_OPT_PEND_FLAG_CLR_ALL: /* See if all req. flags are set for current node */
1175  flags_rdy = (OS_FLAGS)(~p_grp->Flags & p_tcb->FlagsPend);
1176  if (flags_rdy == p_tcb->FlagsPend) {
1177  OS_FlagTaskRdy(p_tcb, /* Make task RTR, event(s) Rx'd */
1178  flags_rdy,
1179  ts);
1180  }
1181  break;
1182 
1183  case OS_OPT_PEND_FLAG_CLR_ANY: /* See if any flag set */
1184  flags_rdy = (OS_FLAGS)(~p_grp->Flags & p_tcb->FlagsPend);
1185  if (flags_rdy != (OS_FLAGS)0) {
1186  OS_FlagTaskRdy(p_tcb, /* Make task RTR, event(s) Rx'd */
1187  flags_rdy,
1188  ts);
1189  }
1190  break;
1191 #endif
1192  default:
1193  OS_CRITICAL_EXIT();
1194  *p_err = OS_ERR_FLAG_PEND_OPT;
1195  return ((OS_FLAGS)0);
1196  }
1197  p_pend_data = p_pend_data_next; /* Point to next task waiting for event flag(s) */
1198  if (p_pend_data != (OS_PEND_DATA *)0) {
1199  p_tcb = p_pend_data->TCBPtr;
1200  } else {
1201  p_tcb = (OS_TCB *)0;
1202  }
1203  }
1205 
1206  if ((opt & OS_OPT_POST_NO_SCHED) == (OS_OPT)0) {
1207  OSSched();
1208  }
1209 
1211  flags_cur = p_grp->Flags;
1213  *p_err = OS_ERR_NONE;
1214  return (flags_cur);
1215 }
1216 
1217 /*$PAGE*/
1218 /*
1219 ************************************************************************************************************************
1220 * MAKE TASK READY-TO-RUN, EVENT(s) OCCURRED
1221 *
1222 * Description: This function is internal to uC/OS-III and is used to make a task ready-to-run because the desired event
1223 * flag bits have been set.
1224 *
1225 * Arguments : p_tcb is a pointer to the OS_TCB of the task to remove
1226 * -----
1227 *
1228 * flags_rdy contains the bit pattern of the event flags that cause the task to become ready-to-run.
1229 *
1230 * ts is a timestamp associated with the post
1231 *
1232 * Returns : none
1233 *
1234 * Note(s) : This function is INTERNAL to uC/OS-III and your application should not call it.
1235 ************************************************************************************************************************
1236 */
1237 
1238 void OS_FlagTaskRdy (OS_TCB *p_tcb,
1239  OS_FLAGS flags_rdy,
1240  CPU_TS ts)
1241 {
1242  p_tcb->FlagsRdy = flags_rdy;
1243  p_tcb->PendStatus = OS_STATUS_PEND_OK; /* Clear pend status */
1244  p_tcb->PendOn = OS_TASK_PEND_ON_NOTHING; /* Indicate no longer pending */
1245  p_tcb->TS = ts;
1246  switch (p_tcb->TaskState) {
1247  case OS_TASK_STATE_RDY:
1248  case OS_TASK_STATE_DLY:
1251  break;
1252 
1253  case OS_TASK_STATE_PEND:
1255  OS_TaskRdy(p_tcb);
1256  p_tcb->TaskState = OS_TASK_STATE_RDY;
1257  break;
1258 
1261  p_tcb->TaskState = OS_TASK_STATE_SUSPENDED;
1262  break;
1263 
1264  default:
1265  break;
1266  }
1267  OS_PendListRemove(p_tcb);
1268 }
1269 #endif