本帖最后由 qq448309212947 于 2015-11-12 14:14 编辑
接着上次的GPIO驱动,花了几天的时间调试了一下GPIO的IRQ中断驱动程序,还是借鉴 开发板的例程进行了修改。
这里的测试程序比较简单,就是在while循环中一直等待中断的发生,产生中断后打印出 irq test。
在调试过程中出现了 GPIO请求失败的错误,最后发现是之前在测试LED驱动的时候已经请求过GPIO,而没有释放。
驱动程序:
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include <../arch/ARM/mach-mx28/mx28_pins.h>
-
- #define DEVICE_NAME "irq"
- #define LED_GPIO MXS_PIN_TO_GPIO(PINID_LCD_D07)
- #define LED_GPIO1 MXS_PIN_TO_GPIO(PINID_SSP0_DATA7)
- static irqreturn_t buttons_irq(int irq, void *dev_id)
- {
- printk("irq test n");
- return IRQ_RETVAL(IRQ_HANDLED);
- }
- static int gpio_open(struct inode *inode, struct file *filp)
- {
- int irq_no;
- int iRet;
- gpio_free(LED_GPIO);
- gpio_free(LED_GPIO1);
- iRet=gpio_request(LED_GPIO, "led");
- if (iRet != 0) {
- printk("request gpio failed n");
- return -EBUSY;
- }
- gpio_direction_input(LED_GPIO);
- irq_no = gpio_to_irq(LED_GPIO);
- set_irq_type(irq_no, IRQF_TRIGGER_FALLING);
- iRet = request_irq(irq_no, buttons_irq, IRQF_DISABLED, "gpio_int", NULL);
- if (iRet != 0){
- printk("request irq failed!! ret: %d irq:%d gpio:%d n", iRet, irq_no, LED_GPIO);
- return -EBUSY;
- }
- iRet=gpio_request(LED_GPIO1, "led1");
- if (iRet != 0) {
- printk("request gpio1 failed n");
- return -EBUSY;
- }
- gpio_direction_input(LED_GPIO1);
- irq_no = gpio_to_irq(LED_GPIO1);
- set_irq_type(irq_no, IRQF_TRIGGER_FALLING);
- iRet = request_irq(irq_no, buttons_irq, IRQF_DISABLED, "gpio_int", NULL);
- if (iRet != 0){
- printk("request irq failed!! ret: %d irq:%d gpio:%d n", iRet, irq_no, LED_GPIO1);
- return -EBUSY;
- }
- return 0;
- }
- static int gpio_release(struct inode *inode, struct file *filp)
- {
- int irq_no;
- irq_no = gpio_to_irq(LED_GPIO);
- free_irq(irq_no, NULL);
- gpio_free(LED_GPIO);
- irq_no = gpio_to_irq(LED_GPIO1);
- free_irq(irq_no, NULL);
- gpio_free(LED_GPIO1);
- return 0;
- }
- static struct file_operations gpio_fops={
- .owner = THIS_MODULE,
- .open = gpio_open,
- //.read = gpio_read,
- .release = gpio_release,
- };
- static struct miscdevice gpio_miscdev = {
- .minor = MISC_DYNAMIC_MINOR,
- .name = DEVICE_NAME,
- .fops = &gpio_fops,
- };
- static int __init gpio_init(void)
- {
- misc_register(&gpio_miscdev);
- printk(DEVICE_NAME" up. n");
- return 0;
- }
- static void __exit gpio_exit(void)
- {
- misc_deregister(&gpio_miscdev);
- printk(DEVICE_NAME " down.n");
- }
- module_init(gpio_init);
- module_exit(gpio_exit);
- MODULE_LICENSE("Dual BSD/GPL");
- MODULE_AUTHOR("zhuguojun, ZhiYuan Electronics Co, Ltd.");
- MODULE_DESCRIPTION("GPIO DRIVER FOR EasyARM-i.MX28xx");
复制代码
Makefile:
- ARCH=arm
- CROSS_COMPILE=/opt/gcc-4.4.4-glibc-2.11.1-multilib-1.0/arm-fsl-linux-gnueabi/bin/arm-fsl-linux-gnueabi-
- obj-m := gpioInt.o
- KDIR := /usr/linux-2.6.35.3
- PWD := $(shell pwd)
- default:
- make -C $(KDIR) M=$(PWD) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) modules
- clean:
- $(MAKE) -C $(KDIR) M=$(PWD) clean
-
复制代码
测试程序:
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- int main(int argc, char **argv)
- {
- int fd;
- int a,b;
- fd = open("/dev/irq", O_RDWR);
- if (fd < 0) {
- perror("open /dev/irq");
- }
- while(1);
- return 0;
- }
复制代码
下面是实物演示:
0
|
|
|
|