美文网首页
Qnx定时器的使用

Qnx定时器的使用

作者: jackniu_ae28 | 来源:发表于2019-11-26 11:17 被阅读0次
    1.创建定时器

    QNX定时器首先需要创建一个定时器对象,设置通知类型,一般包括信号、脉冲或线程创建,并创建通知结构(结构sigevent),设置定时类型 (相对与绝对,一次与周期),最后启动它。

       int timer_create( clockid_t clock_id,        struct sigevent * evp,          timer_t * timerid )
    

    第一个参数指向时钟源,分为三类,分别是CLOCK_REALTIME、CLOCK_SOFTTIME、CLOCK_MONOTONIC。
    CLOCK_REALTIM: 标准POSIX定义的时钟,如果它处于省电模式,基于这个时钟的定时器可以唤醒处理器。
    CLOCK_SOFTTIME:这个时钟只在处理器不处于节电模式时才激活。例如,使用CLOCK_SOFTTIME计时器休眠的应用程序不会在应用程序应该唤醒时唤醒处理器。这将允许处理器进入省电模式。
    CLOCK_MONOTONIC:这个时钟总是固定定时增加,无法调整
    第二个参数是指向结构sigevent数据结构的指针。这个数据结构用于通知内核,在“触发”时,计时器应该传递什么类型的事件。
    第三个参数指向timer_t对象的指针,函数在该对象中存储新定时器参数,如定时周期和启动时间。

    2 设置定时器

    创建了定时器之后,现在必须决定它是哪种类型的定时器。由timer_settime()的参数组合完成的,timer_settime()函数用于实际启动计时器:

          int timer_settime (timer_t timerid,       int flags,    struct itimerspec *value,      struct itimerspec *oldvalue);
    

    timerid 参数是从 timer_create() 函数调用中得到的值,创建一组计时器,然后在它们上分别调用timer_settime() 来设置和启动它们。
    flags参数就是指定绝对与相对标志。如果传递常量TIMER_ABSTIME,那么它就是绝对的,与预期的差不多。然后,在希望计时器关闭的时候传递实际的日期和时间。如果传递一个0,那么计时器将被视为相对于当前时间,那如何指定时间。以下是两个数据结构的关键部分():

       struct timespec {
                long    tv_sec,
                    tv_nsec;
        };
       struct itimerspec {
                struct timespec it_value,   //单次启动时间
                            it_interval;              //定时时间
       };
    

    it_value指定从现在开始计时器应该停止多长时间(在相对计时器的情况下),或者计时器应该停止的时间(在绝对计时器的情况下)。一旦计时器触发,it_interval值指定一个相对值来重新加载计时器,以便它能够再次触发。注意,为it_interval指定一个值为0,使它成为一个一次性定时器。创建一个定期计时器,将it_interval设置为reload值,并将it_value设置为零it_valueit_interval成员实际上都是类型
    struct timespec的结构,另一个POSIX对象。该结构允许指定秒分辨率。第一个成员,tv_sec,是秒数;第二个成员tv_nsec是当前秒内的纳秒数。

    例子1 创建一个单次运行时钟
    it_value.tv_sec = 5;
    it_value.tv_nsec = 500000000;
    it_interval.tv_sec = 0;
    it_interval.tv_nsec = 0;
    

    这将创建一个一次性计时器,在5.5秒内关闭。这是一个相对计时器,因为如果不是的话,那么这个时间早就过去了(比1970年1月1日晚5.5秒,GMT时间00:00)。
    这是另一个例子:

    it_value.tv_sec = 987654321;
    it_value.tv_nsec = 0;
    it_interval.tv_sec = 0;
    it_interval.tv_nsec = 0;
    

    这就产生了一个一次性计时器,在美国东部时间2001年4月19日星期四00:25:21开始计时。(有一大堆函数可读的日期和“自1970年1月1日以来的秒数”之间转换。查看time()asctime()ctime()mktime()strftime()等C库。对于这个例子,我们假设它是一个绝对计时器,因为如果它是相对的会等待大量的秒(987654321秒大约是31.3年)。
    最后一个例子:

    it_value.tv_sec = 1;
    it_value.tv_nsec = 0;
    it_interval.tv_sec = 0;
    it_interval.tv_nsec = 500000000;
    

    假设它是相对的,这个定时器将会在一秒内停止,然后每隔半秒再次停止。完全不需要重新加载的值看起来像一次性的值。

    例子2 定时器实例程序
    #include <stdlib.h>
    #include <stdio.h>
    #include <signal.h>
    #include <time.h>
    #include <sys/netmgr.h>
    #include <sys/neutrino.h>
     
    typedef union {
          struct _pulse   pulse;
            int dat;
          
    } my_message_t;
    
    my_message_t st;
    void testpidsigal()
    {
    
    
        st.dat++;
        printf("hello world\r\n");
    }
    #define MY_PULSE_CODE   _PULSE_CODE_MINAVAIL
    int main(int argc, char *argv[])
    {
     
       struct sigevent         event;
       struct itimerspec       itime;
       timer_t                 timer_id,timer_id1;
       int                     chid;
       int                     rcvid;
       my_message_t            msg;
       void (*testprt)();
     
       chid = ChannelCreate(0);/*创建通道*/
    
     /*  event.sigev_notify = SIGEV_PULSE;
       event.sigev_coid = ConnectAttach(ND_LOCAL_NODE, 0,
                                        chid,
                                        _NTO_SIDE_CHANNEL, 0);
       event.sigev_priority = getprio(0);
       event.sigev_code = 1;*/
    
       SIGEV_PULSE_INIT(&event, ConnectAttach(ND_LOCAL_NODE, 0,chid,_NTO_SIDE_CHANNEL, 0), getprio(0), 1, &testpidsigal);
    
       timer_create(CLOCK_REALTIME, &event, &timer_id);
     
     
        /*it_value 设定的是第一次初始化值*/
       itime.it_value.tv_sec =1;
       /* 500 million nsecs = .5 secs */
       itime.it_value.tv_nsec = 500000000;
       /*it_interval 设定的是每次间隔值*/
       itime.it_interval.tv_sec = 1;
       /* 500 million nsecs = .5 secs */
       itime.it_interval.tv_nsec = 500000000;
       timer_settime(timer_id, 0, &itime, NULL);
     
     
    
       for (;;) {
           rcvid = MsgReceive(chid, &msg, sizeof(msg), NULL);
           if (rcvid == 0) { /* 收到一个脉冲 */
                if (msg.pulse.code == 1) {
                    printf("we got a pulse from our timer %d\n",msg.pulse.code);//获取脉冲代码
                    testprt=msg.pulse.value.sival_ptr;
                    testprt();//这里打印Helloworld
                }
                    }
         }
    
    }
    

    相关文章

      网友评论

          本文标题:Qnx定时器的使用

          本文链接:https://www.haomeiwen.com/subject/wsrewctx.html