tinyOS  v1.00
tFlagGroup.c
Go to the documentation of this file.
1 
14 #include "tFlagGroup.h"
15 #include "tinyOS.h"
16 
17 #if !defined(TINYOS_ENABLE_FLAGGROUP) || TINYOS_ENABLE_FLAGGROUP == 1
18 
24 void tFlagGroupInit (tFlagGroup *flagGroup, uint32_t flags) {
25  tEventInit(&flagGroup->event, tEventTypeFlagGroup);
26  flagGroup->flags = flags;
27 }
28 
38 static uint32_t tFlagGroupCheckAndConsume (tFlagGroup *flagGroup, uint32_t type, uint32_t *flags) {
39  uint32_t srcFlags = *flags;
40  uint32_t isSet = type & TFLAGGROUP_SET;
41  uint32_t isAll = type & TFLAGGROUP_ALL;
42  uint32_t isConsume = type & TFLAGGROUP_CONSUME;
43 
44  // 有哪些类型的标志位出现
45  // flagGroup->flags & flags:计算出哪些位为1
46  // ~flagGroup->flags & flags:计算出哪位为0
47  uint32_t calcFlag = isSet ? (flagGroup->flags & srcFlags) : (~flagGroup->flags & srcFlags);
48 
49  // 所有标志位出现, 或者做任意标志位出现,满足条件
50  if (((isAll != 0) && (calcFlag == srcFlags)) || ((isAll == 0) && (calcFlag != 0))) {
51  // 是否消耗掉标志位
52  if (isConsume) {
53  if (isSet) {
54  // 清除为1的标志位,变成0
55  flagGroup->flags &= ~srcFlags;
56  } else {
57  // 清除为0的标志位,变成1
58  flagGroup->flags |= srcFlags;
59  }
60  }
61  *flags = calcFlag;
62  return tErrorNoError;
63  }
64 
65  *flags = calcFlag;
67 }
68 
78 uint32_t tFlagGroupWait (tFlagGroup *flagGroup, uint32_t waitType, uint32_t requestFlag,
79  uint32_t *resultFlag, uint32_t waitTicks) {
80  uint32_t result;
81  uint32_t flags = requestFlag;
82 
83  uint32_t status = tTaskEnterCritical();
84  result = tFlagGroupCheckAndConsume(flagGroup, waitType, &flags);
85  if (result != tErrorNoError) {
86  // 如果事件标志不满足条件,则插入到等待队列中
87  currentTask->waitFlagsType = waitType;
88  currentTask->eventFlags = requestFlag;
89  tEventWait(&flagGroup->event, currentTask, (void *) 0, tEventTypeFlagGroup, waitTicks);
90 
91  tTaskExitCritical(status);
92 
93  // 再执行一次事件调度,以便于切换到其它任务
94  tTaskSched();
95 
96  *resultFlag = currentTask->eventFlags;
97  result = currentTask->waitEventResult;
98  } else {
99  *resultFlag = flags;
100  tTaskExitCritical(status);
101  }
102 
103  return result;
104 }
105 
114 uint32_t tFlagGroupNoWaitGet (tFlagGroup *flagGroup, uint32_t waitType, uint32_t requestFlag, uint32_t *resultFlag) {
115  uint32_t flags = requestFlag;
116 
117  uint32_t status = tTaskEnterCritical();
118  uint32_t result = tFlagGroupCheckAndConsume(flagGroup, waitType, &flags);
119  tTaskExitCritical(status);
120 
121  *resultFlag = flags;
122  return status;
123 }
124 
131 void tFlagGroupNotify (tFlagGroup *flagGroup, uint8_t isSet, uint32_t flags) {
132  tList *waitList;
133  tNode *node;
134  tNode *nextNode;
135  uint8_t sched = 0;
136 
137  uint32_t status = tTaskEnterCritical();
138 
139  if (isSet) {
140  flagGroup->flags |= flags; // 置1事件
141  } else {
142  flagGroup->flags &= ~flags; // 清0事件
143  }
144 
145  // 遍历所有的等待任务, 获取满足条件的任务,加入到待移除列表中
146  waitList = &flagGroup->event.waitList;
147  for (node = waitList->headNode.nextNode; node != &(waitList->headNode); node = nextNode) {
148  uint32_t result;
149  tTask *task = tNodeParent(node, tTask, linkNode);
150  uint32_t flags = task->eventFlags;
151  nextNode = node->nextNode;
152 
153  // 检查标志
154  result = tFlagGroupCheckAndConsume(flagGroup, task->waitFlagsType, &flags);
155  if (result == tErrorNoError) {
156  // 唤醒任务
157  task->eventFlags = flags;
158  tEventWakeUpTask(&flagGroup->event, task, (void *) 0, tErrorNoError);
159  sched = 1;
160  }
161  }
162 
163  // 如果有任务就绪,则执行一次调度
164  if (sched) {
165  tTaskSched();
166  }
167 
168  tTaskExitCritical(status);
169 }
170 
176 void tFlagGroupGetInfo (tFlagGroup *flagGroup, tFlagGroupInfo *info) {
177  uint32_t status = tTaskEnterCritical();
178 
179  // 拷贝需要的信息
180  info->flags = flagGroup->flags;
181  info->taskCount = tEventWaitCount(&flagGroup->event);
182 
183  tTaskExitCritical(status);
184 }
185 
191 uint32_t tFlagGroupDestroy (tFlagGroup *flagGroup) {
192  uint32_t status = tTaskEnterCritical();
193 
194  // 清空事件控制块中的任务
195  uint32_t count = tEventRemoveAll(&flagGroup->event, (void *) 0, tErrorDel);
196 
197  tTaskExitCritical(status);
198 
199  // 清空过程中可能有任务就绪,执行一次调度
200  if (count > 0) {
201  tTaskSched();
202  }
203  return count;
204 }
205 
206 #endif // TINYOS_ENABLE_FLAGGROUP
207 
uint32_t flags
Definition: tFlagGroup.h:31
void tFlagGroupInit(tFlagGroup *flagGroup, uint32_t flags)
Definition: tFlagGroup.c:24
Definition: tTask.h:31
#define TFLAGGROUP_CONSUME
Definition: tFlagGroup.h:45
tEvent event
Definition: tFlagGroup.h:25
uint32_t tFlagGroupNoWaitGet(tFlagGroup *flagGroup, uint32_t waitType, uint32_t requestFlag, uint32_t *resultFlag)
Definition: tFlagGroup.c:114
uint32_t tEventRemoveAll(tEvent *event, void *msg, uint32_t result)
Definition: tEvent.c:163
tTaskCritical_t tTaskEnterCritical(void)
Definition: tSwitch.c:36
#define tNodeParent(node, parent, name)
Definition: tLib.h:48
tList waitList
Definition: tEvent.h:34
#define TFLAGGROUP_SET
Definition: tFlagGroup.h:36
uint32_t tEventWaitCount(tEvent *event)
Definition: tEvent.c:206
void tTaskSched(void)
任务调度接口。通过它来选择下一个具体的任务,然后切换至该任务运行。
Definition: tCore.c:126
Definition: tLib.h:35
void tFlagGroupNotify(tFlagGroup *flagGroup, uint8_t isSet, uint32_t flags)
Definition: tFlagGroup.c:131
void tEventInit(tEvent *event, tEventType type)
Definition: tEvent.c:21
uint32_t tFlagGroupDestroy(tFlagGroup *flagGroup)
Definition: tFlagGroup.c:191
uint32_t eventFlags
Definition: tTask.h:61
void tTaskExitCritical(tTaskCritical_t status)
Definition: tSwitch.c:47
void tEventWait(tEvent *event, tTask *task, void *msg, uint32_t state, uint32_t timeout)
Definition: tEvent.c:35
void tFlagGroupGetInfo(tFlagGroup *flagGroup, tFlagGroupInfo *info)
Definition: tFlagGroup.c:176
void tEventWakeUpTask(tEvent *event, tTask *task, void *msg, uint32_t result)
Definition: tEvent.c:109
uint32_t waitFlagsType
Definition: tTask.h:60
struct _tNode * nextNode
Definition: tLib.h:37
uint32_t taskCount
Definition: tFlagGroup.h:32
tTask * currentTask
当前任务:记录当前是哪个任务正在运行
Definition: tCore.c:17
#define TFLAGGROUP_ALL
Definition: tFlagGroup.h:38
tNode headNode
Definition: tLib.h:44
uint32_t tFlagGroupWait(tFlagGroup *flagGroup, uint32_t waitType, uint32_t requestFlag, uint32_t *resultFlag, uint32_t waitTicks)
Definition: tFlagGroup.c:78
uint32_t flags
Definition: tFlagGroup.h:26
Definition: tLib.h:43
uint32_t waitEventResult
Definition: tTask.h:59