linux之定时器

1 问题的引入—》软件消抖

在实际的应用中,如按键按下的的现象应该是:
松开(高电平)-》按下(低电平)-》松开(高电平)
但是由于实际按键的硬件原因导致的机械抖动,会导致产生多次中断,上报多次按键值。可是实际上,我们只要一次按键值。
在这里插入图片描述
为了避免这种情况的发生
1)、我们可以使用中断来处理,死等:
在按键中断程序中,可以循环判断几十亳秒,发现电平稳定之后再上报。但是这样违背了中断的原则之一:将尽可能的快。
2)、使用定时器
在这里插入图片描述
每次产生中断,在中断执行函数中,我们做的不是读按键值,而是修改定时器的超时时间:

eg: mod_timer(&timer, 10ms);

如果10ms内,再次发生了中断,就认为是抖动,再次修改定时器的超时时间。如果10ms内,无按键中断发生,就认为是已经稳定了。此时,才读取按键值。

2、定时器相关函数

a、void init_timer(struct timer_list *timer)
init_timer 函数负责初始化 timer_list 类型结构体(定时器的抽象)
b、void add_timer(struct timer_list *timer)
向 Linux 内核注册定时器,使用 add_timer 函数向内核注册定时器以后,
定时器就会开始运行
c、int del_timer(struct timer_list * timer)
删除一个定时器
d、int mod_timer(struct timer_list *timer, unsigned long expires)
注:expires基于jiffies来设置的。
mod_timer 函数用于修改定时值。
注:
它等同于:

del_timer(timer); 
timer->expires = expires; 
add_timer(timer);

更加高效

示例:

struct timer_list timer; /* 定义定时器 */
/* 定时器回调函数 */
 void function(unsigned long arg)
{
    
    
/* 定时器处理代码*/
/* 如果需要定时器周期性运行的话就使用 mod_timer
* 函数重新设置超时值并且启动定时器。 */
mod_timer(&dev->timertest, jiffies + msecs_to_jiffies(2000));
}
/* 初始化函数 */
void init(void)
{
    
    
 init_timer(&timer); /* 初始化定时器 */
 timer.function = function; /* 设置定时处理函数 */
 timer.expires=jffies + msecs_to_jiffies(2000);/* 超时时间 2 秒 */
 timer.data = (unsigned long)&dev; /* 将设备结构体作为参数 */
 add_timer(&timer); /* 启动定时器 */
}
 /* 退出函数 */
 void exit(void)
 {
    
    
del_timer(&timer); /* 删除定时器 */
}

3、定时器的时间说明

重要的知识点:
1)、节拍率/系统滴答
就像人类的心跳一样,eg:节拍率=100;表示1s发生100次。可理解成,内核1s会产生100次滴答中断,系统心跳是1s100次。
2)、jiffies
这是一个全局变量,每产生一次中断,这个数值就会+1.
定时器的时间就是基于jiffies的。
注:

int mod_timer(struct timer_list *timer, unsigned long expires)

其中,expires基于jiffies来设置的。
我们修改超时时间时,一般使用这 2 种方法:
① 在 add_timer 之前,直接修改:

timer.expires = jiffies + xxx; // xxx 表示多少个滴答后超时,也就是 xxx*10ms
timer.expires = jiffies + 2*HZ; // HZ 等于 CONFIG_HZ, 2*HZ 就相当于 2 秒

② 在 add_timer 之后,使用 mod_timer 修改:

mod_timer(&timer, jiffies + xxx); // xxx 表示多少个滴答后超时,也就是 xxx*10ms
mod_timer(&timer, jiffies + 2*HZ); // HZ 等于 CONFIG_HZ, 2*HZ 就相当于 2 秒

猜你喜欢

转载自blog.csdn.net/cainiaofu/article/details/115726942
今日推荐