控制IO端口 s3c2410_gpio_setpin()的使用
Linux內(nèi)核版本 2.6.28.7
本文引用地址:http://m.butianyuan.cn/article/201611/318858.htmarm-linux-gcc 3.4.1
- #include
- #include
- #include
- #include
- #include
- #include
interrupt.h>/*設(shè)置中斷方式*/ - #include
- #include
- #include
- #include
- #include
- //設(shè)備名
- #defineIO_DEVICE_NAME"my_io"
- //主設(shè)備號
- #defineIO_DEVICE_MAJOR240
- //次設(shè)備號
- #defineIO_DEVICE_SECONDARY32
- //返回一個(gè)數(shù)x的第y位
- #defineMYBIT(x,y)((x>>y)%2)
- #ifndef_LINUX_IRQRETURN_H
- #define_LINUX_IRQRETURN_H
- typedefintirqreturn_t;
- #defineIRQ_EINT00
- #defineIRQ_EINT22
- #defineIRQ_EINT33
- #defineIRQ_EINT432
- #defineIRQ_NONE(0)
- #defineIRQ_HANDLED(1)
- #defineIRQ_RETVAL(x)((x)!=0)
- #endif
- /*
- *S3C2410GPIOedgedetectionforIRQs:
- *IRQsaregeneratedonFalling-Edge,Rising-Edge,both,lowlevelorhigglevel.
- *Thismustbecalled*before*thecorrespondingIRQisregistered.
- */
- #defineEXT_LOWLEVEL0
- #defineEXT_HIGHLEVEL1
- #defineEXT_FALLING_EDGE2
- #defineEXT_RISING_EDGE4
- #defineEXT_BOTH_EDGES6
- staticintflag_0,flag_2;//中斷轉(zhuǎn)換標(biāo)志
- staticintcnt;
- DECLARE_WAIT_QUEUE_HEAD(io_wait);//聲明等待隊(duì)列
- voidio_con_set();
- staticirqreturn_tio_interrupt_0(intirq,void*dev_id,structpt_regs*regs)
- {
- printk("**********theinterrupt0works**********/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);
- }
- returnIRQ_HANDLED;
- }
- staticirqreturn_tio_interrupt_2(intirq,void*dev_id,structpt_regs*regs)
- {
- printk("**********theinterrupt2works**********/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);
- }
- returnIRQ_HANDLED;
- }
- staticintio_open(structinode*inode,structfile*file)//打開設(shè)備函數(shù)
- {
- intret;
- set_irq_type(IRQ_EINT0,EXT_FALLING_EDGE);//設(shè)置中斷0觸發(fā)方式
- set_irq_type(IRQ_EINT2,EXT_FALLING_EDGE);//設(shè)置中斷2觸發(fā)方式
- //EXT_LOWLEVEL
- //EXT_HIGHLEVEL
- //EXT_FALLING_EDGE
- //EXT_RISING_EDGE
- //EXT_BOTH_EDGES
- 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);//注冊中斷0
- if(ret<0)
- {
- printk("IRQ%dcannotrequest/n",IRQ_EINT0);
- returnret;
- }
- ret=request_irq(IRQ_EINT2,io_interrupt_2,IRQF_SHARED,IO_DEVICE_NAME,1);//注冊中斷2
- if(ret<0)
- {
- printk("IRQ%dcannotrequest/n",IRQ_EINT2);
- returnret;
- }
- printk("thedeviceisopened/n");
- io_con_set();
- cnt=0;
- return0;
- }
- voidio_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);
- }
- staticintio_close(structinode*inode,structfile*file)//設(shè)備關(guān)閉函數(shù)
- {
- free_irq(IRQ_EINT0,1);//釋放中斷
- free_irq(IRQ_EINT2,1);//釋放中斷
- printk("thedeviceisclosed/n");
- return0;
- }
- staticssize_tio_read(structfile*filp,char*buff,size_tcount,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("thevalueis%d/n",io_data);
- copy_to_user(buff,(char*)&cnt,sizeof(cnt));
- }
- staticstructfile_operationsio_device_fops=
- {
- .owner=THIS_MODULE,
- .read=io_read,
- .open=io_open,
- .release=io_close,
- };
- staticint__initio_init(void)//insmod加載驅(qū)動時(shí)執(zhí)行
- {
- intret;
- ret=register_chrdev(IO_DEVICE_MAJOR,IO_DEVICE_NAME,&io_device_fops);
- if(ret<0)
- {
- printk("Failtoregistthedevice/n");
- returnret;
- }
- return0;
- }
- staticint__exitio_exit(void)//rmmod卸載驅(qū)動時(shí)執(zhí)行
- {
- unregister_chrdev(IO_DEVICE_MAJOR,IO_DEVICE_NAME);
- printk("thedevicehasbeenunregisted/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
這次本人修改了下內(nèi)核頭文件的目錄,將目錄./arch/arm/include下asm文件夾復(fù)制到./include
將目錄./arch/arm/mach-s3c2410/include下mach文件夾復(fù)制到./include下
驅(qū)動修改版
- #include
- #include
- #include
- #include
- #include
- #include
/*設(shè)置中斷方式*/ - #include
- #include
- #include
- #include
- #include
- //設(shè)備名
- #defineIO_DEVICE_NAME"my_io"
- //主設(shè)備號
- #defineIO_DEVICE_MAJOR240
- //次設(shè)備號
- #defineIO_DEVICE_SECONDARY32
- //返回一個(gè)數(shù)x的第y位
- #defineMYBIT(x,y)((x>>y)%2)
- #ifndef_LINUX_IRQRETURN_H
- #define_LINUX_IRQRETURN_H
- typedefintirqreturn_t;
- #defineIRQ_EINT00
- #defineIRQ_EINT22
- #defineIRQ_EINT33
- #defineIRQ_EINT432
- #defineIRQ_NONE(0)
- #defineIRQ_HANDLED(1)
- #defineIRQ_RETVAL(x)((x)!=0)
- #endif
- /*
- *S3C2410GPIOedgedetectionforIRQs:
- *IRQsaregeneratedonFalling-Edge,Rising-Edge,both,lowlevelorhigglevel.
- *Thismustbecalled*before*thecorrespondingIRQisregistered.
- */
- #defineEXT_LOWLEVEL0
- #defineEXT_HIGHLEVEL1
- #defineEXT_FALLING_EDGE2
- #defineEXT_RISING_EDGE4
- #defineEXT_BOTH_EDGES6
- staticintflag_0,flag_2;//中斷轉(zhuǎn)換標(biāo)志
- staticintcnt;
- DECLARE_WAIT_QUEUE_HEAD(io_wait);//聲明等待隊(duì)列
- voidio_con_set();
- staticirqreturn_tio_interrupt_0(intirq,void*dev_id,structpt_regs*regs)
- {
- if(flag_0==0)
- {
- printk("**********theinterrupt0works**********/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);
- }
- returnIRQ_HANDLED;
- }
- staticirqreturn_tio_interrupt_2(intirq,void*dev_id,structpt_regs*regs)
- {
- if(flag_2==0)
- {
- printk("**********theinterrupt2works**********/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);
- }
- returnIRQ_HANDLED;
- }
- staticintio_open(structinode*inode,structfile*file)//打開設(shè)備函數(shù)
- {
- intret;
- set_irq_type(IRQ_EINT0,EXT_FALLING_EDGE);//設(shè)置中斷0觸發(fā)方式
- set_irq_type(IRQ_EINT2,EXT_FALLING_EDGE);//設(shè)置中斷2觸發(fā)方式
- //EXT_LOWLEVEL
- //EXT_HIGHLEVEL
- //EXT_FALLING_EDGE
- //EXT_RISING_EDGE
- //EXT_BOTH_EDGES
- 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);//注冊中斷0
- if(ret<0)
- {
- printk("IRQ%dcannotrequest/n",IRQ_EINT0);
- returnret;
- }
- ret=request_irq(IRQ_EINT2,io_interrupt_2,IRQF_SHARED,IO_DEVICE_NAME,1);//注冊中斷2
- if(ret<0)
- {
- printk("IRQ%dcannotrequest/n",IRQ_EINT2);
- returnret;
- }
- printk("thedeviceisopened/n");
- io_con_set();
- cnt=0;
- return0;
- }
- voidio_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);
- }
- staticintio_close(structinode*inode,structfile*file)//設(shè)備關(guān)閉函數(shù)
- {
- free_irq(IRQ_EINT0,1);//釋放中斷
- free_irq(IRQ_EINT2,1);//釋放中斷
- printk("thedeviceisclosed/n");
- return0;
- }
- staticssize_tio_read(structfile*filp,char*buff,size_tcount,loff_t*f_ops)//讀取IO端口
- {
- wait_event_interruptible(io_wait,flag_0&flag_2);
- flag_0=0;
- flag_2=0;
- //printk("thevalueis%d/n",io_data);
- copy_to_user(buff,(char*)&cnt,sizeof(cnt));
- }
- staticstructfile_operationsio_device_fops=
- {
- .owner=THIS_MODULE,
- .read=io_read,
- .open=io_open,
- .release=io_close,
- };
- staticint__initio_init(void)//insmod加載驅(qū)動時(shí)執(zhí)行
- {
- intret;
- ret=register_chrdev(IO_DEVICE_MAJOR,IO_DEVICE_NAME,&io_device_fops);
- if(ret<0)
- {
- printk("Failtoregistthedevice/n");
- returnret;
- }
- return0;
- }
- staticint__exitio_exit(void)//rmmod卸載驅(qū)動時(shí)執(zhí)行
- {
- unregister_chrdev(IO_DEVICE_MAJOR,IO_DEVICE_NAME);
- printk("thedevicehasbeenunregisted/n");
- }
- module_init(io_init);
- module_exit(io_exit);
- MODULE_LICENSE("GPL");
這個(gè)驅(qū)動實(shí)際上是通過紅外傳感器檢測電平變化,來實(shí)現(xiàn)人數(shù)的統(tǒng)計(jì),改進(jìn)后能夠?qū)崿F(xiàn)正確的通過中斷先后來識別方向,還排除了單一中斷的
抖動干擾。
評論