ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

SylixOS里的时间【10】--- 软件定时器接口及用法

2020-12-24 14:01:07  阅读:253  来源: 互联网

标签:10 SylixOS 定时器 ULONG timer --- LW API printf


概念

很多系统都提供软件定时器,通过软件定时器可以异步的延时或周期性执行某一函数,使用延时函数也实现同样的功能,但延时函数是同步方式,等待时需要阻塞当前线程,如果要实现多个周期性动作需要创建多个线程。

无论是驱动还是应用程序,经常会用到周期查询任务,最简单高效的的实现方法就是创建一个周期性的软件定时器,在其回调函数中执行响应操作。

接口

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

在这里插入图片描述

在这里插入图片描述

标签:10,SylixOS,定时器,ULONG,timer,---,LW,API,printf
来源: https://blog.csdn.net/ScilogyHunter/article/details/111623367

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有