嵌入式Linux设备驱动开发之:GPIO驱动程序实例
设备号*/
voids3c2410_gpio_cfgpin(unsignedintpin,unsignedintfunction)
{/*对某个管脚进行配置(输入/输出/其他功能)*/
unsignedlongbase=S3C2410_GPIO_BASE(pin);/*获得端口的组基地址*/
unsignedlongshift=1;
unsignedlongmask=0x03;/*通常用配置寄存器的两位表示一个端口*/
unsignedlongcon;
unsignedlongflags;
if(pinS3C2410_GPIO_BANKB)
{
shift=0;
mask=0x01;/*在GPA端口中用配置寄存器的一位表示一个端口*/
}
mask=(S3C2410_GPIO_OFFSET(pin)shift);
local_irq_save(flags);/*保存现场,保证下面一段是原子操作*/
con=__raw_readl(base+0x00);
con=~mask;
con|=function;
__raw_writel(con,base+0x00);/*向配置寄存器写入新配置数据*/
local_irq_restore(flags);/*恢复现场*/
}
voids3c2410_gpio_pullup(unsignedintpin,unsignedintto)
{/*配置上拉功能*/
unsignedlongbase=S3C2410_GPIO_BASE(pin);/*获得端口的组基地址*/
unsignedlongoffs=S3C2410_GPIO_OFFSET(pin);/*获得端口的组内偏移地址*/
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);/*向上拉功能寄存器写入新配置数据*/
local_irq_restore(flags);
}
voids3c2410_gpio_setpin(unsignedintpin,unsignedintto)
{/*向某个管脚进行输出*/
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);/*向数据寄存器写入新数据*/
local_irq_restore(flags);
}
intgpio_open(structinode*inode,structfile*filp)
{/*open操作函数:进行寄存器配置*/
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操作函数:没有实际功能*/
return0;
}
ssize_tgpio_write(structfile*file,constchar__user*buff,
size_tcount,loff_t*offp)
{/*write操作函数:没有实际功能*/
return0;
}
intswitch_gpio(unsignedintpin,unsignedintswt)
{/*向5个端口中的一个输出ON/OFF值*/
if(!((pin=S3C2410_GPF7)(pin>=S3C2410_GPF4))
(pin!=S3C2410_GPB0))
{
printk(Unsupportedpin);
return1;
}
s3c2410_gpio_setpin(pin,swt);
return0;
}
staticintgpio_ioctl(structinode*inode,structfile*file,
unsignedintcmd,unsignedlongarg)
{/*ioctl函数接口:主要接口的实现。对5个GPIO设备进行控制(发亮或发声)*/
unsignedintswt=(unsignedint)arg;
switch(cmd)
{
caseLED_D09_SWT:
{
switch_gpio(S3C2410_GPF7,swt);
}
break;
caseLED_D10_SWT:
{
switch_gpio(S3C2410_GPF6,swt);
}
break;
caseLED_D11_SWT:
{
switch_gpio(S3C2410_GPF5,swt);
}
break;
caseLED_D12_SWT:
{
switch_gpio(S3C2410_GPF4,swt);
}
break;
caseBEEP_SWT:
{
switch_gpio(S3C2410_GPB0,swt);
break;
}
default:
{
printk(Unsupportedcommand\n);
break;
}
}
return0;
}
staticintgpio_release(structinode*node,structfile*file)
{/*release操作函数,熄灭所有灯和关闭蜂鸣器*/
switch_gpio(S3C2410_GPB0,BEEP_SWT_OFF);
switch_gpio(S3C2410_GPF4,LED_SWT_OFF);
switch_gpio(S3C2410_GPF5,LED_SWT_OFF);
switch_gpio(S3C2410_GPF6,LED_SWT_OFF);
switch_gpio(S3C2410_GPF7,LED_SWT_OFF);
return0;
}
staticvoidgpio_setup_cdev(structcdev*dev,intminor,
structfile_operations*fops)
{/*字符设备的创建和注册*/
interr,devno=MKDEV(major,minor);
cdev_init(dev,fops);
dev->owner=THIS_MODULE;
dev->ops=fops;
err=cdev_add(dev,devno,1);
if(err)
{
printk(KERN_NOTICEError%daddinggpio%d,err,minor);
}
}
staticstructfile_operationsgpio_fops=
{/*gpio设备的file_operations结构定义*/
.own
嵌入式Linux 设备驱动 GPIO驱动程序 操作系统 相关文章:
- 嵌入式Linux技术在工业控制网络中的应用(10-30)
- 基于嵌入式Linux的组态软件实时数据库的设计(02-01)
- 基于ARM+DSP的嵌入式Linux数控系统设计(11-18)
- 基于嵌入式Linux的细胞特征提取算法设计(11-19)
- 基于S3C2410的嵌入式Linux系统构建(03-02)
- 嵌入式Linux网络编程之:网络基础编程(08-13)