SylixOS里的时间【10】--- 软件定时器接口及用法
概念
很多系统都提供软件定时器,通过软件定时器可以异步的延时或周期性执行某一函数,使用延时函数也实现同样的功能,但延时函数是同步方式,等待时需要阻塞当前线程,如果要实现多个周期性动作需要创建多个线程。
无论是驱动还是应用程序,经常会用到周期查询任务,最简单高效的的实现方法就是创建一个周期性的软件定时器,在其回调函数中执行响应操作。
接口
SylixOS同样提供软件定时器,可以单次或循环模式执行,且提供普通和高速两种定时器类型。普通软件定时器在线程上下文中判定时间和执行回调,高速软件定时器则是在系统心跳中断中判定时间和执行回调。
/********************************************************************************************************* TIMER 创建选项*********************************************************************************************************/#define LW_OPTION_ITIMER 0x00000001 /* 普通 */#define LW_OPTION_HTIMER 0x00000000 /* 高速 *//********************************************************************************************************* TIMER 设置选项*********************************************************************************************************/#define LW_OPTION_AUTO_RESTART 0x00000001 /* 定时器自动重载 */#define LW_OPTION_MANUAL_RESTART 0x00000000 /* 定时器手动重载 */LW_API VOID API_TimerHTicks(VOID);/* 高速定时器周期服务函数,需要在心跳中断中调用 */LW_API ULONG API_TimerHGetFrequency(VOID); /* 获得高速定时器频率 *//* 建立一个定时器 */LW_API LW_OBJECT_HANDLE API_TimerCreate(CPCHAR pcName,//定时器名字 ULONG ulOption,//定时器类型 LW_OBJECT_ID *pulId); // 返回对象句柄 LW_API ULONG API_TimerDelete(LW_OBJECT_HANDLE *pulId); /* 删除一个定时器 *//* 启动一个定时器 */ LW_API ULONG API_TimerStart(LW_OBJECT_HANDLE ulId,//对象句柄 ULONG ulCounter,//定时时间,以节拍为单位 ULONG ulOption,//选项,单次还是周期性 PTIMER_CALLBACK_ROUTINE cbTimerRoutine,//回调函数 PVOID pvArg);//回调函数参数 /* 启动一个定时器 */LW_API ULONG API_TimerStartEx(LW_OBJECT_HANDLE ulId,//对象句柄 ULONG ulInitCounter,//计数初始值 ULONG ulCounter,//重复计数初始值 ULONG ulOption,//操作选项 PTIMER_CALLBACK_ROUTINE cbTimerRoutine,//回调函数 PVOID pvArg);//回调函数参数 LW_API ULONG API_TimerCancel(LW_OBJECT_HANDLE ulId); /* 停止一个定时器 */LW_API ULONG API_TimerReset(LW_OBJECT_HANDLE ulId); /* 复位一个定时器 *//* 获得一个定时器状态 */ LW_API ULONG API_TimerStatus(LW_OBJECT_HANDLE ulId,//对象句柄 BOOL *pbTimerRunning,//定时器是否在运行 ULONG *pulOption,//定时器选项 ULONG *pulCounter,//定时器当前计数值 ULONG *pulInterval);//间隔时间, 为 0 表示单次运行/* 获得一个定时器状态扩展接口 */ LW_API ULONG API_TimerStatusEx(LW_OBJECT_HANDLE ulId,//对象句柄 BOOL *pbTimerRunning,//定时器是否在运行 ULONG *pulOption,//定时器选项 ULONG *pulCounter,//定时器当前计数值 ULONG *pulInterval,//间隔时间, 为 0 表示单次运行 clockid_t *pclockid);//POSIX 时间类型 LW_API ULONG API_TimerGetName(LW_OBJECT_HANDLE ulId, PCHAR pcName); /* 获得定时器名字 */
用法举例
/************************************************************************************************************* 中国软件开源组织**** 嵌入式实时操作系统**** SylixOS(TM) LW : long wing**** Copyright All Rights Reserved****--------------文件信息--------------------------------------------------------------------------------**** 文 件 名: timerExample.c**** 创 建 人: Hou.JinYu (侯进宇)**** 文件创建日期: 2017 年 12 月 20 日**** 描 述: 软件定时器例程*********************************************************************************************************/#include <stdio.h>#include <stdint.h>#include <stdlib.h>#include <string.h>#include <sys/ioccom.h>#include <pthread.h>/*********************************************************************************************************** 函数名称: timerCb** 功能描述: 软件定时器回调函数** 输 入: pvArg 回调参数** 输 出: 无*********************************************************************************************************/VOID timerCb (PVOID pvArg){ int *pcount = pvArg; (*pcount) ; /* * 中断中不能调用printf函数 */ if (!API_InterContext()) { printf("timer callback, count = %d\n", *pcount); }}/*********************************************************************************************************** 函数名称: main** 功能描述: 程序入口** 输 入: argc 参数个数** argv 参数列表** 输 出: ERROR_CODE*********************************************************************************************************/int main (int argc, char **argv){ LW_OBJECT_HANDLE hTimer; volatile int count = 0; int err; int i; ULONG ulOption = LW_OPTION_ITIMER; ULONG ulCounter = API_TimeGetFrequency(); printf("timer example start\n"); /* * 根据命令参数判断是否为高速定时器,否则默认为普通定时器 */ if (argc == 2) { if (strcmp(argv[1], "h") == 0) { ulOption = LW_OPTION_HTIMER; ulCounter = API_TimerHGetFrequency(); } } /* * 创建软件定时器,指定为普通模式 */ hTimer = API_TimerCreate("timer", ulOption, LW_NULL); if (hTimer == 0) { printf("create timer failed\n"); return (PX_ERROR); } else { printf("create timer success\n"); } /* * 启动定时器,周期为1秒,循环模式,回调函数中对计数加加处理 */ err = API_TimerStart(hTimer, ulCounter, LW_OPTION_AUTO_RESTART, (PTIMER_CALLBACK_ROUTINE)timerCb, (PVOID)&count); if (err) { printf("start timer failed, err = %d\n", err); API_TimerDelete(&hTimer); return (PX_ERROR); } else { printf("start timer success\n"); } /* * 每半秒复位一次软件定时器,这样10次(5秒)内软件定时器应该得不到运行 */ printf("reset timer 10 times\n"); for (i = 0; i < 10; i ) { API_TimeSleep(API_TimeGetFrequency() / 2); API_TimerReset(hTimer); printf("reset timer. i = %d\n", i); } /* * 不再复位软件定时器,轮询count等于5时停止软件定时器 */ printf("wait count to 5\n"); while (1) { if (count > 5) { err = API_TimerCancel(hTimer); if (err) { printf("stop timer failed, err = %d\n", err); API_TimerDelete(&hTimer); return (PX_ERROR); } else { printf("stop timer success\n"); break; } } } /* * 软件定时器已停止,等待5秒,期间不应该有回调运行 */ printf("wait 5s\n"); for (i = 0; i < 10; i ) { API_TimeSleep(API_TimeGetFrequency() / 2); printf("wait timer. i = %d, count = %d\n", i, count); } /* * */ API_TimerDelete(&hTimer); printf("timer example finish\n"); return (0);}/********************************************************************************************************* END*********************************************************************************************************/


赞 (0)
