色yeye在线视频观看_亚洲人亚洲精品成人网站_一级毛片免费播放_91精品一区二区中文字幕_一区二区三区日本视频_成人性生交大免费看

當前位置: > 華清遠見教育科技集團 > 嵌入式學習 > 講師博文 > FS_2416按鍵驅動實現
FS_2416按鍵驅動實現
時間:2016-12-12作者:華清遠見

一.驅動源代碼實現:

#include < linux/module.h>
        #include < linux/kernel.h>
        #include < linux/init.h>
        #include < linux/fs.h>
        #include < linux/cdev.h>
        #include < linux/ interrupt.h>
        #include < linux/irq.h>
        #include < linux/types.h>
        #include < linux/errno.h>
        #include < linux/mm.h>
        #include < linux/sched.h>
        #include < linux/slab.h>
        #include < linux/poll.h>
        #include < asm/io.h>
        #include < asm/uaccess.h>
        #include < asm/system.h>
        #include < mach/regs-gpio.h>
        #include < mach/irqs.h>
        #define GPGCON 0x56000060
        static volatile unsigned int *gpgcon;
        #define GPGDAT 0x56000064
        static volatile unsigned int *gpgdat;
        #define GPGUDP 0x56000068
        static volatile unsigned int *gpgudp;

MODULE_LICENSE("Dual BSD/GPL");
        MODULE_AUTHOR("farsight");

static int irq_major = 251;
        static int irq_minor = 0;
        static struct cdev irq_cdev;
        static int key;
        struct fasync_struct *async_queue;
        static int irq_open(struct inode *inode, struct file *filp)
        {
                return 0;
 nbsp;       }
        static int irq_release(struct inode *inode, struct file *filp)
        {
                return 0;
        }

static ssize_t irq_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos)
        {
                if(copy_to_user(buf, (char *)&key, count))
                return -ENOMEM;
                return count;
        }

static int irq_fasync(int fd, struct file *filp, int mode)
        {
                return fasync_helper(fd, filp, mode, &async_queue);
        }

static struct file_operations fs2416_ops = {
                .owner = THIS_MODULE,
                .open = irq_open,
                .release = irq_release,
                .read = irq_read,
                .fasync = irq_fasync,
        };

static int irq_setup_cdev(struct cdev *cdev, struct file_operations *fops)
        {
                int result;
                dev_t devno = MKDEV(irq_major, irq_minor);
                cdev_init(cdev, fops);
                cdev->owner = THIS_MODULE;
    &nbsnbsp;           result = cdev_add(cdev, devno, 1);
                if(result)
                {                         printk("irq: cdev add faiirq\n");
                        return result;
                }
                return 0;
        }

static irqreturn_t irqhandler(int irqno, void *dev_id)
        {
        printk("irq: interrupt %d\n", irqno);
        switch(irqno)
                {
                case IRQ_EINT(10):
                //printk("eint 10\n");
                key = 2;
                break;
                case IRQ_EINT(11):
                //printk("eint 11\n");
                key = 4;
                break;
        case IRQ_EINT(12):
                //printk("eint 12\n");
                key = 3;
                break;
        case IRQ_EINT(13):
      &nbnbsp;         //printk("eint 13\n");
                key = 5;
                break;
                }
        if (async_queue)
                kill_fasync(&async_queue, SIGIO, POLL_IN);
                return IRQ_HANDLED;
        }

static int __init fs2416_init(void)
        {
        int result;
        dev_t devno = MKDEV(irq_major, irq_minor);
        result = register_chrdev_region(devno, 1, "fs2416");
        if(result)
                {
                        printk("irq: unable to get major %d\n", irq_major);
                        return result;
                }
        result = irq_setup_cdev(&irq_cdev, &fs2416_ops);
        if(result)
                goto err_add_cdev;
        gpgcon = ioremap(GPGCON, 0x04);
        gpgdat = ioremap(GPGDAT, 0x04);
        gpgudp = ioremap(GPGUDP, 0x04);
        // interrupts mode:
                //gpg2 k2
        *gpgcon= (*gpgcon &(~(0x3<<4))) | (0x2 << 4);
                //gpg3 k4
        *gpgcon= (*gpgcon &(~(0x3<<6))) | (0x2 << 6);
                //gpg4 k3
        *gpgcon= (*gpgcon &(~(0x3<<8))) | (0x2 << 8);
                //gpg5 k5
        *gpgcon= (*gpgcon &(~(0x3<<10))) | (0x2 << 10);
        *gpgudp= (*gpgudp &(~(0x3<<4))) | (0x2 << 4);
        *gpgudp= (*gpgudp &(~(0x3<<6))) | (0x2 << 6);
        *gpgudp= (*gpgudp &(~(0x3<<8))) | (0x2 << 8);
        *gpgudp= (*gpgudp &(~(0x3<<10))) | (0x2 << 10);
        result = request_irq(IRQ_EINT(10), irqhandler, IRQF_DISABLED|IRQF_TRIGGER_FALLING, "EINT 10", NULL);
        //printk("req 10 result : %d\n",result);
        if(result)
                goto err1;
        result = request_irq(IRQ_EINT(11), irqhandler, IRQF_DISABLED|IRQF_TRIGGER_FALLING, "EINT 11", NULL);
        //printk("req 11 result : %d\n",result);
        if(result)
                goto err2;
        result = request_irq(IRQ_EINT(12), irqhandler, IRQF_DISABLED|IRQF_TRIGGER_FALLING, "EINT 12", NULL);
        //printk("req 12 result : %d\n",result);
        if(result)
                goto err3;
        result = request_irq(IRQ_EINT(13), irqhandler, IRQF_DISABLED|IRQF_TRIGGER_FALLING, "EINT 13", NULL);
        //printk("req 13 result : %d\n",result);
        if(result)
                goto err4;
        printk("irq: driver installirq, with major %d!\n", irq_major);
        return 0;
      &nbnbsp; err4:
                free_irq(IRQ_EINT(13), NULL);
        err3:
                free_irq(IRQ_EINT(12), NULL);
        err2:
                free_irq(IRQ_EINT(11), NULL);
        err1:
                cdev_del(&irq_cdev);
        err_add_cdev:
                unregister_chrdev_region(devno, 1);
                return result;
        }

static void __exit fs2416_exit(void)
        {
                dev_t devno = MKDEV(irq_major, irq_minor);
                cdev_del(&irq_cdev);
                unregister_chrdev_region(devno, 1);
                free_irq(IRQ_EINT(10), NULL);
                free_irq(IRQ_EINT(11), NULL);
                free_irq(IRQ_EINT(12), NULL);
                free_irq(IRQ_EINT(13), NULL);
                printk("irq: driver uninstalirq!\n");
        }

module_init(fs2416_init);
        module_exit(fs2416_exit);

二.測試程序:

#include < sys/types.h>
        #include < sys/stat.h>
        #include < stdio.h>
        #include < fcntl.h>
  nbsp;      #include < signal.h>
        #include < unistd.h>
        int    fd, oflags;

void input_handler(int signum)
        {
                int key;
                read(fd, (char *)&key, sizeof(key));
                printf("get key data = %d\n", key);
        }
        int main()
        {
                fd = open("/dev/irq", O_RDWR, S_IRUSR | S_IWUSR);
                if(fd < 0)
                        {
                                perror("open");
                                exit(1);
                        }
                int key=-1;
                signal(SIGIO, input_handler);
                fcntl(fd, F_SETOWN, getpid());
                oflags = fcntl(fd, F_GETFL);
                fcntl(fd, F_SETFL, oflags | FASYNC);
                while(1)
                        {
  &nbnbsp;                             sleep(1);
                        }
        }

三.硬件設備:

四.測試

將按鍵的驅動代碼編譯后,插入模塊。

中斷注冊申請完成。

創建設備節點。

運行測試程序,按下按鍵,可以看到中斷產生并且獲得鍵值。

發表評論
評論列表(網友評論僅供網友表達個人看法,并不表明本站同意其觀點或證實其描述)
前台专线:010-82525158 企业培训洽谈专线:010-82525379 院校合作洽谈专线:010-82525379 Copyright © 2004-2018 北京华清远见科技集团有限公司 版权所有 ,京ICP备16055225号,京公海网安备11010802025203号
主站蜘蛛池模板: 成人av一区二区三区在线观看 | 免费A级毛片无码蜜芽欣赏网 | 欧洲一卡2卡三卡4卡乱码毛1 | 精品无码国产一区二区三区AV | 最近2019中文字幕第二页 | 人人妻人人做人人爽夜欢视频 | 午夜欧美日韩精品久久久久久 | 美女光胸无遮挡18禁止观看 | 日韩爱爱| 日日摸天天碰中文字幕你懂的 | 亚洲gay片在线gv网站 | 日韩人妻无码一区二区三区里沙 | 亚洲国产精品尤物yw在线 | 欧美99久久无码一区人妻A片 | 日本高清免费情在线视频免费下个 | 日日夜夜精彩视频 | 国外免费WINDOWS | 亚洲国产亚综合在线区 | 中文字日产幕码三区的做法大全 | 爱爱免费网 | 亚洲精品美女久久7777777 | 麻豆小视频 | 97男人的天堂 | 天堂中文资源库官网 | 日本一道综合一本88在线 | 亚洲精品无人一区二区 | 中文乱码人妻系列一区二区 | 欧美经典一区二区 | 国产精品无码专区在线观看不卡 | 无码一区二区三区免费 | 又硬又水多又坚少妇18P | 视频在线精品 | 无码熟妇人妻AV | 欧洲美女与动zooz | 午夜三级A三级三点窝 | 欧美一区二区黄色片 | 欧美成人精品高清视频在线观看 | 中文字幕AV伊人AV无码AV狼人 | 各种虐奶头的视频无码 | 午夜福利理论片在线观看播放 | 国产午夜亚洲精品理论片不卡 |