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);

  • 相关阅读:
    软件体系架构复习要点
    Operating System on Raspberry Pi 3b
    2019-2020 ICPC North-Western Russia Regional Contest
    2019 ICPC ShenYang Regional Online Contest
    2019 ICPC XuZhou Regional Online Contest
    2019 ICPC NanChang Regional Online Contest
    2019 ICPC NanJing Regional Online Contest
    Codeforces Edu Round 72 (Rated for Div. 2)
    Codeforces Round #583 (Div.1+Div.2)
    AtCoder Beginning Contest 139
  • 原文地址:https://www.cnblogs.com/3ddan/p/3263694.html
Copyright © 2011-2022 走看看