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*********************************************************************************************************/

来源:https://www.icode9.com/content-4-796851.html

(0)

相关推荐