微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 按键中断的简单驱动实现

按键中断的简单驱动实现

时间:10-02 整理:3721RD 点击:

    接着上次的GPIO驱动,花了几天的时间调试了一下GPIO的IRQ中断驱动程序,还是借鉴开发板的例程进行了修改。
    这里的测试程序比较简单,就是在while循环中一直等待中断的发生,产生中断后打印出 irq test。
    在调试过程中出现了GPIO请求失败的错误,最后发现是之前在测试LED驱动的时候已经请求过GPIO,而没有释放。
    驱动程序:

  1. #include <linux/module.h>
  2. #include <linux/kernel.h>
  3. #include <linux/types.h>
  4. #include <linux/sched.h>
  5. #include <linux/init.h>
  6. #include <linux/fs.h>
  7. #include <linux/ioctl.h>
  8. #include <linux/delay.h>
  9. #include <linux/bcd.h>
  10. #include <linux/capability.h>
  11. #include <linux/rtc.h>
  12. #include <linux/cdev.h>
  13. #include <linux/miscdevice.h>
  14. #include <linux/gpio.h>
  15. #include<linux/irq.h>                                         
  16. #include<linux/interrupt.h>   
  17. #include <../arch/arm/mach-mx28/mx28_pins.h>                    
  18.            

  19. #define DEVICE_NAME        "irq"

  20. #define LED_GPIO        MXS_PIN_TO_GPIO(PINID_LCD_D07)        
  21. #define LED_GPIO1         MXS_PIN_TO_GPIO(PINID_SSP0_DATA7)


  22. static irqreturn_t buttons_irq(int irq, void *dev_id)
  23. {
  24.         printk("irq test \n");        

  25.         return IRQ_RETVAL(IRQ_HANDLED);
  26. }

  27. static int gpio_open(struct inode *inode, struct file *filp)
  28. {

  29.         int irq_no;
  30.         int iRet;

  31.         gpio_free(LED_GPIO);
  32.         gpio_free(LED_GPIO1);

  33.         iRet=gpio_request(LED_GPIO, "led");
  34.         if (iRet != 0) {
  35.                 printk("request gpio failed \n");
  36.                 return -EBUSY;
  37.         }
  38.         gpio_direction_input(LED_GPIO);
  39.         irq_no  = gpio_to_irq(LED_GPIO);
  40.         set_irq_type(irq_no, IRQF_TRIGGER_FALLING);        
  41.         iRet = request_irq(irq_no, buttons_irq, IRQF_DISABLED, "gpio_int", NULL);
  42.         if (iRet != 0){
  43.                 printk("request irq failed! ret: %d  irq:%d gpio:%d  \n", iRet, irq_no, LED_GPIO);
  44.                 return -EBUSY;
  45.         }


  46.         iRet=gpio_request(LED_GPIO1, "led1");        
  47.         if (iRet != 0) {
  48.                 printk("request gpio1 failed \n");
  49.                 return -EBUSY;
  50.         }
  51.         gpio_direction_input(LED_GPIO1);
  52.         irq_no  = gpio_to_irq(LED_GPIO1);
  53.         set_irq_type(irq_no, IRQF_TRIGGER_FALLING);        
  54.         iRet = request_irq(irq_no, buttons_irq, IRQF_DISABLED, "gpio_int", NULL);
  55.         if (iRet != 0){
  56.                 printk("request irq failed! ret: %d  irq:%d gpio:%d  \n", iRet, irq_no, LED_GPIO1);
  57.                 return -EBUSY;
  58.         }

  59.         return 0;
  60. }

  61. static int  gpio_release(struct inode *inode, struct file *filp)
  62. {
  63.         int irq_no;

  64.         irq_no  = gpio_to_irq(LED_GPIO);
  65.         free_irq(irq_no, NULL);
  66.         gpio_free(LED_GPIO);

  67.         irq_no  = gpio_to_irq(LED_GPIO1);
  68.         free_irq(irq_no, NULL);
  69.         gpio_free(LED_GPIO1);
  70.         return 0;
  71. }

  72. static struct file_operations gpio_fops={
  73.         .owner                = THIS_MODULE,
  74.         .open                 = gpio_open,
  75.         //.read                = gpio_read,
  76.         .release        = gpio_release,
  77. };

  78. static struct miscdevice gpio_miscdev = {
  79.         .minor  = MISC_DYNAMIC_MINOR,
  80.         .name        = DEVICE_NAME,
  81.         .fops        = &gpio_fops,
  82. };        

  83. static int __init gpio_init(void)
  84. {

  85.         misc_register(&gpio_miscdev);
  86.         printk(DEVICE_NAME" up. \n");
  87.         return 0;
  88. }

  89. static void __exit gpio_exit(void)
  90. {
  91.         misc_deregister(&gpio_miscdev);
  92.         printk(DEVICE_NAME " down.\n");
  93. }

  94. module_init(gpio_init);
  95. module_exit(gpio_exit);

  96. MODULE_LICENSE("Dual BSD/GPL");
  97. MODULE_AUTHOR("zhuguojun, ZhiYuan Electronics Co, Ltd.");
  98. MODULE_DESCRIPTION("GPIO DRIVER FOR EasyARM-i.MX28xx");

复制代码


    Makefile:

  1. ARCH=arm
  2. CROSS_COMPILE=/opt/gcc-4.4.4-glibc-2.11.1-multilib-1.0/arm-fsl-linux-gnueabi/bin/arm-fsl-linux-gnueabi-
  3. obj-m := gpioInt.o
  4. KDIR := /usr/linux-2.6.35.3
  5. PWD := $(shell pwd)
  6. default:
  7.         make -C $(KDIR) M=$(PWD) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) modules
  8.                                                                                                                                                          clean:
  9.         $(MAKE) -C $(KDIR) M=$(PWD) clean
  10.                                                                                                                                                                                                                   

复制代码


    测试程序:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <sys/types.h>
  5. #include <sys/stat.h>
  6. #include <fcntl.h>
  7. #include <termios.h>
  8. #include <errno.h>
  9. #include <limits.h>
  10. #include <asm/ioctls.h>
  11. #include <time.h>
  12. #include <pthread.h>


  13. int main(int argc, char **argv)
  14. {
  15.         int fd;
  16.         int a,b;

  17.         fd = open("/dev/irq", O_RDWR);
  18.         if (fd < 0) {
  19.                 perror("open /dev/irq");
  20.         }

  21.         while(1);

  22.         return 0;
  23. }

复制代码


    下面是实物演示:
   



Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top