我的嵌入式

有志者,事竟成!

控制IO端口 s3c2410_gpio_setpin()的使用 .

 本文基于FL2440 ARM开发板

Linux内核版本 2.6.28.7

arm-linux-gcc 3.4.1 

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

Makefile同上一篇的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

 

 

这次本人修改了下内核头文件的目录,将目录./arch/arm/include下asm文件夹复制到./include

将目录./arch/arm/mach-s3c2410/include下mach文件夹复制到./include下

驱动修改版

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

这个驱动实际上是通过红外传感器检测电平变化,来实现人数的统计,改进后能够实现正确的通过中断先后来识别方向,还排除了单一中断的

抖动干扰。

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

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

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭