嵌入式Linux設(shè)備驅(qū)動(dòng)開發(fā)之:GPIO驅(qū)動(dòng)程序?qū)嵗?/h1>
本文引用地址:http://butianyuan.cn/article/257110.htm11.3.2GPIO驅(qū)動(dòng)程序
GPIO驅(qū)動(dòng)程序代碼如下所示:
/*gpio_drv.h*/
#ifndefFS2410_GPIO_SET_H
#defineFS2410_GPIO_SET_H
#includelinux/ioctl.h>
#defineGPIO_DEVICE_NAMEgpio
#defineGPIO_DEVICE_FILENAME/dev/gpio
#defineLED_NUM4
#defineGPIO_IOCTL_MAGIC'G'
#defineLED_D09_SWT_IOW(GPIO_IOCTL_MAGIC,0,unsignedint)
#defineLED_D10_SWT_IOW(GPIO_IOCTL_MAGIC,1,unsignedint)
#defineLED_D11_SWT_IOW(GPIO_IOCTL_MAGIC,2,unsignedint)
#defineLED_D12_SWT_IOW(GPIO_IOCTL_MAGIC,3,unsignedint)
#defineBEEP_SWT_IOW(GPIO_IOCTL_MAGIC,4,unsignedint)
#defineLED_SWT_ON0
#defineLED_SWT_OFF1
#defineBEEP_SWT_ON1
#defineBEEP_SWT_OFF0
#endif/*FS2410_GPIO_SET_H*/
/*gpio_drv.c*/
#includelinux/config.h>
#includelinux/module.h>
#includelinux/moduleparam.h>
#includelinux/init.h>
#includelinux/kernel.h>/*printk()*/
#includelinux/slab.h>/*kmalloc()*/
#includelinux/fs.h>/*everything...*/
#includelinux/errno.h>/*errorcodes*/
#includelinux/types.h>/*size_t*/
#includelinux/mm.h>
#includelinux/kdev_t.h>
#includelinux/cdev.h>
#includelinux/delay.h>
#includelinux/device.h>
#includeasm/io.h>
#includeasm/uaccess.h>
#includeasm/arch-s3c2410/regs-gpio.h>
#includegpio_drv.h
staticintmajor=0;/*采用字符設(shè)備號(hào)的動(dòng)態(tài)分配*/
module_param(major,int,0);/*以參數(shù)的方式可以指定設(shè)備的主設(shè)備號(hào)*/
voids3c2410_gpio_cfgpin(unsignedintpin,unsignedintfunction)
{/*對(duì)某個(gè)管腳進(jìn)行配置(輸入/輸出/其他功能)*/
unsignedlongbase=S3C2410_GPIO_BASE(pin);/*獲得端口的組基地址*/
unsignedlongshift=1;
unsignedlongmask=0x03;/*通常用配置寄存器的兩位表示一個(gè)端口*/
unsignedlongcon;
unsignedlongflags;
if(pinS3C2410_GPIO_BANKB)
{
shift=0;
mask=0x01;/*在GPA端口中用配置寄存器的一位表示一個(gè)端口*/
}
mask=(S3C2410_GPIO_OFFSET(pin)shift);
local_irq_save(flags);/*保存現(xiàn)場(chǎng),保證下面一段是原子操作*/
con=__raw_readl(base+0x00);
con=~mask;
con|=function;
__raw_writel(con,base+0x00);/*向配置寄存器寫入新配置數(shù)據(jù)*/
local_irq_restore(flags);/*恢復(fù)現(xiàn)場(chǎng)*/
}
voids3c2410_gpio_pullup(unsignedintpin,unsignedintto)
{/*配置上拉功能*/
unsignedlongbase=S3C2410_GPIO_BASE(pin);/*獲得端口的組基地址*/
unsignedlongoffs=S3C2410_GPIO_OFFSET(pin);/*獲得端口的組內(nèi)偏移地址*/
unsignedlongflags;
unsignedlongup;
if(pinS3C2410_GPIO_BANKB)
{
return;
}
local_irq_save(flags);
up=__raw_readl(base+0x08);
up=~(1offs);
up|=tooffs;
__raw_writel(up,base+0x08);/*向上拉功能寄存器寫入新配置數(shù)據(jù)*/
local_irq_restore(flags);
}
voids3c2410_gpio_setpin(unsignedintpin,unsignedintto)
{/*向某個(gè)管腳進(jìn)行輸出*/
unsignedlongbase=S3C2410_GPIO_BASE(pin);
unsignedlongoffs=S3C2410_GPIO_OFFSET(pin);
unsignedlongflags;
unsignedlongdat;
local_irq_save(flags);
dat=__raw_readl(base+0x04);
dat=~(1offs);
dat|=tooffs;
__raw_writel(dat,base+0x04);/*向數(shù)據(jù)寄存器寫入新數(shù)據(jù)*/
local_irq_restore(flags);
}
intgpio_open(structinode*inode,structfile*filp)
{/*open操作函數(shù):進(jìn)行寄存器配置*/
s3c2410_gpio_pullup(S3C2410_GPB0,1);/*BEEP*/
s3c2410_gpio_pullup(S3C2410_GPF4,1);/*LEDD12*/
s3c2410_gpio_pullup(S3C2410_GPF5,1);/*LEDD11*/
s3c2410_gpio_pullup(S3C2410_GPF6,1);/*LEDD10*/
s3c2410_gpio_pullup(S3C2410_GPF7,1);/*LEDD9*/
s3c2410_gpio_cfgpin(S3C2410_GPB0,S3C2410_GPB0_OUTP);
s3c2410_gpio_cfgpin(S3C2410_GPF4,S3C2410_GPF4_OUTP);
s3c2410_gpio_cfgpin(S3C2410_GPF4,S3C2410_GPF5_OUTP);
s3c2410_gpio_cfgpin(S3C2410_GPF4,S3C2410_GPF6_OUTP);
s3c2410_gpio_cfgpin(S3C2410_GPF4,S3C2410_GPF7_OUTP);
return0;
}
ssize_tgpio_read(structfile*file,char__user*buff,
size_tcount,loff_t*offp)
{/*read操作函數(shù):沒有實(shí)際功能*/
return0;
}
ssize_tgpio_write(structfile*file,constchar__user*buff,
size_tcount,loff_t*offp)
{/*write操作函數(shù):沒有實(shí)際功能*/
return0;
}
intswitch_gpio(unsignedintpin,unsignedintswt)
{/*向5個(gè)端口中的一個(gè)輸出ON/OFF值*/
if(!((pin=S3C2410_GPF7)(pin>=S3C2410_GPF4))
(pin!=S3C2410_GPB0))
{
printk(Unsupportedpin);
return1;
}
s3c2410_gpio_setpin(pin,swt);
return0;
}
linux操作系統(tǒng)文章專題:linux操作系統(tǒng)詳解(linux不再難懂)
linux相關(guān)文章:linux教程
蜂鳴器相關(guān)文章:蜂鳴器原理
11.3.2GPIO驅(qū)動(dòng)程序
GPIO驅(qū)動(dòng)程序代碼如下所示:
/*gpio_drv.h*/
#ifndefFS2410_GPIO_SET_H
#defineFS2410_GPIO_SET_H
#includelinux/ioctl.h>
#defineGPIO_DEVICE_NAMEgpio
#defineGPIO_DEVICE_FILENAME/dev/gpio
#defineLED_NUM4
#defineGPIO_IOCTL_MAGIC'G'
#defineLED_D09_SWT_IOW(GPIO_IOCTL_MAGIC,0,unsignedint)
#defineLED_D10_SWT_IOW(GPIO_IOCTL_MAGIC,1,unsignedint)
#defineLED_D11_SWT_IOW(GPIO_IOCTL_MAGIC,2,unsignedint)
#defineLED_D12_SWT_IOW(GPIO_IOCTL_MAGIC,3,unsignedint)
#defineBEEP_SWT_IOW(GPIO_IOCTL_MAGIC,4,unsignedint)
#defineLED_SWT_ON0
#defineLED_SWT_OFF1
#defineBEEP_SWT_ON1
#defineBEEP_SWT_OFF0
#endif/*FS2410_GPIO_SET_H*/
/*gpio_drv.c*/
#includelinux/config.h>
#includelinux/module.h>
#includelinux/moduleparam.h>
#includelinux/init.h>
#includelinux/kernel.h>/*printk()*/
#includelinux/slab.h>/*kmalloc()*/
#includelinux/fs.h>/*everything...*/
#includelinux/errno.h>/*errorcodes*/
#includelinux/types.h>/*size_t*/
#includelinux/mm.h>
#includelinux/kdev_t.h>
#includelinux/cdev.h>
#includelinux/delay.h>
#includelinux/device.h>
#includeasm/io.h>
#includeasm/uaccess.h>
#includeasm/arch-s3c2410/regs-gpio.h>
#includegpio_drv.h
staticintmajor=0;/*采用字符設(shè)備號(hào)的動(dòng)態(tài)分配*/
module_param(major,int,0);/*以參數(shù)的方式可以指定設(shè)備的主設(shè)備號(hào)*/
voids3c2410_gpio_cfgpin(unsignedintpin,unsignedintfunction)
{/*對(duì)某個(gè)管腳進(jìn)行配置(輸入/輸出/其他功能)*/
unsignedlongbase=S3C2410_GPIO_BASE(pin);/*獲得端口的組基地址*/
unsignedlongshift=1;
unsignedlongmask=0x03;/*通常用配置寄存器的兩位表示一個(gè)端口*/
unsignedlongcon;
unsignedlongflags;
if(pinS3C2410_GPIO_BANKB)
{
shift=0;
mask=0x01;/*在GPA端口中用配置寄存器的一位表示一個(gè)端口*/
}
mask=(S3C2410_GPIO_OFFSET(pin)shift);
local_irq_save(flags);/*保存現(xiàn)場(chǎng),保證下面一段是原子操作*/
con=__raw_readl(base+0x00);
con=~mask;
con|=function;
__raw_writel(con,base+0x00);/*向配置寄存器寫入新配置數(shù)據(jù)*/
local_irq_restore(flags);/*恢復(fù)現(xiàn)場(chǎng)*/
}
voids3c2410_gpio_pullup(unsignedintpin,unsignedintto)
{/*配置上拉功能*/
unsignedlongbase=S3C2410_GPIO_BASE(pin);/*獲得端口的組基地址*/
unsignedlongoffs=S3C2410_GPIO_OFFSET(pin);/*獲得端口的組內(nèi)偏移地址*/
unsignedlongflags;
unsignedlongup;
if(pinS3C2410_GPIO_BANKB)
{
return;
}
local_irq_save(flags);
up=__raw_readl(base+0x08);
up=~(1offs);
up|=tooffs;
__raw_writel(up,base+0x08);/*向上拉功能寄存器寫入新配置數(shù)據(jù)*/
local_irq_restore(flags);
}
voids3c2410_gpio_setpin(unsignedintpin,unsignedintto)
{/*向某個(gè)管腳進(jìn)行輸出*/
unsignedlongbase=S3C2410_GPIO_BASE(pin);
unsignedlongoffs=S3C2410_GPIO_OFFSET(pin);
unsignedlongflags;
unsignedlongdat;
local_irq_save(flags);
dat=__raw_readl(base+0x04);
dat=~(1offs);
dat|=tooffs;
__raw_writel(dat,base+0x04);/*向數(shù)據(jù)寄存器寫入新數(shù)據(jù)*/
local_irq_restore(flags);
}
intgpio_open(structinode*inode,structfile*filp)
{/*open操作函數(shù):進(jìn)行寄存器配置*/
s3c2410_gpio_pullup(S3C2410_GPB0,1);/*BEEP*/
s3c2410_gpio_pullup(S3C2410_GPF4,1);/*LEDD12*/
s3c2410_gpio_pullup(S3C2410_GPF5,1);/*LEDD11*/
s3c2410_gpio_pullup(S3C2410_GPF6,1);/*LEDD10*/
s3c2410_gpio_pullup(S3C2410_GPF7,1);/*LEDD9*/
s3c2410_gpio_cfgpin(S3C2410_GPB0,S3C2410_GPB0_OUTP);
s3c2410_gpio_cfgpin(S3C2410_GPF4,S3C2410_GPF4_OUTP);
s3c2410_gpio_cfgpin(S3C2410_GPF4,S3C2410_GPF5_OUTP);
s3c2410_gpio_cfgpin(S3C2410_GPF4,S3C2410_GPF6_OUTP);
s3c2410_gpio_cfgpin(S3C2410_GPF4,S3C2410_GPF7_OUTP);
return0;
}
ssize_tgpio_read(structfile*file,char__user*buff,
size_tcount,loff_t*offp)
{/*read操作函數(shù):沒有實(shí)際功能*/
return0;
}
ssize_tgpio_write(structfile*file,constchar__user*buff,
size_tcount,loff_t*offp)
{/*write操作函數(shù):沒有實(shí)際功能*/
return0;
}
intswitch_gpio(unsignedintpin,unsignedintswt)
{/*向5個(gè)端口中的一個(gè)輸出ON/OFF值*/
if(!((pin=S3C2410_GPF7)(pin>=S3C2410_GPF4))
(pin!=S3C2410_GPB0))
{
printk(Unsupportedpin);
return1;
}
s3c2410_gpio_setpin(pin,swt);
return0;
}
linux操作系統(tǒng)文章專題:linux操作系統(tǒng)詳解(linux不再難懂)linux相關(guān)文章:linux教程
蜂鳴器相關(guān)文章:蜂鳴器原理
評(píng)論