在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            新聞中心

            EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > ARM-LINUX按鍵中斷驅(qū)動程序

            ARM-LINUX按鍵中斷驅(qū)動程序

            作者: 時間:2016-11-11 來源:網(wǎng)絡 收藏

            驅(qū)動程序

            本文引用地址:http://www.biyoush.com/article/201611/316606.htm

            #include
            #include
            #include
            #include
            #include
            #include
            #include
            #include
            #include
            #include
            #include
            #include
            #includeinterrupt.h>
            #include
            #include
            #include


            #define DEV_NAME "qjz_buttons"http://DEV_NAME要與應用程序的open調(diào)用的NAME一樣
            static int buttons_major,buttons_minor=0;//定義設備號
            static struct cdev buttons_cdev;//定義設備結(jié)構(gòu)
            static struct class *buttons_class;
            static dev_t dev;

            struct button_irq_desc
            {
            int irq;
            int pin;
            int pin_setting;
            int number;
            char *name;
            };

            static struct button_irq_desc button_irqs[ ]=
            {
            {IRQ_EINT1,S3C2410_GPF1,S3C2410_GPF1_EINT1,0,"KEY1"},
            {IRQ_EINT4,S3C2410_GPF4,S3C2410_GPF4_EINT4,1,"KEY2"},
            {IRQ_EINT2,S3C2410_GPF2,S3C2410_GPF2_EINT2,2,"KEY3"},
            {IRQ_EINT0,S3C2410_GPF0,S3C2410_GPF0_EINT0,3,"KEY4"},
            };
            static volatile int key_values[]={0,0,0,0};
            static DECLARE_WAIT_QUEUE_HEAD(button_waitq);
            static volatile int ev_press = 0;

            static irqreturn_t buttons_interrupt(int irq,void *dev_id)
            {
            struct button_irq_desc *button_irqs=(struct button_irq_desc *)dev_id;
            int up = s3c2410_gpio_getpin(button_irqs->pin);
            if(!up)
            {
            key_values[button_irqs->number]=(button_irqs->number+1);
            }
            ev_press = 1;
            wake_up_interruptible(&button_waitq);
            return IRQ_RETVAL(IRQ_HANDLED);
            }

            static int buttons_open(struct inode *inode,struct file *filp)
            {
            int i,err;
            unsigned long irq_type;
            irq_type=ioread32(S3C2410_EXTINT0);//設置中斷類型為上升沿
            irq_type&=~(3<<1 | 3<<5 | 3<<9 | 3<<17 );
            irq_type|=(3<<1 | 3<<5 | 3<<9 | 3<<17 );
            iowrite32(irq_type,S3C2410_EXTINT0);
            for(i = 0;i < 4; i++)
            {
            s3c2410_gpio_cfgpin(button_irqs[i].pin,button_irqs[i].pin_setting);
            err = request_irq(button_irqs[i].irq, buttons_interrupt, NULL, button_irqs[i].name,(void*)&button_irqs[i]);
            if(err)//成功返回值0,失敗返回一個負的錯誤碼
            break;
            }
            if(err)//失敗就要釋放已經(jīng)注冊成功的中斷
            {
            i--;
            for(;i>=0;i--)
            {
            disable_irq(button_irqs[i].irq);
            free_irq(button_irqs[i].irq,(void*)&button_irqs[i]);
            }
            return -EBUSY;
            }
            return 0;
            }
            static int buttons_close(struct inode *inode,struct file *file)
            {
            int i;
            for(i=0;i<4;i++)
            {
            disable_irq(button_irqs[i].irq);
            free_irq(button_irqs[i].irq,(void*)&button_irqs[i]);
            }
            return 0;
            }

            static int buttons_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(button_waitq,ev_press);
            }
            ev_press = 0;
            err=copy_to_user(buff,(const void*)key_values,count);
            memset((void*)key_values,0,sizeof(key_values));
            return err?-EFAULT:4;
            }

            static unsigned int buttons_poll(struct file *filp,poll_table *wait)
            {
            unsigned int mask = 0;
            poll_wait(filp,&button_waitq,wait);
            if(ev_press)
            mask |=POLLIN|POLLRDNORM;
            return mask;
            }
            static struct file_operations buttons_fops =
            {
            .owner = THIS_MODULE,
            .open = buttons_open,
            .release = buttons_close,
            .read = buttons_read,
            .poll = buttons_poll,
            };


            static int __init buttons_init(void)
            {
            int result;
            if(buttons_major)
            {
            dev = MKDEV(buttons_major,buttons_minor);
            result = register_chrdev_region(dev,1,DEV_NAME);
            }
            else
            {
            result = alloc_chrdev_region(&dev,buttons_minor,1,DEV_NAME);
            buttons_major = MAJOR(dev);
            }
            if(result < 0)
            {
            printk(KERN_WARNING "buttons:cant get major %dn",buttons_major);
            return result;
            }
            else
            {
            printk(KERN_WARNING"registered oknbuttons_major = %dn",buttons_major);
            }
            /*led_setup_cdev(&leds_cdev,0);*/
            cdev_init(&buttons_cdev,&buttons_fops);
            buttons_cdev.owner = THIS_MODULE;
            buttons_cdev.ops = &buttons_fops;
            result = cdev_add(&buttons_cdev,dev,1);
            if(result < 0)
            {
            printk(KERN_WARNING"cdev_add failed!n");
            return result;
            }
            else
            {
            printk(KERN_WARNING"cdev_add is ok!!n");
            }
            buttons_class = class_create(THIS_MODULE,DEV_NAME);
            if(IS_ERR(buttons_class))
            {
            printk(KERN_ALERT"err:fail in buttons_class!n");
            return -1;
            }
            else
            {
            printk(KERN_WARNING"SUCCESS IN buttons_CLASS!n");
            }
            class_device_create(buttons_class,NULL,MKDEV(buttons_major,0),NULL,DEV_NAME);
            /*class_device_create(leds_class,NULL,dev,NULL,DEV_NAME);*/
            printk(KERN_WARNING"buttons Module initialed!n");
            return 0;
            }

            static void __exit buttons_exit(void)
            {
            int devno = MKDEV(buttons_major,buttons_minor);
            unregister_chrdev_region(devno,1);
            cdev_del(&buttons_cdev);
            class_device_destroy(buttons_class,devno);
            class_destroy(buttons_class);
            printk(KERN_WARNING"buttons module exit!n");
            }

            module_init(buttons_init);
            module_exit(buttons_exit);
            MODULE_LICENSE("Dual BSD/GPL");
            MODULE_DESCRIPTION("buttons device drver");
            MODULE_AUTHOR("xxx");

            應用程序

            #include
            #include
            #include
            #include
            #include
            #include
            #include
            #include
            #include
            #include

            int main(void)
            {
            int i;
            int buttons_fd;
            int key_value[4];
            buttons_fd=open("/dev/qjz_buttons",0);
            if(buttons_fd < 0)
            {
            perror("open buttons fail");
            exit(1);
            }
            for(;;)
            {
            fd_set reads;
            int ret;
            FD_ZERO(&reads);
            FD_SET(buttons_fd,&reads);
            ret = select(buttons_fd+1,&reads,NULL,NULL,NULL);
            if(ret<0)
            {
            perror("select");
            exit(1);
            }
            if(ret ==0)
            {
            printf("timeoutn");
            }
            else if(FD_ISSET(buttons_fd,&reads))
            {
            int ret=read(buttons_fd,key_value,sizeof(key_value));
            printf("%dn",ret);
            //if(ret !=sizeof(key_value))
            //{
            //if(errno !=EAGAIN)//教程中這里是有的,但是不知道為什么每次讀不出來按鍵值,屏蔽后,就可以讀出來!如圖!
            //perror("read buttonsn");
            //continue;
            //}
            //else
            //{
            for(i=0;i<4;i++)
            {
            if(key_value[i] !=0)
            printf("K%d pressd,key value=0x%dn",i+1,key_value[i]);}
            continue;
            // }
            }
            }
            close(buttons_fd);
            return 0;
            }

            奶奶的,怎么按一次有的時候會出現(xiàn)多次按下去的情況那?還是驅(qū)動的問題!感覺應該是中斷的抖動造成的!關(guān)于如何去抖,要看看!

            上面的應用程序用到了select,其實直接阻塞讀,就是直接read也可以得到按鍵值!我覺得select用在多輸入多輸出更有意義,也就是說用在多線程編程(例如聊天服務器里面的多點對多點,)。我不清楚用在這里是干什么?。菜聘M程的效率有關(guān)系)、直接阻塞讀,就是進程來讀,當沒有讀到數(shù)據(jù)就一直阻塞,一直到讀取到數(shù)據(jù)才返回!

            按照網(wǎng)上的資料說的是:Select在Socket編程中還是比較重要的,可是對于初學Socket的人來說都不太愛用Select寫程序,他們只是習慣寫諸如connect、accept、recv或recvfrom這樣的阻塞程序(所謂阻塞方式block,顧名思義,就是進程或是線程執(zhí)行到這些函數(shù)時必須等待某個事件的發(fā)生,如果事件沒有發(fā)生,進程或線程就被阻塞,函數(shù)不能立即返回)??墒鞘褂肧elect就可以完成非阻塞(所謂非阻塞方式non-block,就是進程或線程執(zhí)行此函數(shù)時不必非要等待事件的發(fā)生,一旦執(zhí)行肯定返回,以返回值的不同來反映函數(shù)的執(zhí)行情況,如果事件發(fā)生則與阻塞方式相同,若事件沒有發(fā)生則返回一個代碼來告知事件未發(fā)生,而進程或線程繼續(xù)執(zhí)行,所以效率較高)方式工作的程序,它能夠監(jiān)視我們需要監(jiān)視的文件描述符的變化情況——讀寫或是異常。

            我覺得吧:像本例中在前面用到for循環(huán),這樣就會照成select的效率低下!他也是一直循環(huán)的去檢查有沒有讀到數(shù)據(jù)。這豈不是跟阻塞讀差不多啦!

            阻塞read應用程序如下:

            #include
            #include
            #include
            #include
            #include
            #include
            #include
            #include
            #include

            int main(void)
            {
            int i;
            int buttons_fd;
            int key_value[4];
            buttons_fd=open("/dev/qjz_buttons",0);
            if(buttons_fd < 0)
            {
            perror("open buttons fail");
            exit(1);
            }
            for(;;)
            {
            read(buttons_fd,key_value,sizeof(key_value));

            for(i=0;i<4;i++)
            {
            if(key_value[i] !=0)
            printf("K%d pressd,key value=0x%dn",i+1,key_value[i]);}
            continue;

            }
            close(buttons_fd);
            return 0;
            }




            評論


            技術(shù)專區(qū)

            關(guān)閉