Linux使用struct timer_list来描述一个定时器。
重要成员:
expires:定时时长
*function:超时执行函数名
使用流程:
1、定义定时器变量
/*定义定时器变量结构体*/ struct timer_list key_timer;
2、初始化定时器
a、函数init_timer(timer)
参数:timer:要初始化的定时器的变量名
b、设置超时函数
/*初始化定时器*/ init_timer(&key_timer); key_timer.function = key_timer_func;
3、注册定时器
void add_timer(struct timer_list *timer)
参数:timer:要注册定时器变量的地址
/*注册定时器*/ add_timer(&key_timer);
4、启动定时器
int mod_timer(struct timer_list *timer, unsigned long expires)
参数:
timer:要注册定时器变量的地址
expires:延时时长
/*启动定时器*/ mod_timer(&key_timer,jiffies + (HZ/10));
jiffies:全局变量,当前时间
HZ是一秒的时间。
当计时达到后,会执行成员function指定的函数,这里是key_timer_func
这里将定时器应用到键盘中断驱动程序中,用来延时起到消抖的作用
key.h:
#include <linux/module.h> #include <linux/init.h> #include <linux/fs.h> #include <linux/miscdevice.h> #include <linux/interrupt.h> #include <linux/io.h> #define GPGCON 0x56000060 #define GPGDAT 0x56000064 unsigned int *gpio_config,*gpio_data;
/*定义工作项结构体*/ struct work_struct *work1; /*定义定时器变量结构体*/ struct timer_list key_timer;
驱动程序:
#include "key.h" /******************** 函数名:work1_func 参数:无 返回值:无 函数功能:实现工作项 结构体中的func成员 ********************/ void work1_func() { /*启动定时器*/ mod_timer(&key_timer,jiffies + (HZ/10)); } /************************ 函数名:que_init 参数:无 返回值:无 函数功能:创建一个工作项 *************************/ int que_init() { /*创建工作*/ work1 = kmalloc(sizeof(struct work_struct),GFP_KERNEL); INIT_WORK(work1, work1_func); } /************************ 函数名:key_int 参数:无 返回值:0 函数功能:按键中断处理函数 *************************/ irqreturn_t key_int(int irq, void *dev_id) { /*1、检测设备是否产生中断*/ /*2、清除中断产生标志*/ /*3、提交下半部分工作*/ schedule_work(work1); return 0; } /************************ 函数名:key_hw_init 参数:无 返回值:无 函数功能:初始化与按键相关 的寄存器 *************************/ void key_hw_init() { unsigned int data; gpio_config = ioremap(GPGCON,4); gpio_data = ioremap(GPGDAT,4); data = readw(gpio_config); data &= ((3)|(3<<6)|(3<<10)|(3<<12)|(3<<14)|(3<<22));//~(0b11); data |= (2|(2<<6)|(2<<10)|(2<<12)|(2<<14)|(2<<22));//0b10; writew(data,gpio_config); } /************************ 函数名:key_timer_func 参数:无 返回值:无 函数功能:定时器超时处理函 数,达到规定时间执行此函数 *************************/ void key_timer_func() { unsigned int key_val,i; for(i = 0;i < 15;i++) { if((i == 0)||(i == 3)||(i == 5)||(i == 6)||(i == 7)||(i == 11)) { key_val = readw(gpio_data) & (1 << i); if(key_val == 0) printk("press key%d down\n",i); } } } int key_open(struct inode *node, struct file *filp) { return 0; } /* 函数映射关系表*/ struct file_operations key_fops = { .open = key_open, //.unlocked_ioctl = key_ioctl, }; /*字符设备描述结构*/ struct miscdevice key_miscdev = { .minor = 200, .name = "key", .fops = &key_fops, }; static int key_init() { /*注册设备*/ misc_register(&key_miscdev); /*硬件初始化*/ key_hw_init(); /*注册中断*/ request_irq(IRQ_EINT8,key_int,IRQF_TRIGGER_FALLING ,"key", 0); request_irq(IRQ_EINT11,key_int,IRQF_TRIGGER_FALLING ,"key", 0); request_irq(IRQ_EINT13,key_int,IRQF_TRIGGER_FALLING ,"key", 0); request_irq(IRQ_EINT14,key_int,IRQF_TRIGGER_FALLING ,"key", 0); request_irq(IRQ_EINT15,key_int,IRQF_TRIGGER_FALLING ,"key", 0); request_irq(IRQ_EINT19,key_int,IRQF_TRIGGER_FALLING ,"key", 0); /*工作队列初始化*/ que_init(); /*初始化定时器*/ init_timer(&key_timer); key_timer.function = key_timer_func; /*注册定时器*/ add_timer(&key_timer); printk("key.ko is ready\n"); return 0; } static void key_exit() { /*注销设备*/ misc_deregister(&key_miscdev); /*注销中断*/ free_irq(IRQ_EINT8, 0); } MODULE_LICENSE("GPL"); module_init(key_init); module_exit(key_exit);
此代码适用mini2440开发板,不同型号开发板IO口和中断号不同。如果有疑问或建议,欢迎指出。