通过IO端口读取外部数据,带中断


基于FL2440开发板,Linux内核版本2.6.28

驱动代码

  1. #include <linux/kernel.h>   
  2. #include <linux/init.h>   
  3. #include <linux/module.h>   
  4. #include <linux/fs.h>   
  5. #include <linux/types.h>   
  6. #include <linux/interrupt.h>/*设置中断方式*/   
  7. #include <linux/wait.h>   
  8. #include <linux/sched.h>   
  9. #include <linux/irq.h>   
  10. #include <asm/irq.h>   
  11. #include <asm/uaccess.h>   
  12. #include <asm/io.h>   
  13. #include <linux/ioport.h>   
  14. //设备名   
  15. #define IO_DEVICE_NAME "my_io"   
  16. //主设备号   
  17. #define IO_DEVICE_MAJOR 240   
  18. //次设备号   
  19. #define IO_DEVICE_SECONDARY 32   
  20. #define S3C2410_GPFCON 0x56000070   
  21. #define S3C2410_GPFDAT_RELATIVE 4   
  22. #define S3C2410_GPFUP_RELATIVE 8   
  23. //返回一个数x的第y位   
  24. #define MYBIT(x,y) ((x>>y)%2)   
  25. #ifndef _LINUX_IRQRETURN_H   
  26. #define _LINUX_IRQRETURN_H   
  27. typedef int irqreturn_t;   
  28. #define IRQ_EINT0   0   
  29. #define IRQ_EINT2   2   
  30. #define IRQ_EINT3   3   
  31. #define IRQ_EINT4   32   
  32.   
  33. #define IRQ_NONE       (0)   
  34. #define IRQ_HANDLED       (1)   
  35. #define IRQ_RETVAL(x)      ((x) != 0)   
  36. #endif   
  37. /*  
  38.  * S3C2410 GPIO edge detection for IRQs:  
  39.  * IRQs are generated on Falling-Edge, Rising-Edge, both, low level or higg level.  
  40.  * This must be called *before* the corresponding IRQ is registered.  
  41.  */  
  42. #define EXT_LOWLEVEL        0   
  43. #define EXT_HIGHLEVEL       1   
  44. #define EXT_FALLING_EDGE    2   
  45. #define EXT_RISING_EDGE     4   
  46. #define EXT_BOTH_EDGES      6   
  47. static int flag_0,flag_2;//中断转换标志   
  48. volatile unsigned  int io_base;//io基地址   
  49. static int cnt;   
  50. DECLARE_WAIT_QUEUE_HEAD(io_wait_0);//声明等待队列   
  51. //DECLARE_WAIT_QUEUE_HEAD(io_wait_2);//声明等待队列   
  52. void io_con_set();   
  53. static irqreturn_t io_interrupt_0(int irq,void * dev_id,struct pt_regs *regs)   
  54. {   
  55.     printk("**********the interrupt 0 works**********\n");   
  56.     if(flag_0==0)   
  57.     {   
  58.         cnt=(cnt+1)%2;   
  59.         flag_0=1;   
  60.         if(cnt==0)   
  61.         {   
  62.             printk("IN\n");   
  63.         }   
  64.         wake_up_interruptible(&io_wait_0);   
  65.     }   
  66.     return IRQ_HANDLED;   
  67. }   
  68. static irqreturn_t io_interrupt_2(int irq,void * dev_id,struct pt_regs *regs)   
  69. {   
  70.     printk("**********the interrupt 2 works**********\n");   
  71.     if(flag_0==0)   
  72.     {   
  73.         cnt=(cnt+1)%2;   
  74.         flag_0=1;   
  75.         if(cnt==0)   
  76.         {   
  77.             printk("OUT\n");   
  78.         }   
  79.         wake_up_interruptible(&io_wait_0);   
  80.     }   
  81.     return IRQ_HANDLED;   
  82. }   
  83. static int io_open(struct inode * inode,struct file * file)//打开设备函数   
  84. {   
  85.     int ret;   
  86.     set_irq_type(IRQ_EINT0,EXT_FALLING_EDGE);//设置中断0 触发方式   
  87.     set_irq_type(IRQ_EINT2,EXT_FALLING_EDGE);//设置中断2 触发方式   
  88.     // EXT_LOWLEVEL   
  89.     // EXT_HIGHLEVEL   
  90.     // EXT_FALLING_EDGE   
  91.     // EXT_RISING_EDGE   
  92.     // EXT_BOTH_EDGES   
  93.     disable_irq(IRQ_EINT0);   
  94.     disable_irq(IRQ_EINT2);   
  95.     enable_irq(IRQ_EINT0);   
  96.     enable_irq(IRQ_EINT2);   
  97.     ret=request_irq(IRQ_EINT0,io_interrupt_0,IRQF_SHARED,IO_DEVICE_NAME,1);//注册中断0   
  98.     if(ret<0)   
  99.     {   
  100.         printk("IRQ %d can not request\n",IRQ_EINT0);   
  101.         return ret;   
  102.     }   
  103.     ret=request_irq(IRQ_EINT2,io_interrupt_2,IRQF_SHARED,IO_DEVICE_NAME,1);//注册中断2   
  104.     if(ret<0)   
  105.     {   
  106.         printk("IRQ %d can not request\n",IRQ_EINT2);   
  107.         return ret;   
  108.     }   
  109.     printk("the device is opened\n");   
  110.     io_con_set();   
  111.     cnt=0;   
  112.     return 0;   
  113. }   
  114. void io_con_set()//IO端口控制寄存器初始化   
  115. {   
  116.      int tmp;   
  117.      tmp=readl(io_base);   
  118.         
  119.      printk("the value of the GPFCON is 0x%x\n",tmp);   
  120.      tmp=0xFFFFFEAE&tmp;  //00=输入   01=输出   10=EINT*       
  121.      writel(tmp,io_base);//设置控制寄存器   
  122.         
  123.      //tmp=0xFFFF;   
  124.      //writel(tmp,io_base+S3C2410_GPFUP_RELATIVE); //设置上拉寄存器   
  125. }   
  126. static int io_close(struct inode * inode,struct file * file)//设备关闭函数   
  127. {   
  128.     free_irq(IRQ_EINT0,1);//释放中断   
  129.     free_irq(IRQ_EINT2,1);//释放中断   
  130.     printk("the device is closed\n");   
  131.     return 0;   
  132. }   
  133. static ssize_t io_read(struct file * filp,char  * buff,size_t count,loff_t  * f_ops)//读取IO端口   
  134. {   
  135.     wait_event_interruptible(io_wait_0,flag_0);   
  136.     wait_event_interruptible(io_wait_0,flag_0);   
  137.     flag_0=0;   
  138.     //flag_2=0;   
  139.     //printk("the value is %d\n",io_data);   
  140.     //copy_to_user(buff,(char *)&io_data,sizeof(io_data));   
  141. }   
  142. static struct file_operations io_device_fops =    
  143. {   
  144.     .owner=THIS_MODULE,   
  145.     .read=io_read,   
  146.     .open=io_open,   
  147.     .release=io_close,   
  148. };   
  149. static int __init io_init(void)//insmod加载驱动时执行   
  150. {   
  151.     int ret;   
  152.     request_mem_region(S3C2410_GPFCON,20,"S3C2410_GPF");   
  153.     io_base=ioremap(S3C2410_GPFCON  ,20);   
  154.     if(io_base==0)   
  155.     {   
  156.         printk("Fail to ioremap\n");   
  157.         goto err1;   
  158.         return -1;   
  159.     }   
  160.     ret=register_chrdev(IO_DEVICE_MAJOR,IO_DEVICE_NAME,&io_device_fops);   
  161.     if(ret<0)   
  162.     {   
  163.         printk("Fail to regist the device\n");   
  164.         return ret;   
  165.     }   
  166.     return 0;   
  167. err1:      
  168.     iounmap(io_base);   
  169.     release_mem_region(S3C2410_GPFCON,20);   
  170. }   
  171. static int __exit io_exit(void)//rmmod卸载驱动时执行   
  172. {   
  173.     unregister_chrdev(IO_DEVICE_MAJOR,IO_DEVICE_NAME);   
  174.     iounmap(io_base);   
  175.     release_mem_region(S3C2410_GPFCON,20);   
  176.     printk("the device has been unregisted\n");   
  177. }   
  178. module_init(io_init);   
  179. module_exit(io_exit);   
  180. MODULE_LICENSE("GPL");    
  • 1
  • 2
  • 下一页

相关内容