Linux gpio 中断应用(转载)

 今日为了调试ARM板上的GPIO引脚中断效果,以便在后续项目使用ARM与ZLG7290按键LED中断芯片连接中随意选择空闲的GPIO引脚来作为ZLG7290的中断信号线,特意编写了一个小的Linux GPIO中断驱动程序下载到开发板上做实验。经验证,这种软件中断方式也还差强人意。下面贴出自己编写的不成熟的代码,见笑(<-_->)。

       实验的硬件电路为ARM GPIO的PB17连接一个共阴LED,PB18与PB19连接,PB18由中断驱动设置为低电平触发,PB19由GPIO驱动程序控制,上层应用程序通过驱动控制PB19高低电平变化,从而引发PB18发生中断,中断程序中控制PB17的LED亮和灭。

      Linux中断驱动部分:

 

  1. /* 
  2.  * PB18_IRQTest.c 
  3.  * This is  a test program for sam9260, using PB19(J5_18 pin) input a signal to PB18(J5_16 pin), 
  4.  * PB18 receive this signal as IRQ and make the LED linking on PB17((J5_14 pin)) turn on or turn off    
  5.  * 
  6.  *           @Author: Cun Tian Rui  
  7.  *           @Date :March.18.2011 
  8.  */  
  9.   
  10. #include <linux/types.h>   
  11. #include <linux/kernel.h>   
  12. #include <linux/module.h>   
  13. #include <linux/init.h>   
  14. #include <linux/platform_device.h>   
  15. #include <linux/cdev.h>   
  16. #include <linux/ioctl.h>   
  17. #include <linux/fs.h>   
  18. #include <linux/gpio.h>   
  19. #include <asm/arch/hardware.h>   
  20. #include <asm/arch/gpio.h>   
  21. #include <linux/interrupt.h>   
  22. #include <asm/io.h>   
  23. #include <asm/arch/board.h>   
  24. #include <linux/cdev.h>   
  25. #include <asm/arch/gpio.h>   
  26. #include <asm/uaccess.h>   
  27. #include <asm/io.h>   
  28. #include <asm/arch/at91_pio.h>   
  29. #include <asm/arch/at91_aic.h>   
  30. #include <asm/arch/at91_pmc.h>   
  31.   
  32. void led_on()  
  33. {      
  34.      at91_set_gpio_output(AT91_PIN_PB17,1);  
  35. }  
  36.   
  37. void led_off()  
  38. {      
  39.      at91_set_gpio_output(AT91_PIN_PB17 ,0);  
  40. }  
  41.   
  42. struct light_dev *light_devp;  
  43. int light_major = 200;  
  44.   
  45. struct light_dev  
  46. {  
  47.     struct cdev cdev;  
  48.     unsigned char value;  
  49. };  
  50.   
  51. MODULE_AUTHOR("Cun Tian Rui");  
  52. MODULE_LICENSE("Dual BSD/GPL");  
  53.   
  54.   
  55. static void io_init(void)  
  56. {  
  57.     at91_set_gpio_input(AT91_PIN_PB18, 1);          
  58.     at91_set_deglitch(AT91_PIN_PB18, 1);   
  59.     at91_sys_write(1 + PIO_IDR,  1<<18);  
  60.     at91_sys_write(1 + PIO_IER,  (~(1<<18)));  
  61.     at91_sys_write(AT91_PMC_PCER, 1 << 3);  
  62. }  
  63.   
  64.   
  65. struct gpio_irq_desc  
  66. {  
  67.     int irq;  
  68.     unsigned long flags;  
  69.     char *name;  
  70. };  
  71.   
  72. static struct gpio_irq_desc PB18_IRQ={AT91_PIN_PB18,AT91_AIC_SRCTYPE_LOW,"PB18"};  
  73.   
  74. static irqreturn_t PB18_intHandle(int irq, void *dev_id)  
  75. {  
  76.     led_on();  
  77.     return IRQ_RETVAL(IRQ_HANDLED);  
  78. }  
  79.   
  80. int light_open(struct inode *inode,struct file *filp)  
  81. {  
  82.     int err;  
  83.     struct light_dev *dev;  
  84.     dev = container_of(inode->i_cdev,struct light_dev,cdev);  
  85.     filp->private_data = dev;  
  86.     io_init();  
  87.     err = request_irq(PB18_IRQ.irq,PB18_intHandle,PB18_IRQ.flags,PB18_IRQ.name,(void*)0);  
  88.     if(err)   
  89.         {  
  90.         free_irq(PB18_IRQ.irq,(void*)0);  
  91.         return  -EBUSY;  
  92.     }  
  93.       
  94.     return 0;  
  95. }  
  96.   
  97. int light_release(struct inode *inode,struct file *filp)  
  98. {  
  99.     free_irq(PB18_IRQ.irq,(void*)0);  
  100.     return 0;      
  101. }  
  102.   
  103.   
  104.   
  105. // ioctl   
  106. int light_ioctl(struct inode *inode,struct file *filp,unsigned int cmd,  
  107. unsigned long arg)  
  108. {  
  109.     struct light_dev *dev = filp->private_data;  
  110.   
  111.     switch(cmd)  
  112.     {  
  113.         case 0:  
  114.             at91_set_gpio_output(AT91_PIN_PB19,0);       
  115.         break;  
  116.   
  117.         case 1:  
  118.           at91_set_gpio_output(AT91_PIN_PB19,1);  
  119.        led_off();  
  120.         break;  
  121.   
  122.         default:  
  123.   
  124.             return -ENOTTY;  
  125.         // break;   
  126.     }  
  127.   
  128.     return 0;  
  129. }       
  130.   
  131. struct file_operations light_fops =   
  132. {  
  133.     .owner = THIS_MODULE,  
  134.     .ioctl = light_ioctl,  
  135.     .open  = light_open,  
  136.     .release = light_release,  
  137. };  
  138.   
  139.   
  140. static void light_setup_cdev(struct light_dev *dev,int index)  
  141. {  
  142.     int err,devno = MKDEV(light_major,index);  
  143.   
  144.     cdev_init(&dev->cdev,&light_fops);  
  145.     dev->cdev.owner = THIS_MODULE;  
  146.     dev->cdev.ops = &light_fops;  
  147.   
  148.     err = cdev_add(&dev->cdev,devno,1);  
  149.   
  150.     if(err)  
  151.     {  
  152.         printk(KERN_NOTICE "Error %d adding LED%d",err,index);  
  153.     }  
  154. }  
  155.   
  156.   
  157. int light_init(void)  
  158. {  
  159.     int result;  
  160.   
  161.     dev_t dev = MKDEV(light_major,0);  
  162.     if(light_major)  
  163.     {  
  164.           
  165.         result = register_chrdev_region(dev,1,"PB18_IRQTest");  
  166.     }  
  167.   
  168.     if(result < 0)  
  169.     {  
  170.         return result;  
  171.     }  
  172.   
  173.     light_devp = kmalloc(sizeof(struct light_dev),GFP_KERNEL);  
  174.     if(!light_devp)  
  175.     {  
  176.         result = - ENOMEM;  
  177.         goto fail_malloc;  
  178.     }  
  179.   
  180.     memset(light_devp,0,sizeof(struct light_dev));  
  181.     light_setup_cdev(light_devp,0);  
  182.       
  183.   
  184.     return 0;  
  185.   
  186.     fail_malloc:unregister_chrdev_region(dev,light_devp);  
  187.     return result;  
  188.       
  189. }  
  190.   
  191. void light_cleanup(void)  
  192. {  
  193.     cdev_del(&light_devp->cdev);     
  194.     kfree(light_devp);  
  195.     unregister_chrdev_region(MKDEV(light_major,0),1);    
  196. }  
  197.   
  198. module_init(light_init);  
  199. module_exit(light_cleanup);  

 Linux上层应用程序:

 

  1. #include <stdio.h>   
  2. //#include <conio.h>  
  3. #include <unistd.h>  
  4. #include <stdlib.h>  
  5. #include <string.h>  
  6. #include <fcntl.h>  
  7. #include <sys/types.h>  
  8. #include <sys/stat.h>  
  9. #include <linux/ioctl.h>  
  10. #include <signal.h>   
  11.   
  12.   
  13. int main(int argc ,char *argv[])  
  14. {  
  15.     int fd;  
  16.         char input;  
  17.     fd = open("/dev/PB18_IRQTest",O_RDWR);  
  18.     if(fd < 0)  
  19.         {         
  20.             perror("open PB18_IRQTest device");  
  21.                 return 0;  
  22.         }  
  23.     while(1)  
  24.         {  
  25.              printf("input 0 to trigger int/n");  
  26.              scanf("%c",&input);  
  27.              switch(input)  
  28.              {  
  29.             case '0':  
  30.                         ioctl(fd,0,0);  
  31.             printf("/n");  
  32.             break;  
  33.             case '1':  
  34.             ioctl(fd,1,0);  
  35.             printf("/n");  
  36.             break;  
  37.                 default:  
  38.             printf("/n");  
  39.                     break;                                          
  40.                      }  
  41.                  }                                                           
  42.                   return 0;  
  43. }  

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值