在QNX中,定时器的使用和Linux驱动的大致类似,创建定时器,初始化定时器,设置定时函数等,最后启动定时器,
1.定时器编程
在QNX中使用定时器编程,步骤大致如下:
1.创建定时器对象
2.确定您所希望收到通知的方式,包括信号,脉冲,线程三种,并创建通知结构
3.确定使用的是何种计时器(相对计时器还是绝对计时器,单次计时器还是定期计时器)
4.最后启动这个定时器
1.1 创建定时器对象
在QNX中,使用timer_create()来创建定时器对象
#include <time.h>
#include <sys/siginfo.h>
int
timer_create (clockid_t clock_id,
struct sigevent *event,
timer_t *timerid);
- clock_id表示使用的定时器时钟源,共有三种
- CLOCK_REALTIM:标准POSIX定义的时钟,如果它处于省电模式,基于这个时钟的定时器可以唤醒处理器。
- CLOCK_SOFTTIME
- CLOCK_MONOTONIC:这个时钟总是固定定时增加,无法调整
一般使用第一种
struct sigevent *event
:这个参数表示定时器触发时使用什么应该传递什么事件,共有三种
- 信号,signal
- 脉冲:pluse
- 线程:thread
一般来说传递脉冲事件
3.timer_t *timerid
:该参数存储定时器参数,定时周期
1.2 启动定时器
创建完定时器之后,你需要通过timer_settime
使用何种类型的定时器,并且此函数也用来启动定时器
#include <time.h>
int
timer_settime (timer_t timerid,
int flags,
struct itimerspec *value,
struct itimerspec *oldvalue);
timer_t timerid
:从timer_create中定义的定时器对象flags
:表示定时器使用的是相对时间还是绝对时间,如果传递的是TIMER_ABSTIME
,那么他表示传递的是绝对时间,然后在定时器需要关闭的时候传递实际的日期和时间,这里不做讨论,一般使用相对时间,即相当于当前时间,需要将此参数设置为0。
下面两个数据结构用来指定时间
struct timespec {
long tv_sec,
tv_nsec;
};
struct itimerspec {
struct timespec it_value,
it_interval;
};
struct timespec it_value
:在相对时间下表示从第一次开始计时器多长时间内停止,在绝对时间下表示计时器停止的时间struct timespec it_interval
:表示这个计时器从上一次定时结束多长时间触发一次计时器,
其中tv_sec为秒,tv_nsec为纳秒
下面为两个例子:
it_value.tv_sec = 5;
it_value.tv_nsec = 500000000;
it_interval.tv_sec = 0;
it_interval.tv_nsec = 0;
表示创建一个一次性定时器,表示相对定时器时会在5.5s内关闭,表示绝对计时器时该计时器早已过去,比1970年1月1日晚5.5秒,GMT时间00:00
it_value.tv_sec = 1;
it_value.tv_nsec = 0;
it_interval.tv_sec = 0;
it_interval.tv_nsec = 500000000;
在表示相对时间下,这个定时器将在1s内停止,然后每一次隔0.5停止
1.3 销毁定时器
void timer_delete(timer_t timerid)
2.定时器编程例子
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <time.h>
#include <sys/netmgr.h>
#include <sys/neutrino.h>
void testpidsigal()
{
printf("hello world\r\n");
}
#define MY_PULSE_CODE _PULSE_CODE_MINAVAIL
int main(int argc, char *argv[])
{
struct sigevent event;
struct itimerspec itime;
struct _pulse pulse;
struct sched_param scheduling_params;
timer_t timer_id;
int chid;
int rcvid;
int prio;
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;
*/
/* Get our priority. */
if(SchedGet(0, 0, &scheduling_params) != -1)
{
prio = scheduling_params.sched_priority;
}
else
{
prio = 19;
}
//使用这句初始化event
SIGEV_PULSE_INIT(&event, ConnectAttach(ND_LOCAL_NODE, 0,chid,_NTO_SIDE_CHANNEL, 0), prio, MY_PULSE_CODE, &testpidsigal);
//1.创建定时器
timer_create(CLOCK_REALTIME, &event, &timer_id);
//2.启动定时器
/*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);
while(1)
{
rcvid = MsgReceive(chid, &pulse, sizeof(pulse), NULL);
if (rcvid == 0)
{ /* 收到一个脉冲 */
if (pulse.code == MY_PULSE_CODE)
{
printf("we got a pulse from our timer %d\n",pulse.code);//获取脉冲代码
testprt=pulse.value.sival_ptr;
testprt();//这里打印Helloworld
//或者直接调用
//testpidsigal()
}
}
}
timer_delete(timerid)
}