GPIO中断

Posted 飞雪天龙

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了GPIO中断相关的知识,希望对你有一定的参考价值。


主要功能:通过两个GPIO(S5PV210_GPJ2(7)和S5PV210_GPJ3(0))作为输出,来控制两个作为中断的GPIO(S5PV210_GPH1(4)和S5PV210_GPH1(2)),从而触发两个LED灯( S5PV210_GPH0(6)和S5PV210_GPH0(7))。


主要参考文件linux/interrupt.h, kernel/irq/manage.c, linux/irq.h, kernel/arch/arm/mach-s5pv210/include/mach/irqs.h, kernel/arch/arm/mach-s5pv210/include/mach/gpiolib.c

GPIO中断申请的主要步骤:

1.GPIO注册

2.GPIO中断设置

3.设置GPIO中断的触发方式

4.使能GPIO中断

5.中断注册


GPIO中断驱动

点击(此处)折叠或打开

  1. /*
  2.  * gpio_light.c
  3.  * @Date :11.15.2012
  4.  */
  5.    
  6. #include <mach/irqs.h>
  7. #include <asm/uaccess.h>
  8. #include <mach/regs-gpio.h>
  9. #include <mach/hardware.h>
  10. #include <linux/interrupt.h>
  11. #include <linux/cdev.h>
  12. #include <linux/device.h>
  13. #include <linux/errno.h>
  14. #include <linux/fs.h>
  15. #include <linux/gpio.h>
  16. #include <linux/init.h>
  17. #include <linux/irq.h>
  18. #include <linux/kernel.h>
  19. #include <linux/module.h>
  20. #include <linux/types.h>



  21. #define LIGHT_ON    1
  22. #define LIGHT_OFF    0

  23. #define DEVICE_NAME    "gpio_light"
  24. #define CLASS_NAME    "light_class"

  25. static dev_t devid;
  26. static struct cdev light_cdev;
  27. static struct class *light_class;

  28. static struct gpio gpios_light[] =
  29.      S5PV210_GPH0(6), GPIOF_OUT_INIT_HIGH, "LED1" ,
  30.      S5PV210_GPH0(7), GPIOF_OUT_INIT_HIGH, "LED2" ,
  31.      S5PV210_GPJ2(7), GPIOF_OUT_INIT_LOW, "CONTROL1" ,
  32.      S5PV210_GPJ3(0), GPIOF_OUT_INIT_LOW, "CONTROL2" ,
  33. ;

  34. struct gpio_irqs_desc
  35.     int irq;
  36.     int irq_type;
  37.     int pin;
  38.     int pin_setting;
  39.     int number;
  40.     char *name;
  41. ;
  42. static struct gpio_irqs_desc gpio_irqs [] =
  43.     IRQ_EINT12, IRQ_TYPE_EDGE_RISING, S5PV210_GPH1(4), S3C_GPIO_SFN(0xf), 0, "GPIO_IRQ_LED1",
  44.     IRQ_EINT10, IRQ_TYPE_EDGE_RISING, S5PV210_GPH1(2), S3C_GPIO_SFN(0xf), 1, "GPIO_IRQ_LED2",
  45. ;


  46. void led_on(int cmd)

  47.      gpio_set_value(gpios_light[cmd].gpio, 0);
  48.      printk("Sucess to turn on the %s ! \\n", gpios_light[cmd].label);

  49. void led_off(int cmd)

  50.      gpio_set_value(gpios_light[cmd].gpio, 1);
  51.      printk("Sucess to turn off the %s ! \\n", gpios_light[cmd].label);

  52.       
  53. static irqreturn_t light_intHandle(int irq, void *dev_id)

  54.     struct gpio_irqs_desc *gpio_irqs = (struct gpio_irqs_desc *)dev_id;
  55.     led_on(gpio_irqs->number);
  56.     printk("Sucess to link GPIO with LED ! \\n");
  57.     return IRQ_HANDLED;

  58.   
  59. static void real_gpio_irqs_init(void)

  60.     int err, i;
  61.     for (i = 0; i < sizeof(gpio_irqs)/sizeof(gpio_irqs[0]); i++)
  62.     
  63.         err = gpio_request(gpio_irqs[i].pin, gpio_irqs[i].name); //1.GPIO注册
  64.         if (err)
  65.             pr_err("Failed to request %s ! \\n", gpio_irqs[i].name);
  66.         

  67.         err = s3c_gpio_cfgpin(gpio_irqs [i].pin, gpio_irqs[i].pin_setting); //2.将GPIO设置为中断状态
  68.         if (err)
  69.             pr_err("Failed to set the %s with interrupting !\\n",
  70.                     gpio_irqs[i].name);
  71.         

  72.         set_irq_type(gpio_irqs[i].irq, gpio_irqs [i].irq_type); //3.设置GPIO中断的触发方式

  73.         disable_irq(gpio_irqs[i].irq);
  74.         enable_irq(gpio_irqs[i].irq); //4.使能GPIO中断
  75.         err = request_irq(gpio_irqs[i].irq,light_intHandle, 0,gpio_irqs[i].name, //5.中断注册
  76.                         (void *)&gpio_irqs[i]);
  77.         printk("request_irq = %d !!!\\n", err);
  78.         if(err)
  79.             pr_err("Failed to request the %s ! \\n", gpio_irqs[i].name);
  80.     



  81. static int gpios_light_open(struct inode *inode, struct file *filp)

  82.     int err;
  83.     printk("Sucess to open the gpios_light_open ! \\n");
  84.     real_gpio_irqs_init();//完成GPIO中断注册
  85.     err = gpio_request_array(gpios_light, ARRAY_SIZE(gpios_light));
  86.     if (err)
  87.         pr_err("Failed to request GPIO LIGHT ! \\n");
  88.     
  89.     return err;


  90. static int gpios_light_close(struct inode *inode, struct file *filp)

  91.     int i;
  92.     for (i = 0; i < sizeof(gpio_irqs)/sizeof(gpio_irqs[0]); i++)
  93.     
  94.         free_irq(gpio_irqs[i].irq,(void *)&gpio_irqs[i]);
  95.         gpio_free(gpio_irqs[i].pin);
  96.     


  97.     gpio_free_array(gpios_light, ARRAY_SIZE(gpios_light));
  98.     pr_err("Sucess to close ! \\n");
  99.     return 0;


  100. static int gpios_light_ioctl(struct inode *inode, struct file *filp,
  101.         unsigned int cmd, unsigned long arg)

  102.     switch (cmd)
  103.         case LIGHT_ON:
  104.             gpio_set_value(gpios_light[arg + 1].gpio, 1);
  105.             break;
  106.         case LIGHT_OFF:
  107.             gpio_set_value(gpios_light[arg + 1].gpio, 0);
  108.             led_off(arg-1);
  109.             break;
  110.         default:
  111.             return -EINVAL;
  112.     
  113.     return 0;



  114. static struct file_operations gpio_light_fops =

  115.     .owner        = THIS_MODULE,
  116.     .open        = gpios_light_open,
  117.     .release    = gpios_light_close,
  118.     .ioctl        = gpios_light_ioctl,
  119. ;

  120. static int __init gpio_light_init(void)

  121.     int err;
  122.     struct device *pdev;

  123.     err = alloc_chrdev_region(&devid, 0, 1, DEVICE_NAME);
  124.     if (err < 0)
  125.         pr_err("Failed to allocate LIGHT device numbers\\n");
  126.         goto fail;
  127.     

  128.     cdev_init(&light_cdev, &gpio_light_fops);
  129.     light_cdev.owner = THIS_MODULE;
  130.     err = cdev_add(&light_cdev, devid, 1);
  131.     if (err < 0)
  132.         pr_err("Failed to add LIGHT device\\n");
  133.         goto unregister_dev_num;
  134.     

  135.     light_class = class_create(THIS_MODULE, CLASS_NAME);
  136.     if (IS_ERR(light_class))
  137.         pr_err("Failed to create LIGHT class\\n");
  138.         err = PTR_ERR(light_class);
  139.         goto delete_cdev;
  140.     

  141.     pdev = device_create(light_class, NULL, devid, NULL, DEVICE_NAME);
  142.     if (IS_ERR(pdev))
  143.         pr_err("Failed to create LIGHT device\\n");
  144.         err = PTR_ERR(pdev);
  145.         goto destroy_class;
  146.     

  147.     return 0;

  148. destroy_class:
  149.     class_destroy(light_class);

  150. delete_cdev:
  151.     cdev_del(&light_cdev);

  152. unregister_dev_num:
  153.     unregister_chrdev_region(devid, 1);

  154. fail:
  155.     return err;


  156. static void __exit gpio_light_exit(void)

  157.     device_destroy(light_class, devid);
  158.     class_destroy(light_class);
  159.     cdev_del(&light_cdev);
  160.     unregister_chrdev_region(devid, 1);


  161. module_init(gpio_light_init);
  162. module_exit(gpio_light_exit);
  163. MODULE_LICENSE("GPL");


测试程序

点击(此处)折叠或打开

  1. /*
  2.  * lighttest.c
  3.  *
  4.  * Created on: 2012-11-13
  5.  *
  6.  */

  7. #include <stdio.h>
  8. #include <fcntl.h>
  9. #include <unistd.h>
  10. #include <errno.h>
  11. #include <string.h>
  12. #include <sys/ioctl.h>

  13. #define DEVICE_PATH        "/dev/gpio_light"

  14. int main(void)

  15.     int fd;
  16.     int input,led;

  17.     fd = open(DEVICE_PATH, O_RDWR);
  18.     printf("open = %d\\n", fd);
  19.     if (fd == -1)
  20.     
  21.         perror("Can't open " DEVICE_PATH);
  22.         return fd;
  23.     else
  24.         printf("Sucess to open " DEVICE_PATH);

  25.     printf("\\nPlease input which led (1, 2)\\n");
  26.     printf("and input switch mode (1, 0):\\n");
  27.     while (scanf("%d %d",&led, &input) == 2)
  28.         int ret = ioctl(fd, input, led);    
  29.         printf("ret = %d \\n",ret);
  30.     

  31.     close(fd);
  32.     return 0;


<script>window._bd_share_config="common":"bdSnsKey":,"bdText":"","bdMini":"2","bdMiniList":false,"bdPic":"","bdStyle":"0","bdSize":"16","share":;with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];</script> 阅读(1) | 评论(0) | 转发(0) | 0

上一篇:Linux内核线程

下一篇:linux中断流程详解

相关热门文章 给主人留下些什么吧!~~ 评论热议

以上是关于GPIO中断的主要内容,如果未能解决你的问题,请参考以下文章

树莓派官方自带gpio中断驱动bcm2708_gpio.c原理分析 linux 中断架构 中断子系统

stm32 外部中断 能读gpio值吗

STM 32 中断服务函数中加延时的处理

Zephry_GPIO的中断使用详解以及中断原理

[基础篇]ESP8266-SDK教程之GPIO操作(按键LED中断定时器)

stm32外部中断这程序编译没问题,但触发不了外部中断,卡了一天了