zoukankan      html  css  js  c++  java
  • 嵌入式Linux驱动学习之路(十一)按键驱动-中断机制

    轮询方式:

      和led驱动不同的是在配置IO引脚的时候,把LED的输出引脚换成输入,在read函数中向外发送io的状态。必须由应用程序不断的来查询当前IO口的状态来判断。

    中断方式:

    /* file name: key.c */
    #include <linux/sched.h> #include <linux/signal.h> #include <linux/spinlock.h> #include <linux/errno.h> #include <linux/random.h> #include <linux/poll.h> #include <linux/init.h> #include <linux/slab.h> #include <linux/module.h> #include <linux/wait.h> #include <linux/mutex.h> #include <linux/io.h> #include <asm/irq.h> #include <linux/irq.h> #include <linux/fs.h> #include <asm/arch/regs-gpio.h> #include <linux/interrupt.h> static struct class *key_class; //创建类 static struct class_device *key_class_devs; //创建类对应的设备 struct pin_desc{ unsigned int pin; unsigned int key_val; }; struct pin_desc pins_desc[4] = { {S3C2410_GPF0,0X01}, {S3C2410_GPF2,0X02}, {S3C2410_GPG3,0X03}, {S3C2410_GPG11,0X04}, }; unsigned char keyvals=0; static volatile int ev_press = 0; static DECLARE_WAIT_QUEUE_HEAD(button_waitq);     static irqreturn_t keys_irq(int irq, void *dev_id) { struct pin_desc *pindesc = (struct pin_desc *)dev_id; unsigned int pinval; pinval = s3c2410_gpio_getpin(pindesc->pin); if(pinval) { keyvals = pindesc->key_val|0x80; } else { keyvals = pindesc->key_val; } ev_press = 1; wake_up_interruptible(&button_waitq);    //休眠唤醒 return IRQ_HANDLED; } int key_open(struct inode *inode, struct file *fp) { request_irq( IRQ_EINT0, keys_irq, IRQT_BOTHEDGE, "key2", &pins_desc[0]);    //注册终端 linux会自己配置引脚 request_irq( IRQ_EINT2, keys_irq, IRQT_BOTHEDGE, "key3", &pins_desc[1]); request_irq( IRQ_EINT11, keys_irq, IRQT_BOTHEDGE, "key4", &pins_desc[2]); request_irq( IRQ_EINT19, keys_irq, IRQT_BOTHEDGE, "key5", &pins_desc[3]); return 0; } ssize_t key_read(struct file *fp, char __user *buff, size_t count, loff_t *offp){ if(count != 1) { return -EINVAL; } wait_event_interruptible(button_waitq,ev_press);  //休眠 copy_to_user(buff,&keyvals,1); ev_press = 0; return 0; } ssize_t key_write(struct file *fp, const char __user *buf, size_t count, loff_t *ppos){ } int key_close(struct inode *inode, struct file *file) { free_irq(IRQ_EINT0,&pins_desc[0]);    //释放中断源 free_irq(IRQ_EINT2,&pins_desc[1]); free_irq(IRQ_EINT11,&pins_desc[2]); free_irq(IRQ_EINT19,&pins_desc[3]); } struct file_operations led_fops={ .owner = THIS_MODULE, .open = key_open, .write = key_write, .read = key_read, .release = key_close, }; int major; static int key_init(void) { major = register_chrdev( 0,"key_drv", &led_fops ); key_class = class_create(THIS_MODULE,"key_class"); key_class_devs = class_device_create(key_class,NULL,MKDEV(major,0),NULL,"my_keys"); printk("key install Module "); return 0; } static void key_exit(void) { unregister_chrdev( major, "key_drv" ); class_device_unregister(key_class_devs); class_destroy(key_class); printk("key Module exit "); } module_init(key_init); module_exit(key_exit); MODULE_LICENSE("GPL");

    Makefile同led中的类似。

     应用程序:

    #include <stdio.h>
    #include <fcntl.h>
    
    
    int main()
    {
        int fd;
        unsigned char key_val;
        fd = open("/dev/my_keys",O_RDWR);
        if(fd<0)
        {
            printf("open failed
    ");
            return 0;
        }
        while(1)
        {
            read(fd, &key_val,1);
            printf("key:%x
    ",key_val);
        }
    }

    sd

  • 相关阅读:
    noi 2011 noi嘉年华 动态规划
    最小乘积生成树
    noi 2009 二叉查找树 动态规划
    noi 2010 超级钢琴 划分树
    noi 2011 阿狸的打字机 AC自动机
    noi 2009 变换序列 贪心
    poj 3659 Cell Phone Network 动态规划
    noi 2010 航空管制 贪心
    IDEA14下配置SVN
    在SpringMVC框架下建立Web项目时web.xml到底该写些什么呢?
  • 原文地址:https://www.cnblogs.com/ynxf/p/5997591.html
Copyright © 2011-2022 走看看