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中断驱动
点击(此处)折叠或打开
- /*
- * gpio_light.c
- * @Date :11.15.2012
- */
-
- #include <mach/irqs.h>
- #include <asm/uaccess.h>
- #include <mach/regs-gpio.h>
- #include <mach/hardware.h>
- #include <linux/interrupt.h>
- #include <linux/cdev.h>
- #include <linux/device.h>
- #include <linux/errno.h>
- #include <linux/fs.h>
- #include <linux/gpio.h>
- #include <linux/init.h>
- #include <linux/irq.h>
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/types.h>
- #define LIGHT_ON 1
- #define LIGHT_OFF 0
- #define DEVICE_NAME "gpio_light"
- #define CLASS_NAME "light_class"
- static dev_t devid;
- static struct cdev light_cdev;
- static struct class *light_class;
- static struct gpio gpios_light[] =
- S5PV210_GPH0(6), GPIOF_OUT_INIT_HIGH, "LED1" ,
- S5PV210_GPH0(7), GPIOF_OUT_INIT_HIGH, "LED2" ,
- S5PV210_GPJ2(7), GPIOF_OUT_INIT_LOW, "CONTROL1" ,
- S5PV210_GPJ3(0), GPIOF_OUT_INIT_LOW, "CONTROL2" ,
- ;
- struct gpio_irqs_desc
- int irq;
- int irq_type;
- int pin;
- int pin_setting;
- int number;
- char *name;
- ;
- static struct gpio_irqs_desc gpio_irqs [] =
- IRQ_EINT12, IRQ_TYPE_EDGE_RISING, S5PV210_GPH1(4), S3C_GPIO_SFN(0xf), 0, "GPIO_IRQ_LED1",
- IRQ_EINT10, IRQ_TYPE_EDGE_RISING, S5PV210_GPH1(2), S3C_GPIO_SFN(0xf), 1, "GPIO_IRQ_LED2",
- ;
- void led_on(int cmd)
-
- gpio_set_value(gpios_light[cmd].gpio, 0);
- printk("Sucess to turn on the %s ! \\n", gpios_light[cmd].label);
-
- void led_off(int cmd)
-
- gpio_set_value(gpios_light[cmd].gpio, 1);
- printk("Sucess to turn off the %s ! \\n", gpios_light[cmd].label);
-
-
- static irqreturn_t light_intHandle(int irq, void *dev_id)
-
- struct gpio_irqs_desc *gpio_irqs = (struct gpio_irqs_desc *)dev_id;
- led_on(gpio_irqs->number);
- printk("Sucess to link GPIO with LED ! \\n");
- return IRQ_HANDLED;
-
-
- static void real_gpio_irqs_init(void)
-
- int err, i;
- for (i = 0; i < sizeof(gpio_irqs)/sizeof(gpio_irqs[0]); i++)
-
- err = gpio_request(gpio_irqs[i].pin, gpio_irqs[i].name); //1.GPIO注册
- if (err)
- pr_err("Failed to request %s ! \\n", gpio_irqs[i].name);
-
- err = s3c_gpio_cfgpin(gpio_irqs [i].pin, gpio_irqs[i].pin_setting); //2.将GPIO设置为中断状态
- if (err)
- pr_err("Failed to set the %s with interrupting !\\n",
- gpio_irqs[i].name);
-
- set_irq_type(gpio_irqs[i].irq, gpio_irqs [i].irq_type); //3.设置GPIO中断的触发方式
- disable_irq(gpio_irqs[i].irq);
- enable_irq(gpio_irqs[i].irq); //4.使能GPIO中断
- err = request_irq(gpio_irqs[i].irq,light_intHandle, 0,gpio_irqs[i].name, //5.中断注册
- (void *)&gpio_irqs[i]);
- printk("request_irq = %d !!!\\n", err);
- if(err)
- pr_err("Failed to request the %s ! \\n", gpio_irqs[i].name);
-
-
- static int gpios_light_open(struct inode *inode, struct file *filp)
- int err;
- printk("Sucess to open the gpios_light_open ! \\n");
- real_gpio_irqs_init();//完成GPIO中断注册
- err = gpio_request_array(gpios_light, ARRAY_SIZE(gpios_light));
- if (err)
- pr_err("Failed to request GPIO LIGHT ! \\n");
-
- return err;
- static int gpios_light_close(struct inode *inode, struct file *filp)
- int i;
- for (i = 0; i < sizeof(gpio_irqs)/sizeof(gpio_irqs[0]); i++)
-
- free_irq(gpio_irqs[i].irq,(void *)&gpio_irqs[i]);
- gpio_free(gpio_irqs[i].pin);
-
- gpio_free_array(gpios_light, ARRAY_SIZE(gpios_light));
- pr_err("Sucess to close ! \\n");
- return 0;
- static int gpios_light_ioctl(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
- switch (cmd)
- case LIGHT_ON:
- gpio_set_value(gpios_light[arg + 1].gpio, 1);
- break;
- case LIGHT_OFF:
- gpio_set_value(gpios_light[arg + 1].gpio, 0);
- led_off(arg-1);
- break;
- default:
- return -EINVAL;
-
- return 0;
- static struct file_operations gpio_light_fops =
- .owner = THIS_MODULE,
- .open = gpios_light_open,
- .release = gpios_light_close,
- .ioctl = gpios_light_ioctl,
- ;
- static int __init gpio_light_init(void)
- int err;
- struct device *pdev;
- err = alloc_chrdev_region(&devid, 0, 1, DEVICE_NAME);
- if (err < 0)
- pr_err("Failed to allocate LIGHT device numbers\\n");
- goto fail;
-
- cdev_init(&light_cdev, &gpio_light_fops);
- light_cdev.owner = THIS_MODULE;
- err = cdev_add(&light_cdev, devid, 1);
- if (err < 0)
- pr_err("Failed to add LIGHT device\\n");
- goto unregister_dev_num;
-
- light_class = class_create(THIS_MODULE, CLASS_NAME);
- if (IS_ERR(light_class))
- pr_err("Failed to create LIGHT class\\n");
- err = PTR_ERR(light_class);
- goto delete_cdev;
-
- pdev = device_create(light_class, NULL, devid, NULL, DEVICE_NAME);
- if (IS_ERR(pdev))
- pr_err("Failed to create LIGHT device\\n");
- err = PTR_ERR(pdev);
- goto destroy_class;
-
- return 0;
- destroy_class:
- class_destroy(light_class);
- delete_cdev:
- cdev_del(&light_cdev);
- unregister_dev_num:
- unregister_chrdev_region(devid, 1);
- fail:
- return err;
- static void __exit gpio_light_exit(void)
- device_destroy(light_class, devid);
- class_destroy(light_class);
- cdev_del(&light_cdev);
- unregister_chrdev_region(devid, 1);
- module_init(gpio_light_init);
- module_exit(gpio_light_exit);
- MODULE_LICENSE("GPL");
测试程序
点击(此处)折叠或打开
- /*
- * lighttest.c
- *
- * Created on: 2012-11-13
- *
- */
- #include <stdio.h>
- #include <fcntl.h>
- #include <unistd.h>
- #include <errno.h>
- #include <string.h>
- #include <sys/ioctl.h>
- #define DEVICE_PATH "/dev/gpio_light"
- int main(void)
- int fd;
- int input,led;
- fd = open(DEVICE_PATH, O_RDWR);
- printf("open = %d\\n", fd);
- if (fd == -1)
-
- perror("Can't open " DEVICE_PATH);
- return fd;
- else
- printf("Sucess to open " DEVICE_PATH);
- printf("\\nPlease input which led (1, 2)\\n");
- printf("and input switch mode (1, 0):\\n");
- while (scanf("%d %d",&led, &input) == 2)
- int ret = ioctl(fd, input, led);
- printf("ret = %d \\n",ret);
-
- close(fd);
- 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中断流程详解
相关热门文章- linux板子用户态通过/dev/mem...
- Java之异常
- linux dev_queue_xmit、qos队...
- linux tc流量限制不准确问题与...
- CortexA9四核UT4418开发板友坚...
以上是关于GPIO中断的主要内容,如果未能解决你的问题,请参考以下文章
树莓派官方自带gpio中断驱动bcm2708_gpio.c原理分析 linux 中断架构 中断子系统