红联Linux门户
Linux帮助

Linux内核定时器的使用

发布时间:2016-09-26 15:46:16来源:linux网站作者:ELinux2607
内核定时器的结构体定义在include/linux/timer.h:
struct timer_list {  
/* 
* All fields that change during normal runtime grouped to the 
* same cacheline 
*/  
struct list_head entry;  
unsigned long expires;  
struct tvec_base *base; 
void (*function)(unsigned long);  
unsigned long data;
int slack;
#ifdef CONFIG_TIMER_STATS  
int start_pid;  
voidvoid *start_site;  
char start_comm[16];  
#endif  
#ifdef CONFIG_LOCKDEP  
struct lockdep_map lockdep_map;  
#endif  
};  
 
只需初始化定时器的超时时间expires,超时调用函数function,data成员会作为定时器超时函数的参数传递,驱动可以用data来存储自己的私有数据结构地址。下面是定时器应用的一个实例:
驱动的私有数据结构:
struct msg21xx_ts_data {  
struct input_dev *input;  
struct hrtimer timer;  
struct work_struct work;  
int irq;  
struct dentry *dir;  
charchar *ts_info;  
u8 addr;  
int fw_major;  
int fw_minor;  
#ifdef CONFIG_FB  
struct notifier_block fb_notif;  
#endif  
bool suspended;  
struct timer_list tp_timer;  
struct i2c_client *client;  
struct regulator *vdd;  
struct regulator *vcc_i2c;  
struct msg21xx_platform_data *pdata;  
struct workqueue_struct *msg21xx_wq;  
struct mutex msg21xx_mutex;  
};  
 
驱动的probe函数:
static int msg21xx_ts_probe(struct i2c_client *client,  
const struct i2c_device_id *id)  
{  
struct msg21xx_ts_data *data; 
data = kzalloc(sizeof(struct msg21xx_ts_data), GFP_KERNEL);  
if (!data) {  
dev_err(&client->dev, "%s: Alloc mem fail!", __func__);  
err = -ENOMEM;  
goto exit;  
}
init_timer(&data->tp_timer);  
data->tp_timer.function = tp_timer_function;  
data->tp_timer.data = (unsigned long)data;  
//setup_timer(&tp_timer, tp_timer_function, (unsigned long)data);  
add_timer(&data->tp_timer);  
mod_timer(&data->tp_timer, jiffies+HZ * 2);  
}
 
调用init_timer初始化定时器,然后设置定时器的超时调用函数,data成员被初始化为驱动的私有数据结构的地址,最后调用add_timer将定时器加入内核,调用mod_timer后,定时器会在2秒后超时,tp_timer_function函数被调用,data作为函数的参数被传入,在tp_timer_function函数中,就可以操作驱动的硬件。
void tp_timer_function(unsigned long datap)  
{  
struct msg21xx_ts_data *data = (struct msg21xx_ts_data *)datap;
gpio_set_value_cansleep(data->pdata->home_gpio, 0);  
gpio_set_value_cansleep(data->pdata->return_gpio, 0);  
gpio_set_value_cansleep(data->pdata->system_gpio, 0);  
}
 
下面的三条语句可以用一条代替:setup_timer(&tp_timer, tp_timer_function, (unsigned long)data);
init_timer(&data->tp_timer);  
data->tp_timer.function = tp_timer_function;  
data->tp_timer.data = (unsigned long)data;
 
本文永久更新地址:http://www.linuxdiyf.com/linux/24502.html