OS_FLAG_GRP *OSFlagCreate(OS_FLAGS flags,
INT8U *perr){
OS_FLAG_GRP *pgrp;#ifOS_CRITICAL_METHOD ==3u/* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr =0u;#endif#ifdefOS_SAFETY_CRITICALif(perr ==(INT8U *)0){OS_SAFETY_CRITICAL_EXCEPTION();return((OS_FLAG_GRP *)0);}#endif#ifdefOS_SAFETY_CRITICAL_IEC61508if(OSSafetyCriticalStartFlag == OS_TRUE){OS_SAFETY_CRITICAL_EXCEPTION();return((OS_FLAG_GRP *)0);}#endifif(OSIntNesting >0u)/* See if called from ISR ... */{*perr = OS_ERR_CREATE_ISR;/* ... can't CREATE from an ISR */return((OS_FLAG_GRP *)0);}OS_ENTER_CRITICAL();
pgrp = OSFlagFreeList;/* Get next free event flag */if(pgrp !=(OS_FLAG_GRP *)0)/* See if we have event flag groups available */{/* Adjust free list */
OSFlagFreeList =(OS_FLAG_GRP *)OSFlagFreeList->OSFlagWaitList;
pgrp->OSFlagType = OS_EVENT_TYPE_FLAG;/* Set to event flag group type */
pgrp->OSFlagFlags = flags;/* Set to desired initial value */
pgrp->OSFlagWaitList =(void*)0;/* Clear list of tasks waiting on flags */#ifOS_FLAG_NAME_EN >0u
pgrp->OSFlagName =(INT8U *)(void*)"?";#endifOS_EXIT_CRITICAL();*perr = OS_ERR_NONE;}else{OS_EXIT_CRITICAL();*perr = OS_ERR_FLAG_GRP_DEPLETED;}return(pgrp);/* Return pointer to event flag group */}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
事件标志组删除
#ifOS_FLAG_DEL_EN >0u
OS_FLAG_GRP *OSFlagDel(OS_FLAG_GRP *pgrp,
INT8U opt,
INT8U *perr){
BOOLEAN tasks_waiting;
OS_FLAG_NODE *pnode;
OS_FLAG_GRP *pgrp_return;#ifOS_CRITICAL_METHOD ==3u/* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr =0u;#endif#ifdefOS_SAFETY_CRITICALif(perr ==(INT8U *)0){OS_SAFETY_CRITICAL_EXCEPTION();return((OS_FLAG_GRP *)0);}#endif#ifOS_ARG_CHK_EN >0uif(pgrp ==(OS_FLAG_GRP *)0)/* Validate 'pgrp' */{*perr = OS_ERR_FLAG_INVALID_PGRP;return(pgrp);}#endifif(OSIntNesting >0u)/* See if called from ISR ... */{*perr = OS_ERR_DEL_ISR;/* ... can't DELETE from an ISR */return(pgrp);}if(pgrp->OSFlagType != OS_EVENT_TYPE_FLAG)/* Validate event group type */{*perr = OS_ERR_EVENT_TYPE;return(pgrp);}OS_ENTER_CRITICAL();if(pgrp->OSFlagWaitList !=(void*)0)/* See if any tasks waiting on event flags */{
tasks_waiting = OS_TRUE;/* Yes */}else{
tasks_waiting = OS_FALSE;/* No */}switch(opt){case OS_DEL_NO_PEND:/* Delete group if no task waiting */if(tasks_waiting == OS_FALSE){#ifOS_FLAG_NAME_EN >0u
pgrp->OSFlagName =(INT8U *)(void*)"?";#endif
pgrp->OSFlagType = OS_EVENT_TYPE_UNUSED;
pgrp->OSFlagWaitList =(void*)OSFlagFreeList;/* Return group to free list */
pgrp->OSFlagFlags =(OS_FLAGS)0;
OSFlagFreeList = pgrp;OS_EXIT_CRITICAL();*perr = OS_ERR_NONE;
pgrp_return =(OS_FLAG_GRP *)0;/* Event Flag Group has been deleted */}else{OS_EXIT_CRITICAL();*perr = OS_ERR_TASK_WAITING;
pgrp_return = pgrp;}break;case OS_DEL_ALWAYS:/* Always delete the event flag group */
pnode =(OS_FLAG_NODE *)pgrp->OSFlagWaitList;while(pnode !=(OS_FLAG_NODE *)0)/* Ready ALL tasks waiting for flags */{(void)OS_FlagTaskRdy(pnode,(OS_FLAGS)0, OS_STAT_PEND_ABORT);
pnode =(OS_FLAG_NODE *)pnode->OSFlagNodeNext;}#ifOS_FLAG_NAME_EN >0u
pgrp->OSFlagName =(INT8U *)(void*)"?";#endif
pgrp->OSFlagType = OS_EVENT_TYPE_UNUSED;
pgrp->OSFlagWaitList =(void*)OSFlagFreeList;/* Return group to free list */
pgrp->OSFlagFlags =(OS_FLAGS)0;
OSFlagFreeList = pgrp;OS_EXIT_CRITICAL();if(tasks_waiting == OS_TRUE)/* Reschedule only if task(s) were waiting */{OS_Sched();/* Find highest priority task ready to run */}*perr = OS_ERR_NONE;
pgrp_return =(OS_FLAG_GRP *)0;/* Event Flag Group has been deleted */break;default:OS_EXIT_CRITICAL();*perr = OS_ERR_INVALID_OPT;
pgrp_return = pgrp;break;}return(pgrp_return);}#endif
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
事件标志组获取/等待
OS_FLAGS OSFlagPend(OS_FLAG_GRP *pgrp,
OS_FLAGS flags,
INT8U wait_type,
INT32U timeout,
INT8U *perr){
OS_FLAG_NODE node;
OS_FLAGS flags_rdy;
INT8U result;
INT8U pend_stat;
BOOLEAN consume;#ifOS_CRITICAL_METHOD ==3u/* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr =0u;#endif#ifdefOS_SAFETY_CRITICALif(perr ==(INT8U *)0){OS_SAFETY_CRITICAL_EXCEPTION();return((OS_FLAGS)0);}#endif#ifOS_ARG_CHK_EN >0uif(pgrp ==(OS_FLAG_GRP *)0)/* Validate 'pgrp' */{*perr = OS_ERR_FLAG_INVALID_PGRP;return((OS_FLAGS)0);}#endifif(OSIntNesting >0u)/* See if called from ISR ... */{*perr = OS_ERR_PEND_ISR;/* ... can't PEND from an ISR */return((OS_FLAGS)0);}if(OSLockNesting >0u)/* See if called with scheduler locked ... */{*perr = OS_ERR_PEND_LOCKED;/* ... can't PEND when locked */return((OS_FLAGS)0);}if(pgrp->OSFlagType != OS_EVENT_TYPE_FLAG)/* Validate event block type */{*perr = OS_ERR_EVENT_TYPE;return((OS_FLAGS)0);}
result =(INT8U)(wait_type & OS_FLAG_CONSUME);if(result !=(INT8U)0)/* See if we need to consume the flags */{
wait_type &=(INT8U)~(INT8U)OS_FLAG_CONSUME;
consume = OS_TRUE;}else{
consume = OS_FALSE;}/*$PAGE*/OS_ENTER_CRITICAL();switch(wait_type){case OS_FLAG_WAIT_SET_ALL:/* See if all required flags are set */
flags_rdy =(OS_FLAGS)(pgrp->OSFlagFlags & flags);/* Extract only the bits we want */if(flags_rdy == flags)/* Must match ALL the bits that we want */{if(consume == OS_TRUE)/* See if we need to consume the flags */{
pgrp->OSFlagFlags &=(OS_FLAGS)~flags_rdy;/* Clear ONLY the flags we wanted */}
OSTCBCur->OSTCBFlagsRdy = flags_rdy;/* Save flags that were ready */OS_EXIT_CRITICAL();/* Yes, condition met, return to caller */*perr = OS_ERR_NONE;return(flags_rdy);}else/* Block task until events occur or timeout */{OS_FlagBlock(pgrp,&node, flags, wait_type, timeout);OS_EXIT_CRITICAL();}break;case OS_FLAG_WAIT_SET_ANY:
flags_rdy =(OS_FLAGS)(pgrp->OSFlagFlags & flags);/* Extract only the bits we want */if(flags_rdy !=(OS_FLAGS)0)/* See if any flag set */{if(consume == OS_TRUE)/* See if we need to consume the flags */{
pgrp->OSFlagFlags &=(OS_FLAGS)~flags_rdy;/* Clear ONLY the flags that we got */}
OSTCBCur->OSTCBFlagsRdy = flags_rdy;/* Save flags that were ready */OS_EXIT_CRITICAL();/* Yes, condition met, return to caller */*perr = OS_ERR_NONE;return(flags_rdy);}else/* Block task until events occur or timeout */{OS_FlagBlock(pgrp,&node, flags, wait_type, timeout);OS_EXIT_CRITICAL();}break;#ifOS_FLAG_WAIT_CLR_EN >0ucase OS_FLAG_WAIT_CLR_ALL:/* See if all required flags are cleared */
flags_rdy =(OS_FLAGS)~pgrp->OSFlagFlags & flags;/* Extract only the bits we want */if(flags_rdy == flags)/* Must match ALL the bits that we want */{if(consume == OS_TRUE)/* See if we need to consume the flags */{
pgrp->OSFlagFlags |= flags_rdy;/* Set ONLY the flags that we wanted */}
OSTCBCur->OSTCBFlagsRdy = flags_rdy;/* Save flags that were ready */OS_EXIT_CRITICAL();/* Yes, condition met, return to caller */*perr = OS_ERR_NONE;return(flags_rdy);}else/* Block task until events occur or timeout */{OS_FlagBlock(pgrp,&node, flags, wait_type, timeout);OS_EXIT_CRITICAL();}break;case OS_FLAG_WAIT_CLR_ANY:
flags_rdy =(OS_FLAGS)~pgrp->OSFlagFlags & flags;/* Extract only the bits we want */if(flags_rdy !=(OS_FLAGS)0)/* See if any flag cleared */{if(consume == OS_TRUE)/* See if we need to consume the flags */{
pgrp->OSFlagFlags |= flags_rdy;/* Set ONLY the flags that we got */}
OSTCBCur->OSTCBFlagsRdy = flags_rdy;/* Save flags that were ready */OS_EXIT_CRITICAL();/* Yes, condition met, return to caller */*perr = OS_ERR_NONE;return(flags_rdy);}else/* Block task until events occur or timeout */{OS_FlagBlock(pgrp,&node, flags, wait_type, timeout);OS_EXIT_CRITICAL();}break;#endifdefault:OS_EXIT_CRITICAL();
flags_rdy =(OS_FLAGS)0;*perr = OS_ERR_FLAG_WAIT_TYPE;return(flags_rdy);}/*$PAGE*/OS_Sched();/* Find next HPT ready to run */OS_ENTER_CRITICAL();if(OSTCBCur->OSTCBStatPend != OS_STAT_PEND_OK)/* Have we timed-out or aborted? */{
pend_stat = OSTCBCur->OSTCBStatPend;
OSTCBCur->OSTCBStatPend = OS_STAT_PEND_OK;OS_FlagUnlink(&node);
OSTCBCur->OSTCBStat = OS_STAT_RDY;/* Yes, make task ready-to-run */OS_EXIT_CRITICAL();
flags_rdy =(OS_FLAGS)0;switch(pend_stat){case OS_STAT_PEND_ABORT:*perr = OS_ERR_PEND_ABORT;/* Indicate that we aborted waiting */break;case OS_STAT_PEND_TO:default:*perr = OS_ERR_TIMEOUT;/* Indicate that we timed-out waiting */break;}return(flags_rdy);}
flags_rdy = OSTCBCur->OSTCBFlagsRdy;if(consume == OS_TRUE)/* See if we need to consume the flags */{switch(wait_type){case OS_FLAG_WAIT_SET_ALL:case OS_FLAG_WAIT_SET_ANY:/* Clear ONLY the flags we got */
pgrp->OSFlagFlags &=(OS_FLAGS)~flags_rdy;break;#ifOS_FLAG_WAIT_CLR_EN >0ucase OS_FLAG_WAIT_CLR_ALL:case OS_FLAG_WAIT_CLR_ANY:/* Set ONLY the flags we got */
pgrp->OSFlagFlags |= flags_rdy;break;#endifdefault:OS_EXIT_CRITICAL();*perr = OS_ERR_FLAG_WAIT_TYPE;return((OS_FLAGS)0);}}OS_EXIT_CRITICAL();*perr = OS_ERR_NONE;/* Event(s) must have occurred */return(flags_rdy);}