巧妙利用Linux下的setitimer定时器功能过滤掉过快的硬按键消息

setitimer函数功能介绍编辑

linux下如果对定时要求不太精确的话,使用alarm()signal()就行了,但是如果想要实现精度较高的定时功能的话,就要使用setitimer函数。

setitimer函数参数介绍编辑

int setitimer(int which, const structitimerval *value, struct itimerval *ovalue);

which为定时器类型,setitimer支持3种类型的定时器:

ITIMER_REAL: 以系统真实的时间来计算,它送出SIGALRM信号。

ITIMER_VIRTUAL: -以该进程在用户态下花费的时间来计算,它送出SIGVTALRM信号。

ITIMER_PROF: 以该进程在用户态下和内核态下所费的时间来计算,它送出SIGPROF信号。

setitimer()第一个参数which指定定时器类型(上面三种之一);第二个参数是结构itimerval的一个实例;第三个参数可不做处理。

setitimer()调用成功返回0,否则返回-1

struct itimerval {

struct timeval it_interval;

struct timeval it_value;

};

struct timeval {

long tv_sec;

long tv_usec;

};

it_interval指定间隔时间,it_value指定初始定时时间。如果只指定it_value,就是实现一次定时;如果同时指定 it_interval,则超时后,系统会重新初始化it_valueit_interval,实现重复定时;两者都清零,则会清除定时器。

tv_sec提供秒级精度,tv_usec提供微秒级精度,以值大的为先,注意1s = 1000000us

ovalue用来保存先前的值,常设为NULL

如果是以setitimer提供的定时器来休眠,只需阻塞等待定时器信号就可以。

实例:过滤POWER_OFF_ON,要求每间隔500ms启动一次定时器,定时器时间到后再执行定时器里面的动作(播放暂停)

 

1)定时器定义:

void set_power_off_on_send_timer(inttv_sec,int tv_usec);

/* 
*
开始链接POWER_OFF_ON发送的处理函数
*/
void power_off_on_send_timer_func(int sig)      /*
定时事件代码 */
{
//
定时器溢出,如果此时用户点击车机POWER_OFF_ON硬按键,则会向手机发送播放暂停消息
if(flag_power_off_on_timer > 0)
{
PhoneLinkPlayPause(TRUE);
}
else if(flag_power_off_on_timer < 0)
{
PhoneLinkPlayPause(FALSE);
}
else
{
//Nothing to do s
}
flag_power_off_on_timer = 0;
}

/* 
*
设置定时器时间,设置完后定时器会在指定时间触发power_off_on_send_timer_func 函数 
*/
void set_power_off_on_send_timer(int tv_sec,int tv_usec)
{

INFO("set_power_off_on_send_timer \n");
INFO("flag_power_off_on_timer:<%02x>\n",flag_power_off_on_timer);
struct itimerval power_off_on_send_timer_value;

//it_interval指定间隔时间,it_value指定初始定时时间。

power_off_on_send_timer_value.it_value.tv_usec= tv_usec;

power_off_on_send_timer_value.it_value.tv_sec= tv_sec;
power_off_on_send_timer_value.it_interval.tv_usec = tv_usec;
power_off_on_send_timer_value.it_interval.tv_sec = tv_sec;
signal(SIGALRM, power_off_on_send_timer_func);    /*
捕获定时信号 */
setitimer(ITIMER_REAL, &power_off_on_send_timer_value, NULL);/*
定时开始*/
}
2)应用该定时器.
//
发送POWER-OFF/ON硬按键定时器的标志位
extern int flag_power_off_on_timer;
int  PowerStatusHandle(unsigned charbStatus)

{
     printf("PowerStatusHandle(%d)\n", bStatus);
    //printf("flag_power_off_on_timer:<%02x>\n",flag_power_off_on_timer);
     unsigned char src = GetCurSource();
     static  unsigned char  starttimerFlag = FALSE;
   //printf("power status ==%d\n",bStatus);
    if(SWITCH_OFF== bStatus)//
关屏
{
switch(src)
{
case SOURCE_AUDIO_PLAYER:
MusicBtnPause();
break;
case SOURCE_VIDEO_PLAYER:{
VideoBtnPause();
}
break;
case SOURCE_IPOD:
IpodPlayCtrlPlayPause(IPODPAUSE);
break;
case SOURCE_SMARTPHONE:
//
为避免用户频繁的点击车机的POWER_ON_OFF按键,利用定时器过滤POWER_ON_OFF硬按键消息
if(starttimerFlag == FALSE)
{
starttimerFlag = TRUE;
set_power_off_on_send_timer(0,5*1000*100);
PhoneLinkPlayPause(FALSE);
}
else
{
flag_power_off_on_timer--;
}
break;
}
}
else if(SWITCH_ON== bStatus)//
开屏
{
switch(src)
{
case SOURCE_AUDIO_PLAYER:
//MusicBtnPlay();
SetStartPlayState(PLAY);
MusicResumePlay();
break;
case SOURCE_VIDEO_PLAYER:
if(GetCurMenuId()==MENU_VIDEO_PLAY)
{
if(STOP == GetPlayerStatus()){
SetStartPlayState(PLAY);
VideoResumePlay();
}
else
{
VideoBtnPlay();
}
}
break;
case SOURCE_IPOD:
IpodPlayCtrlPlayPause(IPODPLAY);
break;
case SOURCE_SMARTPHONE:
//
为避免用户频繁的点击车机的POWER_ON_OFF按键,利用定时器过滤POWER_ON_OFF硬按键消息
if(starttimerFlag == FALSE)
{
starttimerFlag = TRUE;
set_power_off_on_send_timer(0,5*1000*100);
PhoneLinkPlayPause(TRUE);
}
else
{
flag_power_off_on_timer++;
}

break;
}

//if(SOURCE_IPOD != src)
      ResetAboutTimer();
}
return 0;
}

 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
setitimer函数是Linux中实现高精度定时器系统调用。它用于设置一个定时器,在指定的时间间隔内周期性地触发一个定时信号。函数原型如下: ```c int setitimer(int which, const struct itimerval *new_value, struct itimerval *old_value); ``` 其中,which参数指定了定时器的类型。常用的取值有: - ITIMER_REAL:使用系统的真实时间来计算定时器间隔,与系统的墙钟相关。 - ITIMER_VIRTUAL:使用进程的虚拟时间来计算定时器间隔,即进程在用户态运行的时间。 - ITIMER_PROF:使用进程在用户态和内核态运行的总时间来计算定时器间隔。 new_value参数是一个itimerval结构体指针,用于指定定时器的间隔和初始启动时间。该结构体定义如下: ```c struct itimerval { struct timeval it_interval; // 定时器的间隔 struct timeval it_value; // 定时器的初始启动时间 }; ``` 其中,timeval结构体定义如下: ```c struct timeval { time_t tv_sec; // 秒数 suseconds_t tv_usec; // 微秒数 }; ``` old_value参数是一个itimerval结构体指针,用于保存之前的定时器设置。 在使用setitimer函数之前,需要通过signal函数注册一个信号处理函数,用于处理定时器触发的信号。一般常用的信号是SIGALRM。 使用setitimer函数可以实现一些需要高精度定时的场景,比如周期性地刷新屏幕、定时采集传感器数据等。定时器的间隔可通过设置it_interval参数来调整,定时器的初始启动时间可通过设置it_value参数来设置。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值