内核定时器编程
软件意义上的定时器最终依赖硬件定时器来实现。内核在时钟中断发生后检测个各定时器是否到期,到期后的定时器处理函数将作为软中断在地半部执行。
在linux设备驱动编程中,可以利用linux内核中提供的一组函数和数据结构来完成定时出发工作或者完成某周期性的事务。
linux内核所提供的用于操作定时器的数据结构和函数如下:
struct tiemr_list {
struct list_head entry; //定时器列表
unsigned long expires;//定时器到期时间
void (*function)(unsigned long ); //定时器处理函数
unsigned long data;//作为参数被传入定时器 处理函数
struct timer_base_s *base;
}
当定时器期满后,其中的function成员将被执行 而 data 成员则是传入的参数,expires 是定时器到期的时间。
struct timer_list my_timer;
初始化定时器
void init_timer(struct timer_list * timer);
static inline void setup_timer(struct timer_list * timer ,void (*function)(unsigned llong),unsigned long data)
增加定时器
void add_timer(struct timer_list * timer)
删除定时器
void del_timer(struct timer_list * timer)
修改定时器的expire
int mod_timer(struct timer_list *timer,unsigned long expires)
上述函数,用于修改定时器的到期时间,在新的被传入的expires到来后才会执行定时器函数。
如:
static vod xxx_do-timer(unsigned long arg) arg 是timer_list->data 传入的值
{
struct xxx_device *dev=(struct xxx_device*)arg; 说明 在定时器初始化的时候 将data=(unsigned long )dev;
将dev结构地址 覆给了 data
。。。。
/*调度定时器在执行*/
dev->xxx_timer.expires=jiffies+delay;
add_timer(&dev->xxx_timer); 定时器时间到期后,如果不再次的 add_timer 那么 以后不再执行定时器中断
定时器中断不再起作用
}
结果显示如下:
应用程序代码如下:
驱动代码如下: