新闻中心

EEPW首页>嵌入式系统>设计应用> 嵌入式Linux设备驱动开发之:GPIO驱动程序实例

嵌入式Linux设备驱动开发之:GPIO驱动程序实例

作者: 时间:2013-09-13 来源:网络 收藏

本文引用地址://m.amcfsurvey.com/article/257110.htm

11.3.2

代码如下所示:

/*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;/*采用字符设备号的动态分配*/

module_param(major,int,0);/*以参数的方式可以指定设备的主设备号*/

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;

}

linux操作系统文章专题:linux操作系统详解(linux不再难懂)

linux相关文章:linux教程


蜂鸣器相关文章:蜂鸣器原理


评论


相关推荐

技术专区

关闭