-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathVirtualTimerManager.c
356 lines (320 loc) · 8.34 KB
/
VirtualTimerManager.c
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
/*
VirtualTimerManager虚拟定时器管理器 Lib
使用SysTick中断作为软件定时器的基准中断,
定时器以毫秒为单位,最短时间间隔1ms。
需求:
1 用户注册的软件定时器实例应通过句柄的形式进行访问。
2 可注册多个软件定时器,定时器成功注册后返回一个句柄(允许用户不接受返回的句柄,使该定时器成为一个无法被引用的实例),若注册失败,返回错误代码。
3 每个定时器实例允许注册多个服务函数,优先调用更早注册的服务函数。
4 每个定时器实例的优先级要求可调节,当优先级一致时,优先调用更早注册的定时器的服务函数
5 可通过句柄来操作对应定时器实例的服务函数列表,对列表进行 增加、删除、查找、修改、清空 等操作。
增加:为定时器实例新建一个服务函数
删除:删除指定的服务函数
修改:修改指定的服务函数,将其指向另一个函数指针
清空:清空该定时器实例的全部服务函数
6 定时器实例可被使能和失能
*/
#include "VTM.h"
static void FuncList_Load(TimerNode_TypeDef *Node);
static void FuncList_Sort(void);
static void FuncList_NodeScan(void);
/*timerList虚拟定时器列表头节点*/
static TimerNode_TypeDef *timerListHead;
/*funcList定时器函数列表链表,每一个节点为一个函数列表*/
static TimerNode_TypeDef *funcList[FuncListSize];
/*fCont定时器函数timeout计数*/
static uint8_t fCont = 0;
bool VTMEnable = false;
/**
* @brief Enable 虚拟定时器管理器使能
* @param en :使能
* @retval 无
*/
void VTM_Enable(bool en)
{
VTMEnable = en;
}
/**
* @brief TimerManager_Init 定时器列表初始化
* @param 无
* @retval 无
*/
void VTM_TimerManagerInit()
{
timerListHead = (TimerNode_TypeDef *)MM_Alloc(sizeof(TimerNode_TypeDef));
timerListHead->func = NULL;
timerListHead->interval = 0;
timerListHead->isEnable = false;
timerListHead->priority = 0;
timerListHead->perpareTime = 0;
timerListHead->funcVal = 0;
timerListHead->Next = NULL;
}
/**
* @brief Timer_Register 定时器注册函数
* @param intv:时间间隔
* @param prio:优先级,越大优先级越高(0-255)
* @param en:使能
* @param *f:含有一个参数的函数指针
* @param val:参数指针
* @retval newNode:注册的节点的指针
*/
TimerNode_TypeDef * VTM_TimerRegister(uint16_t intv, uint8_t prio, bool en, VTM_Callback_t f, void *val)
{
TimerNode_TypeDef *root = timerListHead;
while(root->Next != NULL)
{
root = root->Next;
}
TimerNode_TypeDef *newNode = (TimerNode_TypeDef*)MM_Alloc(sizeof(TimerNode_TypeDef));
root->Next = newNode;
newNode->interval = intv;
newNode->priority = prio;
newNode->isEnable = en;
newNode->func = f;
newNode->funcVal = val;
newNode->funcListHead = NULL;
newNode->Next = NULL;
if(!f)
{
newNode->funcListHead = (FuncNode_TypeDef*)MM_Alloc(sizeof(FuncNode_TypeDef));
newNode->funcListHead->func = NULL;
newNode->funcListHead->funcVal = NULL;
newNode->funcListHead->Next = NULL;
}
if(newNode)
return newNode;
else
return 0;
}
/**
* @brief FuncList_Load 装填定时器函数列表
* @param tOp:timerOption定时器列表中定时器下标
* @retval 无
*/
static void FuncList_Load(TimerNode_TypeDef *Node)
{
funcList[fCont] = Node;
fCont++;
}
/**
* @brief FuncList_Sort 定时器函数列表排序,按优先级排序,冒泡排序法
* @param 无
* @retval 无
*/
static void FuncList_Sort()
{
uint8_t sTmp = 1;
for(int i = 0; i < fCont; i++)
{
for(int j = sTmp; j < fCont; j++)
{
if(funcList[i]->priority < funcList[j]->priority)
{
TimerNode_TypeDef *tmp = funcList[j];
funcList[j] = funcList[i];
funcList[i] = tmp;
}
}
sTmp++;
}
}
/**
* @brief FuncList_NodeScan 定时器函数列表节点扫描
* @param 无
* @retval 无
*/
static void FuncList_NodeScan()
{
FuncNode_TypeDef *tmp;
for(int i = 0; i < fCont; i++)
{
if(funcList[i]->isEnable)
{
if(funcList[i]->func != NULL)
(*funcList[i]->func)(funcList[i]->funcVal);
tmp = funcList[i]->funcListHead;
while(tmp)
{
if(tmp->isEnable && tmp->func != NULL)
(*tmp->func)(tmp->funcVal);
tmp = tmp->Next;
}
}
}
}
/**
* @brief OnceCycle_Finish 单次扫描完成
* @param 无
* @retval 无
*/
static void OneCycle_Finish()
{
memset(funcList, 0, FuncListSize);
fCont = 0;
}
/**
* @brief TimerScan 虚拟定时器扫描
* @param 无
* @retval 无
*/
void VTM_TimerScan()
{
TimerNode_TypeDef *Node = timerListHead;
while(Node)
{
Node->perpareTime = (Node->perpareTime + 1) % Node->interval;
if(!Node->perpareTime&&(Node->func||Node->funcListHead))
FuncList_Load(Node);
Node = Node->Next;
}
if(timerListHead->Next)
{
FuncList_Sort();
FuncList_NodeScan();
}
OneCycle_Finish();
}
/**
* @brief Timer_Enable 虚拟定时器使能设置
* @param Node :定时器节点
* @param en :使能
* @retval 设置结果 设置失败返回0,设置成功返回1
*/
uint8_t VTM_TimerEnable(TimerNode_TypeDef *Node, bool en)
{
if(Node)
{
Node->isEnable = en;
return 1;
}
return 0;
}
/**
* @brief Timer_SetPriority 虚拟定时器设置优先级
* @param Node :定时器节点
* @param prio :优先级
* @retval 设置结果 设置失败返回0,设置成功返回优先级
*/
uint8_t VTM_TimerSetPriority(TimerNode_TypeDef *Node, uint8_t prio)
{
if(Node)
Node->priority = prio;
else
return 0;
return Node->priority;
}
/**
* @brief Timer_SetInterval 虚拟定时器设置时间间隔
* @param Node :定时器节点
* @param intv :间隔时间
* @retval 设置结果 设置失败返回0,设置成功返回:间隔时间
*/
uint16_t VTM_TimerSetInterval(TimerNode_TypeDef *Node, uint16_t intv)
{
if(Node)
{
Node->interval = intv;
return Node->interval;
}
return 0;
}
/**
* @brief TimerNodeDel 删除虚拟定时器节点
* @param Node :定时器节点
* @retval 删除结果 删除失败返回0,删除成功返回1
*/
uint8_t VTM_TimerNodeDel(TimerNode_TypeDef *Node)
{
TimerNode_TypeDef *tmp = timerListHead;
if(tmp == 0 || Node == 0)
{
return 0;
}
if(tmp->Next == 0)
{
return 0;
}
TimerNode_TypeDef *tmpPrev;
while(tmp != Node)
{
tmpPrev = tmp;
tmp = tmp->Next;
}
if(Node->Next)
tmpPrev->Next = tmp->Next;
else
tmpPrev->Next = NULL;
return MM_Free(Node);
}
/**
* @brief VTM_FuncNodeRegister 定时器函数节点注册函数
* @param timerNode:目标定时器指针
* @param func:目标函数
* @param val:目标函数参数
* @retval newFuncNode:注册的节点的指针
*/
FuncNode_TypeDef *VTM_FuncNodeRegister(TimerNode_TypeDef *timerNode, VTM_Callback_t func, void *val)
{
FuncNode_TypeDef *root = timerNode->funcListHead;
while(root->Next != NULL)
{
root = root->Next;
}
FuncNode_TypeDef *newFuncNode = (FuncNode_TypeDef*)MM_Alloc(sizeof(FuncNode_TypeDef));
root->Next = newFuncNode;
newFuncNode->func = func;
newFuncNode->isEnable = true;
newFuncNode->funcVal = val;
newFuncNode->Next = NULL;
if(newFuncNode)
return newFuncNode;
else
return 0;
}
/**
* @brief FuncNodeEnable 函数节点使能
* @param timerNode :定时器节点
* @param FuncNode :函数节点
* @param en :使能状态
* @retval
*/
uint8_t VTM_FuncNodeEnable(FuncNode_TypeDef *FuncNode,bool en)
{
FuncNode_TypeDef *tmp = FuncNode;
if(tmp)
{
FuncNode->isEnable=en;
return 1;
}
return 0;
}
/**
* @brief FuncNodeDel 删除函数节点
* @param timerNode :定时器节点
* @param FuncNode :函数节点
* @retval 删除结果 删除失败返回0,删除成功返回1
*/
uint8_t VTM_FuncNodeDel(TimerNode_TypeDef *timerNode,FuncNode_TypeDef *FuncNode)
{
FuncNode_TypeDef *tmp = timerNode->funcListHead;
if(tmp == 0 || FuncNode == 0)
{
return 0;
}
if(tmp->Next == 0)
{
return 0;
}
FuncNode_TypeDef *tmpPrev;
while(tmp != FuncNode)
{
tmpPrev = tmp;
tmp = tmp->Next;
}
if(FuncNode->Next)
tmpPrev->Next = tmp->Next;
else
tmpPrev->Next = NULL;
return MM_Free(FuncNode);
}