• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2009-2022 Huawei Technologies Co., Ltd. All rights reserved.
3  *
4  * UniProton is licensed under Mulan PSL v2.
5  * You can use this software according to the terms and conditions of the Mulan PSL v2.
6  * You may obtain a copy of Mulan PSL v2 at:
7  *          http://license.coscl.org.cn/MulanPSL2
8  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
9  * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
10  * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
11  * See the Mulan PSL v2 for more details.
12  * Create: 2009-12-22
13  * Description: 定时器模块的对外头文件。
14  */
15 #ifndef PRT_TIMER_H
16 #define PRT_TIMER_H
17 
18 #include "prt_module.h"
19 #include "prt_errno.h"
20 
21 #ifdef __cplusplus
22 #if __cplusplus
23 extern "C" {
24 #endif
25 #endif
26 
27 /*
28  * 定时器状态枚举值
29  */
30 enum TimerFlag {
31     OS_TIMER_FREE = 1, /* 定时器空闲状态 */
32     OS_TIMER_CREATED = 2, /* 定时器没有运行 */
33     OS_TIMER_RUNNING = 4, /* 定时器正在运行 */
34     OS_TIMER_EXPIRED = 8 /* 定时器已经超时 */
35 };
36 
37 /*
38  * OS_timer错误码: 指针参数为空。
39  *
40  * 值: 0x02000d01
41  *
42  * 解决方案: 查看入参指针是否为空。
43  */
44 #define OS_ERRNO_TIMER_INPUT_PTR_NULL OS_ERRNO_BUILD_ERROR(OS_MID_TIMER, 0x01)
45 
46 /*
47  * OS_timer错误码: 定时器回调函数为空。
48  *
49  * 值: 0x02000d02
50  *
51  * 解决方案: 查看定时器回调函数是否为空。
52  */
53 #define OS_ERRNO_TIMER_PROC_FUNC_NULL OS_ERRNO_BUILD_ERROR(OS_MID_TIMER, 0x02)
54 
55 /*
56  * OS_timer错误码: 定时器句柄非法。
57  *
58  * 值: 0x02000d03
59  *
60  * 解决方案: 检查输入的定时器句柄是否正确。
61  */
62 #define OS_ERRNO_TIMER_HANDLE_INVALID OS_ERRNO_BUILD_ERROR(OS_MID_TIMER, 0x03)
63 
64 /*
65  * OS_timer错误码: 定时器周期参数非法。
66  *
67  * 值: 0x02000d04
68  *
69  * 解决方案: 查看定时器周期参数是否正确。
70  */
71 #define OS_ERRNO_TIMER_INTERVAL_INVALID OS_ERRNO_BUILD_ERROR(OS_MID_TIMER, 0x04)
72 
73 /*
74  * OS_timer错误码: 定时器工作模式参数非法。
75  *
76  * 值: 0x02000d05
77  *
78  * 解决方案: 查看定时器工作模式参数是否正确,参照工作模式配置枚举定义#enum TmrMode。
79  */
80 #define OS_ERRNO_TIMER_MODE_INVALID OS_ERRNO_BUILD_ERROR(OS_MID_TIMER, 0x05)
81 
82 /*
83  * OS_timer错误码: 定时器类型参数非法。
84  *
85  * 值: 0x02000d06
86  *
87  * 解决方案: 查看定时器类型参数是否正确,参照类型配置枚举定义#enum TimerType。
88  */
89 #define OS_ERRNO_TIMER_TYPE_INVALID OS_ERRNO_BUILD_ERROR(OS_MID_TIMER, 0x06)
90 
91 /*
92  * 软件定时器错误码:软件定时器组的最大定时器个数为零。
93  *
94  * 值: 0x02000d07
95  *
96  * 解决方案: 软件定时器组的最大定时器个数必须大于零。
97  */
98 #define OS_ERRNO_TIMER_NUM_ZERO OS_ERRNO_BUILD_ERROR(OS_MID_TIMER, 0x07)
99 
100 /*
101  * 软件定时器错误码:定时器未初始化或定时器组未创建。
102  *
103  * 值: 0x02000d08
104  *
105  * 解决方案: 只有在定时器初始化且定时器组已经创建的情况下才能使用定时器。
106  */
107 #define OS_ERRNO_TIMER_NOT_INIT_OR_GROUP_NOT_CREATED OS_ERRNO_BUILD_ERROR(OS_MID_TIMER, 0x08)
108 
109 /*
110  * 软件定时器错误码:定时器设置的定时周期转化为Tick数后不为整数。
111  *
112  * 值: 0x02000d09
113  *
114  * 解决方案: 请确保设置的定时周期是Tick的整数倍。
115  */
116 #define OS_ERRNO_SWTMR_INTERVAL_NOT_SUITED OS_ERRNO_BUILD_ERROR(OS_MID_TIMER, 0x09)
117 
118 /*
119  * 软件定时器错误码:达到最大支持定时器数目。
120  *
121  * 值: 0x02000d0a
122  *
123  * 解决方案: 达到最大支持定时器个数,不能再创建软件定时器。
124  */
125 #define OS_ERRNO_SWTMR_MAXSIZE OS_ERRNO_BUILD_ERROR(OS_MID_TIMER, 0x0a)
126 
127 /*
128  * 软件定时器错误码:定时器未创建。
129  *
130  * 值: 0x02000d0b
131  *
132  * 解决方案: 创建定时器后再使用。
133  */
134 #define OS_ERRNO_SWTMR_NOT_CREATED OS_ERRNO_BUILD_ERROR(OS_MID_TIMER, 0x0b)
135 
136 /*
137  * 软件定时器错误码:定时器已经处于未启动状态。
138  *
139  * 值: 0x02000d0c
140  *
141  * 解决方案: 定时器处于未启动状态,不能进行一些操作,请检查操作的合法性。
142  */
143 #define OS_ERRNO_SWTMR_UNSTART OS_ERRNO_BUILD_ERROR(OS_MID_TIMER, 0x0c)
144 
145 /*
146  * 软件定时器错误码:初始化内存不足。
147  *
148  * 值: 0x02000d0d
149  *
150  * 解决方案: 请适当增加系统默认FSC分区大小。
151  */
152 #define OS_ERRNO_SWTMR_NO_MEMORY OS_ERRNO_BUILD_ERROR(OS_MID_TIMER, 0x0d)
153 
154 /*
155  * 软件定时器错误码:TICK没有初始化。
156  *
157  * 值: 0x02000d0e
158  *
159  * 解决方案: 初始化Tick。
160  */
161 #define OS_ERRNO_TICK_NOT_INIT OS_ERRNO_BUILD_ERROR(OS_MID_TIMER, 0x0e)
162 
163 /*
164  * 软件定时器错误码:软件定时器定时周期过大,转换为Tick数超过0xFFFFFFFF。
165  *
166  * 值: 0x02000d0f
167  *
168  * 解决方案: 请确保传入的定时周期转化为Tick数后不大于0xFFFFFFFF。
169  */
170 #define OS_ERRNO_SWTMR_INTERVAL_OVERFLOW OS_ERRNO_BUILD_ERROR(OS_MID_TIMER, 0x0f)
171 
172 /*
173  * 软件定时器错误码:Tick定时器组已创建。
174  *
175  * 值: 0x02000d10
176  *
177  * 解决方案: 不能重复创建定时器组。
178  */
179 #define OS_ERRNO_TIMER_TICKGROUP_CREATED OS_ERRNO_BUILD_ERROR(OS_MID_TIMER, 0x10)
180 
181 /*
182  * 软件定时器错误码:创建软件定时器时传入定时器组组号非法。
183  *
184  * 值: 0x02000d11
185  *
186  * 解决方案: 确保传入的定时器组号是通过使用定时器组创建接口得到。
187  */
188 #define OS_ERRNO_TIMERGROUP_ID_INVALID OS_ERRNO_BUILD_ERROR(OS_MID_TIMER, 0x11)
189 
190 /*
191  * 软件定时器错误码:软件定时器组的最大定时器个数大于0xffff。
192  *
193  * 值: 0x02000d12
194  *
195  * 解决方案: 确保软件定时器组的最大定时器个数小于等于0xffff。
196  */
197 #define OS_ERRNO_TIMER_NUM_TOO_LARGE OS_ERRNO_BUILD_ERROR(OS_MID_TIMER, 0x12)
198 
199 /*
200  * 软件定时器错误码:返回指针参数为空。
201  *
202  * 值: 0x02000d13
203  *
204  * 解决方案: 输入有效的指针参数。
205  */
206 #define OS_ERRNO_SWTMR_RET_PTR_NULL OS_ERRNO_BUILD_ERROR(OS_MID_TIMER, 0x13)
207 
208 /*
209  * 定时器句柄定义
210  */
211 typedef U32 TimerHandle;
212 
213 /*
214  * 定时器组句柄定义
215  */
216 typedef U32 TimerGroupId;
217 
218 /*
219  * 定时器回调函数定义,带5个参数、返回值类型为void的函数指针类型,其中参数tmrHandle在核内硬件定时器、
220  * 全局硬件定时器和软件定时器中分别表示逻辑ID、物理ID和逻辑ID。
221  */
222 typedef void (*TmrProcFunc)(TimerHandle tmrHandle, U32 arg1, U32 arg2, U32 arg3, U32 arg4);
223 
224 /*
225  * 定时器组时钟源类型枚举定义
226  */
227 enum TimerGrpSrcType {
228     OS_TIMER_GRP_SRC_HARDWARE, /* 硬件私有时钟源 */
229     OS_TIMER_GRP_SRC_HARDWARE_SHARED, /* 硬件共享时钟源 */
230     OS_TIMER_GRP_SRC_EXTERN, /* 外部时钟源 */
231     OS_TIMER_GRP_SRC_TICK, /* TICK时钟源 */
232     OS_TIMER_GRP_SRC_INVALID
233 };
234 
235 /*
236  * 定时器组用户配置结构体
237  */
238 struct TmrGrpUserCfg {
239     /* 时钟源类型 */
240     enum TimerGrpSrcType tmrGrpSrcType;
241     /* 时间轮的刻度,即每刻度多少个us */
242     U32 perStep;
243     /* 最大定时器个数 */
244     U32 maxTimerNum;
245     /* 时间轮长度必须是2的N次方,此处配置N的大小 */
246     U32 wheelLen2Power;
247 };
248 
249 /*
250  * 定时器工作模式枚举定义
251  */
252 enum TmrMode {
253     OS_TIMER_LOOP, /* 定时器周期触发模式 */
254     OS_TIMER_ONCE, /* 定时器单次触发模式 */
255     OS_TIMER_INVALID_MODE
256 };
257 
258 /*
259  * 定时器类型枚举定义
260  */
261 enum TimerType {
262     OS_TIMER_HARDWARE, /* 硬件定时器(核内私有硬件定时器) */
263     OS_TIMER_SOFTWARE, /* 软件定时器(核内私有软件定时器) */
264     OS_TIMER_SOFTWARE_SHARED, /* 共享软件定时器,目前不支持 */
265     OS_TIMER_INVALID_TYPE
266 };
267 
268 /*
269  * 定时器创建参数结构体定义
270  */
271 struct TimerCreatePara {
272     /* 定时器创建模块ID,当前未使用,忽略 */
273     U32 moduleId;
274     /* 定时器类型 */
275     enum TimerType type;
276     /* 定时器工作模式 */
277     enum TmrMode mode;
278     /* 定时器周期(单次指定时器响应时长),软件定时器单位是ms,硬件定时器单位是us,高精度定时器单位是ns */
279     U32 interval;
280     /*
281      * 定时器组号,硬件定时器不使用,若创建软件定时器,定时器组ID由OS创建
282      */
283     U32 timerGroupId;
284     /* 定时器硬中断优先级 */
285     U16 hwiPrio;
286     U16 resv;
287     /*
288      * 定时器回调函数
289      */
290     TmrProcFunc callBackFunc;
291     /* 定时器用户参数1 */
292     U32 arg1;
293     /* 定时器用户参数2 */
294     U32 arg2;
295     /* 定时器用户参数3 */
296     U32 arg3;
297     /* 定时器用户参数4 */
298     U32 arg4;
299 };
300 
301 /*
302  * 软件定时器信息的结构体类型定义
303  */
304 struct SwTmrInfo {
305     /* 定时器状态,三种状态:Free,Created,Running,Expired */
306     U8 state;
307     /* 保留字段 */
308     U8 resved[3];
309     /* 定时器类型,两种类型:周期性、一次性 */
310     enum TmrMode mode;
311     /* 定时器超时间隔 */
312     U32 interval;
313     /* 定时器离超时剩余的ms数 */
314     U32 remainMs;
315     /* 定时器超时处理函数 */
316     TmrProcFunc handler;
317 };
318 
319 /*
320  * @brief 创建定时器。
321  *
322  * @par 描述
323  * 创建一个属性为createPara的定时器,返回定时器逻辑ID tmrHandle。
324  *
325  * @attention
326  * <ul>
327  * <li>如果用户打开Tick开关则可创建硬件定时器个数少一个。</li>
328  * <li>中断处理函数handler的第一个参数是创建的定时器的逻辑编号。</li>
329  * <li>定时器创建成功后并不立即开始计数,需显式调用#PRT_TimerStart或者#PRT_TimerRestart启动。</li>
330  * <li>对于周期定时模式的定时器,建议用户不要把定时间隔设置的过低,避免一直触发定时器的处理函数。</li>
331  * <li>struct TimerCreatePara参数里面的interval元素表示定时器周期,软件定时器单位是ms,
332  * 核内硬件定时器、全局硬件定时器单位是us,设置时间间隔的时候请注意适配,过大会出现溢出。</li>
333  * </ul>
334  *
335  * @param createPara [IN]  类型#struct TimerCreatePara *,定时器创建参数
336  * @param tmrHandle  [OUT] 类型#TimerHandle *,定时器句柄
337  *
338  * @retval #OS_OK  0x00000000,定时器创建成功。
339  * @retval #其它值,创建失败。
340  * @par 依赖
341  * <ul><li>prt_timer.h:该接口声明所在的头文件。</li></ul>
342  * @see PRT_TimerDelete
343  */
344 extern U32 PRT_TimerCreate(struct TimerCreatePara *createPara, TimerHandle *tmrHandle);
345 
346 /*
347  * @brief 删除定时器。
348  *
349  * @par 描述
350  * 释放一个定时器逻辑ID为tmrHandle的定时器资源。
351  *
352  * @attention
353  * <ul>
354  * <li>硬件定时器删除后将停止计数。</li>
355  * <li>删除处于超时状态下的软件定时器时,OS采用延时删除的方式。详细说明请见手册注意事项。</li>
356  * </ul>
357  *
358  * @param mid       [IN]  类型#U32,模块号,当前未使用,忽略
359  * @param tmrHandle [IN]  类型#TimerHandle,定时器句柄,通过PRT_TimerCreate接口获取
360  *
361  * @retval #OS_OK  0x00000000,定时器删除成功。
362  * @retval #其它值,删除失败。
363  * @par 依赖
364  * <ul><li>prt_timer.h:该接口声明所在的头文件。</li></ul>
365  * @see PRT_TimerCreate
366  */
367 extern U32 PRT_TimerDelete(U32 mid, TimerHandle tmrHandle);
368 
369 /*
370  * @brief 启动定时器。
371  *
372  * @par 描述
373  * 将定时器逻辑ID为tmrHandle的定时器由创建状态变成启动状态。
374  *
375  * @attention
376  * <ul>
377  * <li>创建后初次启动定时器时,从设置的值开始计数;如果重复启动或者启动后停止然后再启动,
378  * 从重复启动点或者停止点的计数值开始计数。</li>
379  * <li>对于全局硬件定时器,无论是第一次启动还是重复启动,下一次启动都从初始值开始计时。</li>
380  * <li>对于单次触发模式,触发一次后,可以调用启动接口再次启动该定时器,时间间隔为设置的时间间隔。</li>
381  * <li>启动处于超时状态下的软件定时器时,OS采用延时启动的方式。详细说明请见手册注意事项。</li>
382  * </ul>
383  *
384  * @param mid       [IN]  类型#U32,模块号,当前未使用,忽略
385  * @param tmrHandle [IN]  类型#TimerHandle,定时器句柄,通过#PRT_TimerCreate接口获取
386  *
387  * @retval #OS_OK  0x00000000,定时器启动成功。
388  * @retval #其它值,启动失败。
389  * @par 依赖
390  * <ul><li>prt_timer.h:该接口声明所在的头文件。</li></ul>
391  * @see PRT_TimerStop
392  */
393 extern U32 PRT_TimerStart(U32 mid, TimerHandle tmrHandle);
394 
395 /*
396  * @brief 停止定时器。
397  *
398  * @par 描述
399  * 停止定时器逻辑ID为tmrHandle的定时器计数,使定时器由计时状态变成创建状态。
400  *
401  * @attention
402  * <ul>
403  * <li>定时器停止后,下一次启动将重新从停止点的计数值开始计数。
404  * 但是对于全局硬件定时器,下一次启动从初始值开始计时。</li>
405  * <li>不能停止未启动的定时器。</li>
406  * <li>停止处于超时状态下的软件定时器时,OS采用延时停止的方式。详细说明请见手册注意事项。</li>
407  * <li>核内硬件定时器在停止过程中如果发生超时,则剩余时间为0,但不会响应定时器处理函数。</li>
408  * </ul>
409  *
410  * @param mid       [IN]  类型#U32,模块号,当前未使用,忽略
411  * @param tmrHandle [IN]  类型#TimerHandle,定时器句柄,通过#PRT_TimerCreate接口获取
412  *
413  * @retval #OS_OK  0x00000000,定时器停止成功。
414  * @retval #其它值,停止失败。
415  *
416  * @par 依赖
417  * <ul><li>prt_timer.h:该接口声明所在的头文件。</li></ul>
418  * @see PRT_TimerStart
419  */
420 extern U32 PRT_TimerStop(U32 mid, TimerHandle tmrHandle);
421 
422 /*
423  * @brief 重启定时器
424  *
425  * @par 描述
426  * 重启定时器逻辑ID为tmrHandle的定时器计数,对于停止过的定时器,相当于恢复到刚创建时的定时时长开始计时。
427  *
428  * @attention
429  * <ul>
430  * <li>重启处于超时状态下的软件定时器时,OS采用延时重启的方式。详细说明请见手册注意事项。</li>
431  * </ul>
432  *
433  * @param mid       [IN]  类型#U32,模块号,当前未使用,忽略
434  * @param tmrHandle [IN]  类型#TimerHandle,定时器句柄,通过#PRT_TimerCreate接口获取
435  *
436  * @retval #OS_OK  0x00000000,定时器重启成功。
437  * @retval #其它值,重启失败。
438  * @par 依赖
439  * <ul><li>prt_timer.h:该接口声明所在的头文件。</li></ul>
440  * @see PRT_TimerStop
441  */
442 extern U32 PRT_TimerRestart(U32 mid, TimerHandle tmrHandle);
443 
444 /*
445  * @brief 定时器剩余超时时间查询
446  *
447  * @par 描述
448  * 输入定时器句柄tmrHandle,获得对应定时器超时剩余时间expireTime。
449  *
450  * @attention
451  * <ul>
452  * <li>软件定时器单位毫秒,核内和全局硬件定时器单位微秒。</li>
453  * <li>由于OS内部软件定时器采用Tick作为计时单位,硬件定时器采用Cycle作为计时单位,
454  * 所以剩余时间转化成ms或us不一定是整数,当转化后的ms或us数不为整数时,返回的剩余时间是该ms或us数取整后+1;
455  * 例如转化后ms数为4.2,则最终用户得到的剩余时间是5ms。</li>
456  * </ul>
457  *
458  * @param mid        [IN]  类型#U32,模块号,当前未使用,忽略
459  * @param tmrHandle  [IN]  类型#TimerHandle,定时器句柄,通过#PRT_TimerCreate接口获取
460  * @param expireTime [OUT] 类型#U32 *,定时器的剩余的超时时间,共享和私有硬件定时器单位us,软件定时器单位ms
461  *
462  * @retval #OS_OK  0x00000000,定时器剩余超时时间查询成功。
463  * @retval #其它值,查询失败。
464  * @par 依赖
465  * <ul><li>prt_timer.h:该接口声明所在的头文件。</li></ul>
466  * @see PRT_TimerCreate
467  */
468 extern U32 PRT_TimerQuery(U32 mid, TimerHandle tmrHandle, U32 *expireTime);
469 
470 /*
471  * @brief 获取指定软件定时器的信息。
472  *
473  * @par 描述
474  * 根据指定的定时器ID,获取定时器ID为tmrHandle的定时器的信息info。
475  *
476  * @attention
477  * <ul>
478  * <li>由于OS内部采用Tick作为软件定时器的时钟源,所以剩余时间转化成ms不一定是整数,
479  * 当转化后的毫秒数不为整数时,返回的剩余时间是该毫秒数取整后+1;
480  * 例如转化后毫秒数为4.2,则最终用户得到的剩余时间是5ms。</li>
481  * </ul>
482  *
483  * @param tmrHandle [IN]  类型#TimerHandle,定时器句柄;
484  * @param info      [OUT] 类型#struct SwTmrInfo *,存放定时器信息结构体指针。
485  *
486  * @retval #SRE_OK  0x00000000,获取指定定时器的信息成功。
487  * @retval #其他值  信息获取失败。
488  * <ul><li>prt_timer.h:该接口声明所在的头文件。</li></ul>
489  * @see 无
490  */
491 extern U32 PRT_SwTmrInfoGet(TimerHandle tmrHandle, struct SwTmrInfo *info);
492 
493 #ifdef __cplusplus
494 #if __cplusplus
495 }
496 #endif
497 #endif
498 
499 #endif /* PRT_TIMER_H */
500