⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 button.c

📁 LINUX2.6下实现按键驱动
💻 C
字号:
#include <linux/config.h>#include <linux/module.h>#include <linux/version.h>#include <linux/kernel.h>#include <linux/init.h>#include <linux/fs.h>#include <asm/hardware.h>#include <asm/delay.h>#include <asm/uaccess.h>#include <asm-arm/arch-s3c2410/regs-gpio.h>#include  <asm/io.h>#include <asm-arm/arch-s3c2410/irqs.h>#include  <asm-arm/irq.h>#include <linux/interrupt.h>#include  <linux/wait.h>#define     BUTTON_IRQ1 IRQ_EINT5#define     BUTTON_IRQ2 IRQ_EINT6#define DEVICE_NAME "button"static int buttonMajor=0;#define     BUTTONMINOR 0#define     MAX_BUTTON_BUF 16    #define BUTTONSTATUS_1      5#define BUTTONSTATUS_2      6static unsigned char buttonRead(void);static int flag=0;typedef struct {    unsigned int buttonStatus;      //按键状态    unsigned char buf[MAX_BUTTON_BUF]; //按键缓冲区    unsigned int head,tail;         //按键缓冲区头和尾    wait_queue_head_t wq;           //等待队列} BUTTON_DEV;static BUTTON_DEV buttondev;#define BUF_HEAD    (buttondev.buf[buttondev.head])     //缓冲区头#define BUF_TAIL    (buttondev.buf[buttondev.tail])     //缓冲区尾#define INCBUF(x,mod)   ((++(x)) & ((mod)-1))       //移动缓冲区指针static void (*buttonEvent)(void);static void buttonEvent_dummy(void) {}static void buttonEvent_1(void){    if(buttondev.buttonStatus==BUTTONSTATUS_2) {    BUF_HEAD=BUTTONSTATUS_2;     }    else {    BUF_HEAD=BUTTONSTATUS_1;     }    buttondev.head=INCBUF(buttondev.head,MAX_BUTTON_BUF);    flag=1;    wake_up_interruptible(&(buttondev.wq));    printk("buttonEvent_1\n");} static irqreturn_t isr_button(int irq,void *dev_id,struct pt_regs *regs){       printk("Occured key board Inetrrupt,irq=%d\n",irq-44);    switch (irq) {    case BUTTON_IRQ1:buttondev.buttonStatus=BUTTONSTATUS_1;                break;    case BUTTON_IRQ2:buttondev.buttonStatus=BUTTONSTATUS_2;                break;    default:break;     }        buttonEvent();    return 0;}static int button_open(struct inode *inode,struct file *filp) {    int ret;    buttondev.head=buttondev.tail=0;    buttonEvent=buttonEvent_1;    ret=request_irq(BUTTON_IRQ1,isr_button,SA_INTERRUPT,DEVICE_NAME,NULL);  if(ret) {    printk("BUTTON_IRQ1: could not register interrupt ret=%d\n",ret);    return ret;     }    ret=request_irq(BUTTON_IRQ2,isr_button,SA_INTERRUPT,DEVICE_NAME,NULL);    if(ret) {    printk("BUTTON_IRQ2: could not register interrupt\n");    return ret;     }   return 0;}static int button_release(struct inode *inode,struct file *filp){    buttonEvent=buttonEvent_dummy;    free_irq(BUTTON_IRQ1,NULL);    free_irq(BUTTON_IRQ2,NULL);    return 0;}static ssize_t button_read(struct file *filp,char *buffer,size_t count,loff_t *ppos){    static unsigned char button_ret;retry:    printk("retry start\n");    if(buttondev.head!=buttondev.tail) {    button_ret=buttonRead();    copy_to_user(buffer,(char *)&button_ret,sizeof(unsigned char));    printk("the button_ret is 0x%x\n",button_ret);    return sizeof(unsigned char);     }    else {    if(filp->f_flags & O_NONBLOCK)        return -EAGAIN;    printk("sleep\n");    //interruptible_sleep_on(&(buttondev.wq));//为安全起见,最好不要调用该睡眠函数    wait_event_interruptible(buttondev.wq,flag);    flag=0;    printk("sleep_after\n");    if(signal_pending(current))         {        printk("rturn -ERESTARTSYS\n");        return -ERESTARTSYS;          }    goto retry;     }    return sizeof(unsigned char);}static struct file_operations button_fops= {    .owner =   THIS_MODULE,    .open   =   button_open,    .read   =   button_read,    .release    =   button_release,};static int __init s3c2410_button_init(void){    int ret;    set_irq_type(BUTTON_IRQ1,IRQT_FALLING);    set_irq_type(BUTTON_IRQ2,IRQT_FALLING);    buttonEvent=buttonEvent_dummy;        ret=register_chrdev(0,DEVICE_NAME,&button_fops);    if(ret<0) {    printk("button: can't get major number\n");    return ret;     }    buttonMajor=ret;#ifdef CONFIG_DEVFS_FSdevfs_mk_cdev(MKDEV(buttonMajor,BUTTONMINOR),S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP,DEVICE_NAME);#endif    //buttondev.head=buttondev.tail=0;    buttondev.buttonStatus=BUTTONSTATUS_1;    init_waitqueue_head(&(buttondev.wq));    printk(DEVICE_NAME" initialized\n");    return 0;}static unsigned char buttonRead(void){    unsigned char button_ret;    button_ret=BUF_TAIL;    buttondev.tail=INCBUF(buttondev.tail,MAX_BUTTON_BUF);    return button_ret;}    static void __exit s3c2410_button_eixt(void){#ifdef CONFIG_DEVFS_FS    devfs_remove(DEVICE_NAME);    #endif    unregister_chrdev(buttonMajor,DEVICE_NAME);    printk("\nbutton remove\n");}MODULE_LICENSE("GPL");MODULE_AUTHOR("Kision");MODULE_DESCRIPTION ("the first char device driver");module_init(s3c2410_button_init);module_exit(s3c2410_button_eixt);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -