嵌入式Linux设备驱动开发之:GPIO驱动程序实例
11.3GPIO驱动程序实例
11.3.1GPIO工作原理
FS2410开发板的S3C2410处理器具有117个多功能通用I/O(GPIO)端口管脚,包括GPIO8个端口组,分别为GPA(23个输出端口)、GPB(11个输入/输出端口)、GPC(16个输入/输出端口)、GPD(16个输入/输出端口)、GPE(16个输入/输出端口)、GPF(8个输入/输出端口)、GPH(11个输入/输出端口)。根据各种系统设计的需求,通过软件方法可以将这些端口配置成具有相应功能(例如:外部中断或数据总线)的端口。
为了控制这些端口,S3C2410处理器为每个端口组分别提供几种相应的控制寄存器。其中最常用的有端口配置寄存器(GPACON~GPHCON)和端口数据寄存器(GPADAT~GPHDAT)。因为大部分I/O管脚可以提供多种功能,通过配置寄存器(PnCON)设定每个管脚用于何种目的。数据寄存器的每位将对应于某个管脚上的输入或输出。所以通过对数据寄存器(PnDAT)的位读写,可以进行对每个端口的输入或输出。
在此主要以发光二极管(LED)和蜂鸣器为例,讨论GPIO设备的驱动程序。它们的硬件驱动电路的原理图如图11.4所示。
图11.4LED(左)和蜂鸣器(右)的驱动电路原理图
在图11.4中,可知使用S3C2410处理器的通用I/O口GPF4、GPF5、GPF6和GPF7分别直接驱动LEDD12、D11、D10以及D9,而使用GPB0端口驱动蜂鸣器。4个LED分别在对应端口(GPF4~GPF7)为低电平时发亮,而蜂鸣器在GPB0为高电平时发声。这5个端口的数据流方向均为输出。
在表11.15中,详细描述了GPF的主要控制寄存器。GPB的相关寄存器的描述与此类似,具体可以参考S3C2410处理器数据手册。
表11.15 GPF端口(GPF0-GPF7)的主要控制寄存器
寄存器 | 地址 | R/W | 功能 | 初始值 | |
GPFCON | 0x56000050 | R/W | 配置GPF端口组 | 0x0 | |
GPFDAT | 0x56000054 | R/W | GPF端口的数据寄存器 | 未定义 | |
GPFUP | 0x56000058 | R/W | GPF端口的取消上拉寄存器 | 0x0 | |
GPFCON | 位 | 描述 | |||
GPF7 | [15:14] | 00=输入01=输出10=EINT711=保留 | |||
GPF6 | [13:12] | 00=输入01=输出10=EINT611=保留 | |||
GPF5 | [11:10] | 00=输入01=输出10=EINT511=保留 | |||
GPF4 | [9:8] | 00=输入01=输出10=EINT411=保留 | |||
GPF3 | [7:6] | 00=输入01=输出10=EINT311=保留 | |||
GPF2 | [5:4] | 00=输入01=输出10=EINT211=保留 | |||
GPF1 | [3:2] | 00=输入01=输出10=EINT111=保留 | |||
GPF0 | [1:0] | 00=输入01=输出10=EINT011=保留 |
GPFDAT | 位 | 描述 |
GPF[7:0] | [7:0] | 每位对应于相应的端口,若端口用于输入,则可以通过相应的位读取数据;若端口用于输出,则可以通过相应的位输出数据;若端口用于其他功能,则其值无法确定。 |
GPFUP | 位 | 描述 |
GPF[7:0] | [7:0] | 0:向相应端口管脚赋予上拉(pull-up)功能 1:取消上拉功能 |
为了驱动LED和蜂鸣器,首先通过端口配置寄存器将5个相应寄存器配置为输出模式。然后通过对端口数据寄存器的写操作,实现对每个GPIO设备的控制(发亮或发声)。在下一个小节中介绍的驱动程序中,s3c2410_gpio_cfgpin()函数和s3c2410_gpio_pullup()函数将进行对某个端口的配置,而s3c2410_gpio_setpin()函数实现向数据寄存器的某个端口的输出。
11.3.2GPIO驱动程序
GPIO驱动程序代码如下所示:
/*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);/*以参数的方式可以指定设备的主
嵌入式Linux 设备驱动 GPIO驱动程序 操作系统 相关文章:
- 嵌入式Linux技术在工业控制网络中的应用(10-30)
- 基于嵌入式Linux的组态软件实时数据库的设计(02-01)
- 基于ARM+DSP的嵌入式Linux数控系统设计(11-18)
- 基于嵌入式Linux的细胞特征提取算法设计(11-19)
- 基于S3C2410的嵌入式Linux系统构建(03-02)
- 嵌入式Linux网络编程之:网络基础编程(08-13)