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

 

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

主机平台:Ubuntu 11.04 内核版本2.6.39

 

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

Makefile

 

obj-m := my_io.o

KERNELDIR ?= /arm/linux-2.6.28.7-2440

PWD := $(shell pwd)

default:

$(MAKE) -C $(KERNELDIR) M=$(PWD) modules

clean:

rm -f *.o *.ko *.order *.symvers

调用代码:

 
     #include <stdio.h>   
  1. #include <stdlib.h>   
  2. #include <errno.h>   
  3.   
  4. #define MY_DEVICE "/dev/my_io"   
  5.   
  6. int main()  
  7. {  
  8.     int ret;  
  9.     int data;  
  10.     int i;  
  11.     ret=open(MY_DEVICE,0);  
  12.     printf("ret=%d\n",ret);  
  13.     for(i=0;i<20;i++)  
  14.     {  
  15.         read(ret,&data,sizeof(data));  
  16.         printf("the data is %d\n",data);  
  17.     }  
  18.     close(ret);  
  19.     printf("the device is closed\n");  
  20.     return 0;  
  21. }  

 

阅读更多
个人分类: linux驱动
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭