Button驱动

  1. #include <linux/module.h>  
  2. #include <linux/kernel.h>  
  3. #include <linux/fs.h>  
  4. #include <linux/init.h>  
  5. #include <linux/delay.h>  
  6. #include <linux/poll.h>  
  7. #include <linux/irq.h>  
  8. #include <asm/irq.h>  
  9. #include <linux/interrupt.h>  
  10. #include <asm/uaccess.h>  
  11. #include <mach/regs-gpio.h>  
  12. #include <mach/hardware.h>  
  13. #include <linux/platform_device.h>  
  14. #include <linux/cdev.h>  
  15. #include <linux/miscdevice.h>  
  16.   
  17. #include <linux/gpio.h>  
  18. #include <linux/sched.h>  
  19.   
  20. #define DEVICE_NAME     "buttons_liu"  
  21.   
  22.   
  23. //#define DEBUG   
  24. struct button_irq_desc {  
  25.     int irq;  
  26.     int pin;  
  27.     int pin_setting;  
  28.     int number;  
  29.     char *name;   
  30. };  
  31.   
  32. static struct button_irq_desc button_irqs [] = {  
  33.     {IRQ_EINT8 , S3C2410_GPG0 ,  S3C2410_GPG0_EINT8  , 0, "KEY0"},  
  34.     {IRQ_EINT11, S3C2410_GPG3 ,  S3C2410_GPG3_EINT11 , 1, "KEY1"},  
  35.     {IRQ_EINT13, S3C2410_GPG5 ,  S3C2410_GPG5_EINT13 , 2, "KEY2"},  
  36.     {IRQ_EINT14, S3C2410_GPG6 ,  S3C2410_GPG6_EINT14 , 3, "KEY3"},  
  37.     {IRQ_EINT15, S3C2410_GPG7 ,  S3C2410_GPG7_EINT15 , 4, "KEY4"},  
  38.     {IRQ_EINT19, S3C2410_GPG11,  S3C2410_GPG11_EINT19, 5, "KEY5"},  
  39. };  

  40. //static volatile char key_values [] = {‘0‘, ‘0‘, ‘0‘, ‘0‘, ‘0‘, ‘0‘};  
  41. static int key_values = 0;  
  42.   
  43. static DECLARE_WAIT_QUEUE_HEAD(button_waitq);  
  44.   
  45. static volatile int ev_press = 0;  
  46.   
  47.   
  48. static irqreturn_t buttons_interrupt(int irq, void *dev_id)  
  49. {  
  50.     struct button_irq_desc *button_irqs = (struct button_irq_desc *)dev_id;  
  51.     int down;  
  52.     // udelay(0);  
  53.       
  54.     /*上升沿触发,GPIO DAT 应该为非0 的数*/  
  55.     down = !s3c2410_gpio_getpin(button_irqs->pin);  //按下down = 1 = !0 //松开down = 0 = !1  
  56.     if (!down) {   
  57.     //printk("rising\n");  
  58.     key_values = button_irqs->number;  
  59.         ev_press = 1;                          //表示中断发生了  
  60.         wake_up_interruptible(&button_waitq);  
  61.     }  
  62.    else {  
  63.     //printk("falling\n");  
  64.     ev_press = 0;  
  65.     return 0;                        // irqrequest_t,可能返回两个特殊的值:IRQ_NONE和IRQ_HANDLED.  
  66.    }                                 // 当中断处理程序检测到一个中断时,但该中断对应的设备并不是在注册处理函数期间指定的产生源时,返回IRQ_NONE;  
  67.     return IRQ_RETVAL(IRQ_HANDLED);  // 当中断处理程序被正确调用,且确实是它所对应的设备产生了中断时,返回IRQ_HANDLED    
  68. }  
  69.   
  70.   
  71. static int s3c24xx_buttons_open(struct inode *inode, struct file *file)  
  72. {  
  73.     int i;  
  74.     int err = 0;  
  75.       
  76.     for (i = 0; i < sizeof(button_irqs)/sizeof(button_irqs[0]); i++) {  
  77.     if (button_irqs[i].irq < 0) {  
  78.         continue;  
  79.     }  
  80.   
  81.     /* 设置中断触发方式 IRQ_TYPE_EDGE_FALLING,IRQ_TYPE_EDGE_RISING,IRQ_TYPE_EDGE_BOTH ;我们这里设置为上升沿触发*/  
  82.         //err = request_irq(button_irqs[i].irq, buttons_interrupt, IRQ_TYPE_EDGE_BOTH,   
  83.         //                  button_irqs[i].name, (void *)&button_irqs[i]);  
  84.         err = request_irq(button_irqs[i].irq, buttons_interrupt, IRQ_TYPE_EDGE_RISING,   
  85.                           button_irqs[i].name, (void *)&button_irqs[i]);  
  86.         if (err)  
  87.             break;               //request_irq 返回0表示成功。  
  88.     }  
  89.   
  90.     if (err) {  
  91.         i--;  
  92.         for (; i >= 0; i--) {  
  93.         if (button_irqs[i].irq < 0) {  
  94.         continue;  
  95.         }  
  96.         disable_irq(button_irqs[i].irq);  
  97.             free_irq(button_irqs[i].irq, (void *)&button_irqs[i]);  
  98.         }  
  99.         return -EBUSY;  
  100.     }  
  101.   
  102.     ev_press = 0;  
  103.       
  104.     return 0;  
  105. }  
  106.   
  107.   
  108. static int s3c24xx_buttons_close(struct inode *inode, struct file *file)  
  109. {  
  110.     int i;  
  111.       
  112.     for (i = 0; i < sizeof(button_irqs)/sizeof(button_irqs[0]); i++) {  
  113.     if (button_irqs[i].irq < 0) {  
  114.         continue;  
  115.     }  
  116.     free_irq(button_irqs[i].irq, (void *)&button_irqs[i]);  
  117.     }  
  118.   
  119.     return 0;  
  120. }  
  121.   
  122.   
  123. static int s3c24xx_buttons_read(struct file *filp, char __user *buff, size_t count, loff_t *offp)  
  124. {  
  125.     unsigned long err;  
  126.     //int i=0;  
  127.     if (!ev_press) {  
  128.     if (filp->f_flags & O_NONBLOCK)  
  129.         return -EAGAIN;  
  130.     else  
  131.         wait_event_interruptible(button_waitq, ev_press);  
  132.     }  
  133.     if(count != sizeof key_values)  
  134.     return -EINVAL;  
  135.     ev_press = 0;  
  136.     err = copy_to_user(buff, &key_values, sizeof(key_values));  
  137.     return sizeof(key_values);  
  138. }  
  139.   
  140. static unsigned int s3c24xx_buttons_poll( struct file *file, struct poll_table_struct *wait)  
  141. {  
  142.     unsigned int mask = 0;  
  143.     poll_wait(file, &button_waitq, wait);  
  144.     if (ev_press)  
  145.         mask |= POLLIN | POLLRDNORM;  
  146.     return mask;  
  147. }  
  148.   
  149.   
  150. static struct file_operations dev_fops = {  
  151.     .owner   =   THIS_MODULE,  
  152.     .open    =   s3c24xx_buttons_open,  
  153.     .release =   s3c24xx_buttons_close,   
  154.     .read    =   s3c24xx_buttons_read,  
  155.     .poll    =   s3c24xx_buttons_poll,  
  156. };  
  157.   
  158. static struct miscdevice misc = {  
  159.     .minor = MISC_DYNAMIC_MINOR,  
  160.     .name = DEVICE_NAME,  
  161.     .fops = &dev_fops,  
  162. };  
  163.   
  164. static int __init dev_init(void)  
  165. {  
  166.     int ret;  
  167.   
  168.     ret = misc_register(&misc);  
  169. #ifdef DEBUG  
  170.     printk("debug test\n");//ykz  
  171. #endif  
  172.     printk (DEVICE_NAME"\tinitialized\n");  
  173.   
  174.     return ret;  
  175. }  
  176.   
  177. static void __exit dev_exit(void)  
  178. {  
  179.     misc_deregister(&misc);  
  180. }  
  181.   
  182. module_init(dev_init);  
  183. module_exit(dev_exit);  
  184. MODULE_LICENSE("GPL");  
  185. MODULE_AUTHOR("FriendlyARM Inc.");


request_irq(unsignedintirq,   irq_handler_thandler,     unsignedlongflags,     constchar*name,      void*dev)

发生对应于第 1个参数 irq 的中断时,则调用第 2 个参数handler 为要注册的中断服务函数(也就是把 handler() 中断服务函数注册到内核中 )。

第 3 个参数 flags 指定了快速中断或中断共享等中断处理属性

第 4 个参数 name,通常是设备驱动程序的名称

第 5 个参数 dev_id 中断名称 可作为共享中断时的中断区别参数,也可以用来指定中断服务函数需要参考的数据地址。建议将设备结构指针作为dev_id参数

时间: 2024-10-11 04:19:52

Button驱动的相关文章

Linux 驱动——Button驱动1

button_drv.c驱动文件: #include <linux/module.h>#include <linux/kernel.h>#include <linux/init.h>#include <asm/io.h> //包含iomap函数iounmap函数 #include <asm/uaccess.h>    //包含copy_from_user函数#include <linux/device.h>   //包含class类相

misc类型 按键驱动及应用- Linux

 闲着无聊,再扔个以前抄的水模版骗人 button 驱动: #include <linux/module.h> #include <linux/kernel.h> #include <linux/fs.h> #include <linux/init.h> #include <linux/delay.h> #include <linux/poll.h> #include <linux/sched.h> #include &l

深入浅出剖析C语言函数指针与回调函数(二)

上一篇博文的地址: http://blog.csdn.net/morixinguan/article/details/65494239 这节,我们来看看函数指针与回调函数在Linux内核中的应用. 从上节我们了解到,函数指针和回调函数在开发者和用户之间的一个例子,那么这节,我将引用Linux内核中文件操作结构体来详细的说明. 我们首先来看到这个结构体,这段代码位于linux内核的include/linux/fs.h中,由于代码众多,我只截取几个最基本的例子: File_operations文件操

MPSOC开发板软件资源

米尔推出的MPSOC开发板配备了丰富可靠的开源代码资源(linux OS+外设驱动+例程),助力快速入门. 类别 名称 描述信息 源码 Tool chains gcc5.2.1 gcc version 5.2.1(Linaro GCC5.2) Bootloader BOOT.bin 包括fsbl,u-boot Yes Driver usb2.0 Host usb2.0 Host驱动 Yes Driver usb3.0 Kernel Host usb3.0 Host驱动 Yes Driver Et

Linux设备驱动之button按键驱动学习与小结

button按键驱动,相对于前面的LED驱动来说.增加了中断服务程序以及等待队列等新知识点. 先上学习的驱动代码. 内核:linux3.0 板子:fl2440 /********************************************************************************* * Copyright: (C) 2011 Guo Wenxue<[email protected]> * All rights reserved. * * Filenam

fl2440 platform总线button字符设备驱动

驱动程序: 1 #include "s3c_driver.h" 2 3 #define DRV_DESC "S3C24XX button driver" 4 5 /* Driver version*/ 6 #define DRV_MAJOR_VER 1 7 #define DRV_MINOR_VER 0 8 #define DRV_REVER_VER 0 9 10 #define DEV_NAME DEV_BUTTON_NAME 11 12 //#define DE

13.Linux键盘按键驱动 (详解)

版权声明:本文为博主原创文章,未经博主允许不得转载. 在上一节分析输入子系统内的intput_handler软件处理部分后,接下来我们开始写input_dev驱动 本节目标: 实现键盘驱动,让开发板的4个按键代表键盘中的L.S.空格键.回车键 1.先来介绍以下几个结构体使用和函数,下面代码中会用到 1)input_dev驱动设备结构体中常用成员如下: struct input_dev { void *private; const char *name; //设备名字 const char *ph

构建你的长寿命的API第1部分:规范驱动的API开发

构建你的长寿命的API第1部分:规范驱动的API开发 这篇文章是由MuleSoft的Mike Stowe在nginx.conf 2016公布的演示文稿改编的.第一部分重点是规范驱动的API开发. 第二部分讨论的最佳实践.你能够查看完整的呈现的记录的v=G8p4g3yYLBw">YouTube.详细信息例如以下: 0:00 介绍 1:52 API正在改变世界 2:32 API正在连接一切 3:36 API应该是持久的 4:01 构建一个持久的API的5个步骤 4:38 从长计议 6:03 你

按键驱动异步通知

在此以前,我们都是让应用程序主动去读按键的状态,有没有一种情况,当驱动程序有数据时,主动去告诉应用程序,告诉它,有数据了,你赶紧来读吧.这种情况在linux里的专业术语就叫异步通知. 在按键的例子中异步通知可以理解为:当按键按下时,驱动程序会提醒(即触发)应用程序(通过信号signal来实现). 举一个例子:进程之间发信号 原来我们常用  kill 这个命令 : kill       -9    pid   kill这个命令就是一个发信号 发送者  :   kill 接收者  :   pid 信