tinyOS  v1.00
tTimer.c
Go to the documentation of this file.
1 
14 #include "tTimer.h"
15 #include "tinyOS.h"
16 
17 #if !defined(TINYOS_ENABLE_TIMER) || TINYOS_ENABLE_TIMER == 1
18 
19 static tList tTimerHardList; // "硬"定时器列表
20 static tList tTimerSoftList; // "软"定时器列表
21 static tSem tTimerProtectSem; // 用于访问软定时器列表的信号量
22 static tSem tTimerTickSem; // 用于软定时器任务与中断同步的计数信号量
23 
34 void tTimerInit (tTimer *timer, uint32_t delayTicks, uint32_t durationTicks,
35  void (*timerFunc) (void *arg), void *arg, uint32_t config) {
36  tNodeInit(&timer->linkNode);
37  timer->startDelayTicks = delayTicks;
38  timer->durationTicks = durationTicks;
39  timer->timerFunc = timerFunc;
40  timer->arg = arg;
41  timer->config = config;
42 
43  // 如果初始启动延时为0,则使用周期值
44  if (delayTicks == 0) {
45  timer->delayTicks = durationTicks;
46  } else {
47  timer->delayTicks = timer->startDelayTicks;
48  }
49  timer->state = tTimerCreated;
50 }
51 
56 void tTimerStart (tTimer *timer) {
57  switch (timer->state) {
58  case tTimerCreated:
59  case tTimerStopped:
60  timer->delayTicks = timer->startDelayTicks ? timer->startDelayTicks : timer->durationTicks;
61  timer->state = tTimerStarted;
62 
63  // 根据定时器类型加入相应的定时器列表
64  if (timer->config & TIMER_CONFIG_TYPE_HARD) {
65  // 硬定时器,在时钟节拍中断中处理,所以使用critical来防护
66  uint32_t status = tTaskEnterCritical();
67 
68  // 加入硬定时器列表
69  tListAddLast(&tTimerHardList, &timer->linkNode);
70 
71  tTaskExitCritical(status);
72  } else {
73  // 软定时器,先获取信号量。以处理此时定时器任务此时同时在访问软定时器列表导致的冲突问题
74  tSemWait(&tTimerProtectSem, 0);
75  tListAddLast(&tTimerSoftList, &timer->linkNode);
76  tSemNotify(&tTimerProtectSem);
77  }
78  break;
79  default:
80  break;
81  }
82 }
83 
88 void tTimerStop (tTimer *timer) {
89  switch (timer->state) {
90  case tTimerStarted:
91  case tTimerRunning:
92  // 如果已经启动,判断定时器类型,然后从相应的延时列表中移除
93  if (timer->config & TIMER_CONFIG_TYPE_HARD) {
94  // 硬定时器,在时钟节拍中断中处理,所以使用critical来防护
95  uint32_t status = tTaskEnterCritical();
96 
97  // 从硬定时器列表中移除
98  tListRemove(&tTimerHardList, &timer->linkNode);
99 
100  tTaskExitCritical(status);
101  } else {
102  // 软定时器,先获取信号量。以处理此时定时器任务此时同时在访问软定时器列表导致的冲突问题
103  tSemWait(&tTimerProtectSem, 0);
104  tListRemove(&tTimerSoftList, &timer->linkNode);
105  tSemNotify(&tTimerProtectSem);
106  }
107  timer->state = tTimerStopped;
108  break;
109  default:
110  break;
111  }
112 }
113 
118 void tTimerDestroy (tTimer *timer) {
119  tTimerStop(timer);
120  timer->state = tTimerDestroyed;
121 }
122 
128 void tTimerGetInfo (tTimer *timer, tTimerInfo *info) {
129  uint32_t status = tTaskEnterCritical();
130 
131  info->startDelayTicks = timer->startDelayTicks;
132  info->durationTicks = timer->durationTicks;
133  info->timerFunc = timer->timerFunc;
134  info->arg = timer->arg;
135  info->config = timer->config;
136  info->state = timer->state;
137 
138  tTaskExitCritical(status);
139 }
140 
144 static void tTimerCallFuncList (tList *timerList) {
145  tNode *node;
146 
147  // 检查所有任务的delayTicks数,如果不0的话,减1。
148  for (node = timerList->headNode.nextNode; node != &(timerList->headNode); node = node->nextNode) {
149  tTimer *timer = tNodeParent(node, tTimer, linkNode);
150 
151  // 如果延时已到,则调用定时器处理函数
152  if ((timer->delayTicks == 0) || (--timer->delayTicks == 0)) {
153  // 切换为正在运行状态
154  timer->state = tTimerRunning;
155 
156  // 调用定时器处理函数
157  timer->timerFunc(timer->arg);
158 
159  // 切换为已经启动状态
160  timer->state = tTimerStarted;
161 
162  if (timer->durationTicks > 0) {
163  // 如果是周期性的,则重复延时计数值
164  timer->delayTicks = timer->durationTicks;
165  } else {
166  // 否则,是一次性计数器,中止定时器
167  tListRemove(timerList, &timer->linkNode);
168  timer->state = tTimerStopped;
169  }
170  }
171  }
172 }
173 
177 static tTask tTimeTask;
178 static tTaskStack tTimerTaskStack[TINYOS_TIMERTASK_STACK_SIZE];
179 
180 static void tTimerSoftTask (void *param) {
181  for (;;) {
182  // 等待系统节拍发送的中断事件信号
183  tSemWait(&tTimerTickSem, 0);
184 
185  // 获取软定时器列表的访问权限
186  tSemWait(&tTimerProtectSem, 0);
187 
188  // 处理软定时器列表
189  tTimerCallFuncList(&tTimerSoftList);
190 
191  // 释放定时器列表访问权限
192  tSemNotify(&tTimerProtectSem);
193  }
194 }
195 
200  uint32_t status = tTaskEnterCritical();
201 
202  // 处理硬定时器列表
203  tTimerCallFuncList(&tTimerHardList);
204 
205  tTaskExitCritical(status);
206 
207  // 通知软定时器节拍变化
208  tSemNotify(&tTimerTickSem);
209 }
210 
214 void tTimerModuleInit (void) {
215  tListInit(&tTimerHardList);
216  tListInit(&tTimerSoftList);
217  tSemInit(&tTimerProtectSem, 1, 1);
218  tSemInit(&tTimerTickSem, 0, 0);
219 }
220 
224 void tTimerInitTask (void) {
225 
226 #if TINYOS_TIMERTASK_PRIO >= (TINYOS_PRO_COUNT - 1)
227 #error "The proprity of timer task must be greater then (TINYOS_PRO_COUNT - 1)"
228 #endif
229  tTaskInit(&tTimeTask, tTimerSoftTask, (void *) 0,
230  TINYOS_TIMERTASK_PRIO, tTimerTaskStack, sizeof(tTimerTaskStack));
231 
232 }
233 
234 #endif
235 
void * arg
Definition: tTimer.h:41
uint32_t startDelayTicks
Definition: tTimer.h:36
uint32_t config
Definition: tTimer.h:43
Definition: tSem.h:24
void tTimerDestroy(tTimer *timer)
Definition: tTimer.c:118
uint32_t startDelayTicks
Definition: tTimer.h:49
Definition: tTask.h:31
uint32_t durationTicks
Definition: tTimer.h:37
uint32_t tTaskStack
Definition: tTask.h:25
void * arg
Definition: tTimer.h:53
void tListRemove(tList *list, tNode *node)
Definition: tList.c:200
void tSemInit(tSem *sem, uint32_t startCount, uint32_t maxCount)
Definition: tSem.c:24
tTaskCritical_t tTaskEnterCritical(void)
Definition: tSwitch.c:36
#define tNodeParent(node, parent, name)
Definition: tLib.h:48
void tTimerStart(tTimer *timer)
Definition: tTimer.c:56
void tNodeInit(tNode *node)
Definition: tList.c:19
uint32_t tSemWait(tSem *sem, uint32_t waitTicks)
Definition: tSem.c:41
void(* timerFunc)(void *arg)
Definition: tTimer.h:52
Definition: tLib.h:35
tTimerState state
Definition: tTimer.h:56
void tTaskInit(tTask *task, void(*entry)(void *), void *param, uint32_t prio, uint32_t *stack, uint32_t size)
Definition: tTask.c:23
void tListAddLast(tList *list, tNode *node)
Definition: tList.c:148
void tTimerModuleInit(void)
Definition: tTimer.c:214
uint32_t config
Definition: tTimer.h:55
tNode linkNode
Definition: tTimer.h:34
uint32_t durationTicks
Definition: tTimer.h:50
void tTimerInitTask(void)
Definition: tTimer.c:224
void tTimerModuleTickNotify(void)
Definition: tTimer.c:199
void tTaskExitCritical(tTaskCritical_t status)
Definition: tSwitch.c:47
tTimerState state
Definition: tTimer.h:44
uint32_t delayTicks
Definition: tTimer.h:38
void tTimerStop(tTimer *timer)
Definition: tTimer.c:88
void tTimerInit(tTimer *timer, uint32_t delayTicks, uint32_t durationTicks, void(*timerFunc)(void *arg), void *arg, uint32_t config)
Definition: tTimer.c:34
void tSemNotify(tSem *sem)
Definition: tSem.c:88
struct _tNode * nextNode
Definition: tLib.h:37
tNode headNode
Definition: tLib.h:44
void(* timerFunc)(void *arg)
Definition: tTimer.h:40
void tTimerGetInfo(tTimer *timer, tTimerInfo *info)
Definition: tTimer.c:128
Definition: tTimer.h:33
#define TIMER_CONFIG_TYPE_HARD
Definition: tTimer.h:60
Definition: tLib.h:43
void tListInit(tList *list)
Definition: tList.c:32