zoukankan      html  css  js  c++  java
  • 简单键盘驱动

     #include<linux/timer.h>
    #include<linux/fs.h>
    #include<linux/delay.h>
    #include<linux/jiffies.h>
    #include<linux/kernel.h>
    #include<asm/string.h>
    #include<asm/io.h>
    #include<linux/module.h>
    #include<linux/types.h>
    #include<linux/mm.h>
    #include<linux/gpio.h>
    #include<linux/cdev.h>
    #include<linux/wait.h>
    #include<linux/sched.h>
    #include<linux/poll.h>
    #define MAX_KEYS 6
    #define KEY_TIMER_DELAY HZ/5
    MODULE_LICENSE("Dual BSD/GPL");
    static struct timer_list key_timer;
    static int key_major=0;
    static int key_values[MAX_KEYS]={0};
    static int ev_press=0;
    static struct timer_list key_timer;
    static struct cdev KeyDevs;
    wait_queue_head_t key_waitq;
    unsigned int key_desc[MAX_KEYS]={S3C2410_GPG(0),S3C2410_GPG(3),S3C2410_GPG(5),S3C2410_GPG(6),S3C2410_GPG(7),S3C2410_GPG(11)};
    void key_timer_handle(unsigned long data)

    {
            unsigned int *key_p=(unsigned int *)data;
            int down;
            static unsigned char pressed[MAX_KEYS]={0};
            int i;
            for(i=0;i<MAX_KEYS;i++,key_p++)
            {
                    s3c2410_gpio_setpin(*key_p,0<<0);
                    down=s3c2410_gpio_getpin(*key_p);
                    if(down==0)
                    {
                            pressed[i]++;
                    }
                    ndelay(10);
                    if(down==0&&pressed[i]==1)
                    {
                            printk("pressed ");
                            key_values[i]=i+1;
                            ev_press=1;
                            wake_up_interruptible(&key_waitq);
                    }
                    if(down==1&&pressed[i]==1)
                            pressed[i]=0;
            }
            key_timer.expires=jiffies+KEY_TIMER_DELAY;
            add_timer(&key_timer);
    }

    static int key_open(struct inode *inode,struct file *filp)
    {
             init_waitqueue_head(&key_waitq);
             init_timer(&key_timer);
             key_timer.function=&key_timer_handle;
             key_timer.data=(unsigned long)&key_desc;
             key_timer.expires=jiffies+KEY_TIMER_DELAY;
             add_timer(&key_timer);
             return 0;
    }
    static unsigned int key_poll(struct file *file,struct poll_table_struct *wait)
    {
            unsigned int mask=0;
            poll_wait(file,&key_waitq,wait);
            if(ev_press)
                    mask|=POLLIN|POLLRDNORM;
            return mask;
    }
    static ssize_t key_read(struct file *filp,char __user *buff,size_t count,loff_t *offp)
    {
            unsigned long err;
            if(!ev_press)
            {
                    if(filp->f_flags&O_NONBLOCK)
                            return -EAGAIN;
                    else
                            wait_event_interruptible(key_waitq,ev_press);
            }

            ev_press=0;
            err=copy_to_user(buff,key_values,min(sizeof(key_values),count));
            memset(key_values,0,sizeof(key_values));
            return err?-EFAULT:min(sizeof(key_values),count);
    }
    static int key_release(struct inode *node,struct file *file)
    {
            del_timer(&key_timer);
            return 0;
    }
    static void key_setup_cdev(struct cdev *dev,int minor,struct file_operations *fops)
    {
            int err,devno=MKDEV(key_major,minor);
            cdev_init(dev,fops);
            dev->owner=THIS_MODULE;
            dev->ops=fops;
            err=cdev_add(dev,devno,1);
            if(err)
                    printk(KERN_NOTICE "Error %d adding key %d",err,minor);
    }
    static struct file_operations key_ops={
    .owner=THIS_MODULE,
    .open=key_open,
    .release=key_release,
    .read=key_read,
    .poll=key_poll,

    };
    static int __init keys_init(void)
    {
            int result;
            dev_t dev=MKDEV(key_major,0);
            result=alloc_chrdev_region(&dev,0,1,"key");
            key_major=MAJOR(dev);
            if(result<0)
            {
                    printk(KERN_WARNING "key: unable to get major %d ",key_major);
                    return result;
            }
            if(key_major==0)
                    key_major=result;
            key_setup_cdev(&KeyDevs,0,&key_ops);
            printk("key device installed,with major %d ",key_major);
            return 0;
    }
    static void __exit key_exit(void)
    {
            cdev_del(&KeyDevs);
            unregister_chrdev_region(MKDEV(key_major,0),1);
            printk("key devices uninstalled ");
    }
    module_init(keys_init);

    module_exit(key_exit);

  • 相关阅读:
    [LeetCOde] Reverse Words in a String III
    [LeetCode] Keyboard Row
    [LeetCode] Number Complement
    [LeetCode] Array Partition I
    [LeetCode] Merge Two Binary Trees
    [LeetCode] Hamming Distance
    FFmpeg在ubuntu下安装及使用
    curl命令备注
    CentOS配置防火墙
    leetcode 21 Merge Two Sorted Lists
  • 原文地址:https://www.cnblogs.com/3ddan/p/3263694.html
Copyright © 2011-2022 走看看