首页
登录 | 注册

(2)按键中断

一、硬件
          buttuon1: S3C2410_GPF0 ---- IRQ_EINT0
          buttuon2: S3C2410_GPF2 ---- IRQ_EINT2
          buttuon3: S3C2410_GPG3 --- IRQ_EINT11
          buttuon4: S3C2410_GPG11 ---IRQ_EINT19

1申请中断:

request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, const char *name, void *dev)

                (中断号,中断服务函数,中断触发方式,设备名字,id)

                id作用:①当卸载中断时候(free_irq)id一起确定卸载哪个中断。

                              也可以用来传递参数              

 

2释放中断

void free_irq(unsigned int irq, void *dev_id)

                  (中断号,id

3、等待队列:等待某个事件,事件获取不成功."等待过程(睡眠)" 直到被唤醒“获取事件”

  #define DECLARE_WAIT_QUEUE_HEAD (name)          \

wait_queue_head_t name = __WAIT_QUEUE_HEAD_INITIALIZER(name)
   生成一个名字为name wait_queue_head_t 等待队列头

②唤醒

/*一直在此处阻塞(因为驱动处于休眠态),直到ondition1 */

 wait_event_interruptible(wait, condition);

/*condition=1,唤醒休眠的进程*/

condition=1

wake_up_interruptible(&wait);




  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/irq.h>
  7. #include <asm/uaccess.h>
  8. #include <asm/irq.h>
  9. #include <asm/io.h>
  10. #include <asm/arch/regs-gpio.h>
  11. #include <asm/hardware.h>


  12. static struct class *buttondrv_class;
  13. static struct class_device    *buttondrv_class_dev;

  14. volatile unsigned long *gpfcon;
  15. volatile unsigned long *gpfdat;

  16. volatile unsigned long *gpgcon;
  17. volatile unsigned long *gpgdat;


  18. static DECLARE_WAIT_QUEUE_HEAD(button_waitq);

  19. /* 中断事件标志, 中断服务程序将它置1,button_drv_read将它清0 */
  20. static volatile int ev_press = 0;

  21. struct pin_desc{
  22.     unsigned int pin;
  23.     unsigned int key_val;
  24. };


  25. /* 键值: 按下时, 0x01, 0x02, 0x03, 0x04 */
  26. /* 键值: 松开时, 0x81, 0x82, 0x83, 0x84 */
  27. static unsigned char key_val;

  28. struct pin_desc pins_desc[4] = {
  29.     {S3C2410_GPF0, 0x01},
  30.     {S3C2410_GPF2, 0x02},
  31.     {S3C2410_GPG3, 0x03},
  32.     {S3C2410_GPG11, 0x04},
  33. };


  34. /*
  35.   * 确定按键值
  36.   */
  37. static irqreturn_t buttons_irq(int irq, void *dev_id)
  38. {
  39.     struct pin_desc * pindesc = (struct pin_desc *)dev_id;
  40.     unsigned int pinval;
  41.     
  42.     pinval = s3c2410_gpio_getpin(pindesc->pin);

  43.     if (pinval)
  44.     {
  45.         /* 松开 */
  46.         key_val = 0x80 | pindesc->key_val;
  47.     }
  48.     else
  49.     {
  50.         /* 按下 */
  51.         key_val = pindesc->key_val;
  52.     }

  53.     ev_press = 1; /* 表示中断发生了 */
  54.     wake_up_interruptible(&button_waitq); /* 唤醒休眠的进程 */

  55.     
  56.     return IRQ_RETVAL(IRQ_HANDLED);
  57. }

  58. static int button_drv_open(struct inode *inode, struct file *file)
  59. {
  60.     /* 配置GPF0,2为输入引脚 */
  61.     /* 配置GPG3,11为输入引脚 */
  62.     request_irq(IRQ_EINT0, buttons_irq, IRQT_BOTHEDGE, "S2", &pins_desc[0]);
  63.     request_irq(IRQ_EINT2, buttons_irq, IRQT_BOTHEDGE, "S3", &pins_desc[1]);
  64.     request_irq(IRQ_EINT11, buttons_irq, IRQT_BOTHEDGE, "S4", &pins_desc[2]);
  65.     request_irq(IRQ_EINT19, buttons_irq, IRQT_BOTHEDGE, "S5", &pins_desc[3]);    

  66.     return 0;
  67. }

  68. ssize_t button_drv_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
  69. {
  70.     if (size != 1)
  71.         return -EINVAL;

  72.     /* 如果没有按键动作, 休眠 */
  73.     wait_event_interruptible(button_waitq, ev_press);

  74.     /* 如果有按键动作, 返回键值 */
  75.     copy_to_user(buf, &key_val, 1);
  76.     ev_press = 0;
  77.     
  78.     return 1;
  79. }


  80. int button_drv_close(struct inode *inode, struct file *file)
  81. {
  82.     free_irq(IRQ_EINT0, &pins_desc[0]);
  83.     free_irq(IRQ_EINT2, &pins_desc[1]);
  84.     free_irq(IRQ_EINT11, &pins_desc[2]);
  85.     free_irq(IRQ_EINT19, &pins_desc[3]);
  86.     return 0;
  87. }


  88. static struct file_operations sencod_drv_fops = {
  89.     .owner = THIS_MODULE, /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */
  90.     .open = button_drv_open,
  91.     .read     =    button_drv_read,    
  92.     .release = button_drv_close,    
  93. };


  94. static dev_t devid;
  95. static struct cdev *buttonCdev = NULL;
  96. static struct class *button_class=NULL;
  97. static struct class_device *button_class_dev=NULL;

  98. int major;
  99. static int button_init(void)
  100. {
  101.              alloc_chrdev_region(&devid,0,1,"button"); //向系统动态申请设备号 cat /proc/devices ---->button
  102.         major = MAJOR(devid); //获取主设备号
  103.         buttonCdev = cdev_alloc(); //动态申请cdev内存
  104.         cdev_init(buttonCdev,&sencod_drv_fops); //初始化cdev成员,并建立cdev和file_operations之间的链接
  105.         cdev_add(buttonCdev, devid, 1); //向系统添加一个cdev,完成字符设备的注册

  106.     
  107.      button_class=class_create(THIS_MODULE, "button"); // /sys/class/mybutton/
  108.      button_class_dev=class_device_create(button_class, NULL, devid,NULL, "button"); // /dev/button
  109.     
  110.     gpfcon = (volatile unsigned long *)ioremap(0x56000050, 16);
  111.     gpfdat = gpfcon + 1;

  112.     gpgcon = (volatile unsigned long *)ioremap(0x56000060, 16);
  113.     gpgdat = gpgcon + 1;

  114.     return 0;
  115. }

  116. static void button_exit(void)
  117. {
  118.     class_device_destroy(button_class, devid); //删除设备节点
  119.     class_destroy(button_class); //删除类
  120.     cdev_del(&buttonCdev); //删除cdev结构体
  121.     unregister_chrdev_region(devid, 1); //注销设备号
  122.     
  123.     iounmap(gpfcon);
  124.     iounmap(gpgcon);
  125.     return 0;
  126. }


  127. module_init(button_init);

  128. module_exit(button_exit);

  129. MODULE_LICENSE("GPL");






  1. #include <sys/types.h>
  2. #include <sys/stat.h>
  3. #include <fcntl.h>
  4. #include <stdio.h>

  5. /* thirddrvtest
  6.   */
  7. int main(int argc, char **argv)
  8. {
  9.     int fd;
  10.     unsigned char key_val;
  11.     
  12.     fd = open("/dev/button", O_RDWR);
  13.     if (fd < 0)
  14.     {
  15.         printf("can't open!\n");
  16.     }

  17.     while (1)
  18.     {
  19.         read(fd, &key_val, 1);
  20.         printf("key_val = 0x%x\n", key_val);
  21.     }
  22.     
  23.     return 0;
  24. }



2020 unjeep.com webmaster#unjeep.com
11 q. 0.010 s.
京ICP备10005923号