Linux内核版本 2.6.28.7
arm-linux-gcc 3.4.1
view plain copy to clipboard print ?
- #include <linux/kernel.h>
- #include <linux/init.h>
- #include <linux/module.h>
- #include <linux/fs.h>
- #include <linux/types.h>
- #include <linux/interrupt.h>/*设置中断方式*/
- #include <linux/wait.h>
- #include <linux/irq.h>
- #include <asm/uaccess.h>
- #include <mach/regs-gpio.h>
- #include <mach/hardware.h>
-
- #define IO_DEVICE_NAME "my_io"
-
- #define IO_DEVICE_MAJOR 240
-
- #define IO_DEVICE_SECONDARY 32
-
- #define MYBIT(x,y) ((x>>y)%2)
- #ifndef _LINUX_IRQRETURN_H
- #define _LINUX_IRQRETURN_H
- typedef int irqreturn_t;
- #define IRQ_EINT0 0
- #define IRQ_EINT2 2
- #define IRQ_EINT3 3
- #define IRQ_EINT4 32
- #define IRQ_NONE (0)
- #define IRQ_HANDLED (1)
- #define IRQ_RETVAL(x) ((x) != 0)
- #endif
-
-
-
-
-
- #define EXT_LOWLEVEL 0
- #define EXT_HIGHLEVEL 1
- #define EXT_FALLING_EDGE 2
- #define EXT_RISING_EDGE 4
- #define EXT_BOTH_EDGES 6
- static int flag_0,flag_2;
- static int cnt;
- DECLARE_WAIT_QUEUE_HEAD(io_wait);
- void io_con_set();
- static irqreturn_t io_interrupt_0(int irq,void * dev_id,struct pt_regs *regs)
- {
- printk("**********the interrupt 0 works**********/n");
- if(flag_0==0)
- {
- cnt=(cnt+1)%2;
- flag_0=1;
- if(cnt==0)
- {
- printk("IN/n");
- s3c2410_gpio_setpin(S3C2410_GPB5,0);
- s3c2410_gpio_setpin(S3C2410_GPB6,1);
- }
- wake_up_interruptible(&io_wait);
- }
- return IRQ_HANDLED;
- }
- static irqreturn_t io_interrupt_2(int irq,void * dev_id,struct pt_regs *regs)
- {
- printk("**********the interrupt 2 works**********/n");
- if(flag_2==0)
- {
- cnt=(cnt+1)%2;
- flag_2=1;
- if(cnt==0)
- {
- printk("OUT/n");
- s3c2410_gpio_setpin(S3C2410_GPB5,1);
- s3c2410_gpio_setpin(S3C2410_GPB6,0);
- }
- wake_up_interruptible(&io_wait);
- }
- return IRQ_HANDLED;
- }
- static int io_open(struct inode * inode,struct file * file)
- {
- int ret;
- set_irq_type(IRQ_EINT0,EXT_FALLING_EDGE);
- set_irq_type(IRQ_EINT2,EXT_FALLING_EDGE);
-
-
-
-
-
- disable_irq(IRQ_EINT0);
- disable_irq(IRQ_EINT2);
- enable_irq(IRQ_EINT0);
- enable_irq(IRQ_EINT2);
- ret=request_irq(IRQ_EINT0,io_interrupt_0,IRQF_SHARED,IO_DEVICE_NAME,1);
- if(ret<0)
- {
- printk("IRQ %d can not request/n",IRQ_EINT0);
- return ret;
- }
- ret=request_irq(IRQ_EINT2,io_interrupt_2,IRQF_SHARED,IO_DEVICE_NAME,1);
- if(ret<0)
- {
- printk("IRQ %d can not request/n",IRQ_EINT2);
- return ret;
- }
- printk("the device is opened/n");
- io_con_set();
- cnt=0;
- return 0;
- }
- void io_con_set()
- {
- s3c2410_gpio_cfgpin(S3C2410_GPF0,S3C2410_GPF0_EINT0);
- s3c2410_gpio_cfgpin(S3C2410_GPF2,S3C2410_GPF2_EINT2);
- s3c2410_gpio_cfgpin(S3C2410_GPB5,S3C2410_GPB5_OUTP);
- s3c2410_gpio_cfgpin(S3C2410_GPB6,S3C2410_GPB6_OUTP);
- }
- static int io_close(struct inode * inode,struct file * file)
- {
- free_irq(IRQ_EINT0,1);
- free_irq(IRQ_EINT2,1);
- printk("the device is closed/n");
- return 0;
- }
- static ssize_t io_read(struct file * filp,char * buff,size_t count,loff_t * f_ops)
- {
- wait_event_interruptible(io_wait,flag_0);
- wait_event_interruptible(io_wait,flag_0);
- flag_0=0;
- flag_2=0;
-
- copy_to_user(buff,(char *)&cnt,sizeof(cnt));
- }
- static struct file_operations io_device_fops =
- {
- .owner=THIS_MODULE,
- .read=io_read,
- .open=io_open,
- .release=io_close,
- };
- static int __init io_init(void)
- {
- int ret;
- ret=register_chrdev(IO_DEVICE_MAJOR,IO_DEVICE_NAME,&io_device_fops);
- if(ret<0)
- {
- printk("Fail to regist the device/n");
- return ret;
- }
- return 0;
- }
- static int __exit io_exit(void)
- {
- unregister_chrdev(IO_DEVICE_MAJOR,IO_DEVICE_NAME);
- printk("the device has been unregisted/n");
- }
- module_init(io_init);
- module_exit(io_exit);
- MODULE_LICENSE("GPL");
#include <linux/kernel.h>#include <linux/init.h>#include <linux/module.h>#include <linux/fs.h>#include <linux/types.h>#include <linux/interrupt.h>/*设置中断方式*/#include <linux/wait.h>#include <linux/irq.h>#include <asm/uaccess.h>#include <mach/regs-gpio.h>#include <mach/hardware.h>//设备名#define IO_DEVICE_NAME "my_io"//主设备号#define IO_DEVICE_MAJOR 240//次设备号#define IO_DEVICE_SECONDARY 32//返回一个数x的第y位#define MYBIT(x,y) ((x>>y)%2)#ifndef _LINUX_IRQRETURN_H#define _LINUX_IRQRETURN_Htypedef int irqreturn_t;#define IRQ_EINT0 0#define IRQ_EINT2 2#define IRQ_EINT3 3#define IRQ_EINT4 32#define IRQ_NONE (0)#define IRQ_HANDLED (1)#define IRQ_RETVAL(x) ((x) != 0)#endif/* * S3C2410 GPIO edge detection for IRQs: * IRQs are generated on Falling-Edge, Rising-Edge, both, low level or higg level. * This must be called *before* the corresponding IRQ is registered. */#define EXT_LOWLEVEL 0#define EXT_HIGHLEVEL 1#define EXT_FALLING_EDGE 2#define EXT_RISING_EDGE 4#define EXT_BOTH_EDGES 6static int flag_0,flag_2;//中断转换标志static int cnt;DECLARE_WAIT_QUEUE_HEAD(io_wait);//声明等待队列void io_con_set();static irqreturn_t io_interrupt_0(int irq,void * dev_id,struct pt_regs *regs){printk("**********the interrupt 0 works**********/n");if(flag_0==0){cnt=(cnt+1)%2;flag_0=1;if(cnt==0){printk("IN/n");s3c2410_gpio_setpin(S3C2410_GPB5,0);s3c2410_gpio_setpin(S3C2410_GPB6,1);}wake_up_interruptible(&io_wait);}return IRQ_HANDLED;}static irqreturn_t io_interrupt_2(int irq,void * dev_id,struct pt_regs *regs){printk("**********the interrupt 2 works**********/n");if(flag_2==0){cnt=(cnt+1)%2;flag_2=1;if(cnt==0){printk("OUT/n");s3c2410_gpio_setpin(S3C2410_GPB5,1);s3c2410_gpio_setpin(S3C2410_GPB6,0);}wake_up_interruptible(&io_wait);}return IRQ_HANDLED;}static int io_open(struct inode * inode,struct file * file)//打开设备函数{int ret;set_irq_type(IRQ_EINT0,EXT_FALLING_EDGE);//设置中断0 触发方式set_irq_type(IRQ_EINT2,EXT_FALLING_EDGE);//设置中断2 触发方式// EXT_LOWLEVEL// EXT_HIGHLEVEL// EXT_FALLING_EDGE// EXT_RISING_EDGE// EXT_BOTH_EDGESdisable_irq(IRQ_EINT0);disable_irq(IRQ_EINT2);enable_irq(IRQ_EINT0);enable_irq(IRQ_EINT2);ret=request_irq(IRQ_EINT0,io_interrupt_0,IRQF_SHARED,IO_DEVICE_NAME,1);//注册中断0if(ret<0){printk("IRQ %d can not request/n",IRQ_EINT0);return ret;}ret=request_irq(IRQ_EINT2,io_interrupt_2,IRQF_SHARED,IO_DEVICE_NAME,1);//注册中断2if(ret<0){printk("IRQ %d can not request/n",IRQ_EINT2);return ret;}printk("the device is opened/n");io_con_set();cnt=0;return 0;}void io_con_set()//IO端口控制寄存器初始化{ s3c2410_gpio_cfgpin(S3C2410_GPF0,S3C2410_GPF0_EINT0); s3c2410_gpio_cfgpin(S3C2410_GPF2,S3C2410_GPF2_EINT2); s3c2410_gpio_cfgpin(S3C2410_GPB5,S3C2410_GPB5_OUTP); s3c2410_gpio_cfgpin(S3C2410_GPB6,S3C2410_GPB6_OUTP);}static int io_close(struct inode * inode,struct file * file)//设备关闭函数{free_irq(IRQ_EINT0,1);//释放中断free_irq(IRQ_EINT2,1);//释放中断printk("the device is closed/n");return 0;}static ssize_t io_read(struct file * filp,char * buff,size_t count,loff_t * f_ops)//读取IO端口{wait_event_interruptible(io_wait,flag_0);wait_event_interruptible(io_wait,flag_0);flag_0=0;flag_2=0;//printk("the value is %d/n",io_data);copy_to_user(buff,(char *)&cnt,sizeof(cnt));}static struct file_operations io_device_fops = {.owner=THIS_MODULE,.read=io_read,.open=io_open,.release=io_close,};static int __init io_init(void)//insmod加载驱动时执行{int ret;ret=register_chrdev(IO_DEVICE_MAJOR,IO_DEVICE_NAME,&io_device_fops);if(ret<0){printk("Fail to regist the device/n");return ret;}return 0;}static int __exit io_exit(void)//rmmod卸载驱动时执行{unregister_chrdev(IO_DEVICE_MAJOR,IO_DEVICE_NAME);printk("the device has been unregisted/n");}module_init(io_init);module_exit(io_exit);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下
驱动修改版
view plain copy to clipboard print ?
- #include <linux/kernel.h>
- #include <linux/init.h>
- #include <linux/module.h>
- #include <linux/fs.h>
- #include <linux/types.h>
- #include <linux/interrupt.h>/*设置中断方式*/
- #include <linux/wait.h>
- #include <linux/irq.h>
- #include <asm/uaccess.h>
- #include <mach/regs-gpio.h>
- #include <mach/hardware.h>
-
- #define IO_DEVICE_NAME "my_io"
-
- #define IO_DEVICE_MAJOR 240
-
- #define IO_DEVICE_SECONDARY 32
-
- #define MYBIT(x,y) ((x>>y)%2)
- #ifndef _LINUX_IRQRETURN_H
- #define _LINUX_IRQRETURN_H
- typedef int irqreturn_t;
- #define IRQ_EINT0 0
- #define IRQ_EINT2 2
- #define IRQ_EINT3 3
- #define IRQ_EINT4 32
- #define IRQ_NONE (0)
- #define IRQ_HANDLED (1)
- #define IRQ_RETVAL(x) ((x) != 0)
- #endif
-
-
-
-
-
- #define EXT_LOWLEVEL 0
- #define EXT_HIGHLEVEL 1
- #define EXT_FALLING_EDGE 2
- #define EXT_RISING_EDGE 4
- #define EXT_BOTH_EDGES 6
- static int flag_0,flag_2;
- static int cnt;
- DECLARE_WAIT_QUEUE_HEAD(io_wait);
- void io_con_set();
- static irqreturn_t io_interrupt_0(int irq,void * dev_id,struct pt_regs *regs)
- {
- if(flag_0==0)
- {
- printk("**********the interrupt 0 works**********/n");
- cnt=(cnt+1)%2;
- flag_0=1;
- if(cnt==0)
- {
- printk("IN/n");
- s3c2410_gpio_setpin(S3C2410_GPB5,0);
- s3c2410_gpio_setpin(S3C2410_GPB6,1);
- }
- wake_up_interruptible(&io_wait);
- }
- return IRQ_HANDLED;
- }
- static irqreturn_t io_interrupt_2(int irq,void * dev_id,struct pt_regs *regs)
- {
- if(flag_2==0)
- {
- printk("**********the interrupt 2 works**********/n");
- cnt=(cnt+1)%2;
- flag_2=1;
- if(cnt==0)
- {
- printk("OUT/n");
- s3c2410_gpio_setpin(S3C2410_GPB5,1);
- s3c2410_gpio_setpin(S3C2410_GPB6,0);
- }
- wake_up_interruptible(&io_wait);
- }
- return IRQ_HANDLED;
- }
- static int io_open(struct inode * inode,struct file * file)
- {
- int ret;
- set_irq_type(IRQ_EINT0,EXT_FALLING_EDGE);
- set_irq_type(IRQ_EINT2,EXT_FALLING_EDGE);
-
-
-
-
-
- disable_irq(IRQ_EINT0);
- disable_irq(IRQ_EINT2);
- enable_irq(IRQ_EINT0);
- enable_irq(IRQ_EINT2);
- ret=request_irq(IRQ_EINT0,io_interrupt_0,IRQF_SHARED,IO_DEVICE_NAME,1);
- if(ret<0)
- {
- printk("IRQ %d can not request/n",IRQ_EINT0);
- return ret;
- }
- ret=request_irq(IRQ_EINT2,io_interrupt_2,IRQF_SHARED,IO_DEVICE_NAME,1);
- if(ret<0)
- {
- printk("IRQ %d can not request/n",IRQ_EINT2);
- return ret;
- }
- printk("the device is opened/n");
- io_con_set();
- cnt=0;
- return 0;
- }
- void io_con_set()
- {
- s3c2410_gpio_cfgpin(S3C2410_GPF0,S3C2410_GPF0_EINT0);
- s3c2410_gpio_cfgpin(S3C2410_GPF2,S3C2410_GPF2_EINT2);
- s3c2410_gpio_cfgpin(S3C2410_GPB5,S3C2410_GPB5_OUTP);
- s3c2410_gpio_cfgpin(S3C2410_GPB6,S3C2410_GPB6_OUTP);
- }
- static int io_close(struct inode * inode,struct file * file)
- {
- free_irq(IRQ_EINT0,1);
- free_irq(IRQ_EINT2,1);
- printk("the device is closed/n");
- return 0;
- }
- static ssize_t io_read(struct file * filp,char * buff,size_t count,loff_t * f_ops)
- {
- wait_event_interruptible(io_wait,flag_0&flag_2);
- flag_0=0;
- flag_2=0;
-
- copy_to_user(buff,(char *)&cnt,sizeof(cnt));
- }
- static struct file_operations io_device_fops =
- {
- .owner=THIS_MODULE,
- .read=io_read,
- .open=io_open,
- .release=io_close,
- };
- static int __init io_init(void)
- {
- int ret;
- ret=register_chrdev(IO_DEVICE_MAJOR,IO_DEVICE_NAME,&io_device_fops);
- if(ret<0)
- {
- printk("Fail to regist the device/n");
- return ret;
- }
- return 0;
- }
- static int __exit io_exit(void)
- {
- unregister_chrdev(IO_DEVICE_MAJOR,IO_DEVICE_NAME);
- printk("the device has been unregisted/n");
- }
- module_init(io_init);
- module_exit(io_exit);
- MODULE_LICENSE("GPL");
#include <linux/kernel.h>#include <linux/init.h>#include <linux/module.h>#include <linux/fs.h>#include <linux/types.h>#include <linux/interrupt.h>/*设置中断方式*/#include <linux/wait.h>#include <linux/irq.h>#include <asm/uaccess.h>#include <mach/regs-gpio.h>#include <mach/hardware.h>//设备名#define IO_DEVICE_NAME "my_io"//主设备号#define IO_DEVICE_MAJOR 240//次设备号#define IO_DEVICE_SECONDARY 32//返回一个数x的第y位#define MYBIT(x,y) ((x>>y)%2)#ifndef _LINUX_IRQRETURN_H#define _LINUX_IRQRETURN_Htypedef int irqreturn_t;#define IRQ_EINT0 0#define IRQ_EINT2 2#define IRQ_EINT3 3#define IRQ_EINT4 32#define IRQ_NONE (0)#define IRQ_HANDLED (1)#define IRQ_RETVAL(x) ((x) != 0)#endif/* * S3C2410 GPIO edge detection for IRQs: * IRQs are generated on Falling-Edge, Rising-Edge, both, low level or higg level. * This must be called *before* the corresponding IRQ is registered. */#define EXT_LOWLEVEL 0#define EXT_HIGHLEVEL 1#define EXT_FALLING_EDGE 2#define EXT_RISING_EDGE 4#define EXT_BOTH_EDGES 6static int flag_0,flag_2;//中断转换标志static int cnt;DECLARE_WAIT_QUEUE_HEAD(io_wait);//声明等待队列void io_con_set();static irqreturn_t io_interrupt_0(int irq,void * dev_id,struct pt_regs *regs){if(flag_0==0){printk("**********the interrupt 0 works**********/n");cnt=(cnt+1)%2;flag_0=1;if(cnt==0){printk("IN/n");s3c2410_gpio_setpin(S3C2410_GPB5,0);s3c2410_gpio_setpin(S3C2410_GPB6,1);}wake_up_interruptible(&io_wait);}return IRQ_HANDLED;}static irqreturn_t io_interrupt_2(int irq,void * dev_id,struct pt_regs *regs){if(flag_2==0){printk("**********the interrupt 2 works**********/n");cnt=(cnt+1)%2;flag_2=1;if(cnt==0){printk("OUT/n");s3c2410_gpio_setpin(S3C2410_GPB5,1);s3c2410_gpio_setpin(S3C2410_GPB6,0);}wake_up_interruptible(&io_wait);}return IRQ_HANDLED;}static int io_open(struct inode * inode,struct file * file)//打开设备函数{int ret;set_irq_type(IRQ_EINT0,EXT_FALLING_EDGE);//设置中断0 触发方式set_irq_type(IRQ_EINT2,EXT_FALLING_EDGE);//设置中断2 触发方式// EXT_LOWLEVEL// EXT_HIGHLEVEL// EXT_FALLING_EDGE// EXT_RISING_EDGE// EXT_BOTH_EDGESdisable_irq(IRQ_EINT0);disable_irq(IRQ_EINT2);enable_irq(IRQ_EINT0);enable_irq(IRQ_EINT2);ret=request_irq(IRQ_EINT0,io_interrupt_0,IRQF_SHARED,IO_DEVICE_NAME,1);//注册中断0if(ret<0){printk("IRQ %d can not request/n",IRQ_EINT0);return ret;}ret=request_irq(IRQ_EINT2,io_interrupt_2,IRQF_SHARED,IO_DEVICE_NAME,1);//注册中断2if(ret<0){printk("IRQ %d can not request/n",IRQ_EINT2);return ret;}printk("the device is opened/n");io_con_set();cnt=0;return 0;}void io_con_set()//IO端口控制寄存器初始化{ s3c2410_gpio_cfgpin(S3C2410_GPF0,S3C2410_GPF0_EINT0); s3c2410_gpio_cfgpin(S3C2410_GPF2,S3C2410_GPF2_EINT2); s3c2410_gpio_cfgpin(S3C2410_GPB5,S3C2410_GPB5_OUTP); s3c2410_gpio_cfgpin(S3C2410_GPB6,S3C2410_GPB6_OUTP);}static int io_close(struct inode * inode,struct file * file)//设备关闭函数{free_irq(IRQ_EINT0,1);//释放中断free_irq(IRQ_EINT2,1);//释放中断printk("the device is closed/n");return 0;}static ssize_t io_read(struct file * filp,char * buff,size_t count,loff_t * f_ops)//读取IO端口{wait_event_interruptible(io_wait,flag_0&flag_2);flag_0=0;flag_2=0;//printk("the value is %d/n",io_data);copy_to_user(buff,(char *)&cnt,sizeof(cnt));}static struct file_operations io_device_fops = {.owner=THIS_MODULE,.read=io_read,.open=io_open,.release=io_close,};static int __init io_init(void)//insmod加载驱动时执行{int ret;ret=register_chrdev(IO_DEVICE_MAJOR,IO_DEVICE_NAME,&io_device_fops);if(ret<0){printk("Fail to regist the device/n");return ret;}return 0;}static int __exit io_exit(void)//rmmod卸载驱动时执行{unregister_chrdev(IO_DEVICE_MAJOR,IO_DEVICE_NAME);printk("the device has been unregisted/n");}module_init(io_init);module_exit(io_exit);MODULE_LICENSE("GPL");
这个驱动实际上是通过红外传感器检测电平变化,来实现人数的统计,改进后能够实现正确的通过中断先后来识别方向,还排除了单一中断的
抖动干扰。