色偷偷偷亚洲综合网另类,亚洲欧美另类在线观看,欧美午夜激情在线,久久久精品一区

當前位置: > 華清遠見教育科技集團 > 嵌入式學習 > 講師博文 > 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);
                        }
        }

三.硬件設備:

四.測試

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

中斷注冊申請完成。

創建設備節點。

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

發表評論
評論列表(網友評論僅供網友表達個人看法,并不表明本站同意其觀點或證實其描述)
色偷偷偷亚洲综合网另类,亚洲欧美另类在线观看,欧美午夜激情在线,久久久精品一区
主站蜘蛛池模板: 26uuu日韩精品一区二区| 国产精品成人久久久久| 精品国产成人av| 欧美猛少妇色xxxxx| 欧美性猛交xxxx| 国产91精品高潮白浆喷水| 日本高清不卡的在线| 国产精品人成电影| 亚洲第一黄色网| 亚洲视频第一页| 久久久999国产精品| 欧美日韩中文字幕在线| 国内精品久久久久伊人av| 国产97在线|日韩| 成人性生交xxxxx网站| 日韩av网址在线| 久久视频在线看| 97色在线播放视频| 91精品久久久久久久久青青| 亚洲第一色在线| 精品久久久av| 91成人性视频| 亚洲精品美女网站| 精品日韩美女的视频高清| 奇米影视亚洲狠狠色| 亚洲国产女人aaa毛片在线| 久久亚洲电影天堂| 清纯唯美亚洲综合| 日韩风俗一区 二区| 精品久久久久国产| 国产欧美一区二区| 中文字幕国产日韩| 欧美一区深夜视频| 亚洲人成电影网站色…| 精品久久久久久久中文字幕| 国产v综合v亚洲欧美久久| 亚洲高清免费观看高清完整版| 日韩一区二区av| 国产成人a亚洲精品| 中日韩午夜理伦电影免费| 国内精品久久久久久影视8|