Linux内核定时器

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口和中断号不同。如果有疑问或建议,欢迎指出。

你可能感兴趣的:(linux)