学习嵌入式-迅为4412开发板的GPIO是怎么操作的?

Exynos4412所有的GPIO都有固定的地址,为了方便操作这些GPIO,Linux内核在gpio-exynos4.h里面定义了一些GPIO的宏

详情了解:http://topeetboard.com 更多了解:https://arm-board.taobao.com

例如: 
#define EXYNOS4_GPA0(_nr) (EXYNOS4_GPIO_A0_START + (_nr)) 
#define EXYNOS4_GPA1(_nr) (EXYNOS4_GPIO_A1_START + (_nr)) 
#define EXYNOS4_GPB(_nr) (EXYNOS4_GPIO_B_START + (_nr)) 
..................................... 
#define EXYNOS4_GPY5(_nr) (EXYNOS4_GPIO_Y5_START + (_nr)) 
#define EXYNOS4_GPY6(_nr) (EXYNOS4_GPIO_Y6_START + (_nr)) 
#define EXYNOS4_GPZ(_nr) (EXYNOS4_GPIO_Z_START + (_nr)) 
这些宏就是把每个GPIO的地址做了一下封装,它的好处就是方便我们使用并且根据宏的名字就能直观的知道是在操作哪个GPIO。 
Linux内核中关于GPIO的驱动在driver/gpio/gpio-exynos4.c文件里面,在这个文件中GPIO驱动初始化入口函数是exynos4_gpiolib_init,因为这个文件同时也支持4210的GPIO,所以开始先初始化了一些通用的GPIO(4412和4210都有的GPIO),代码如下: 
chip = exynos4_gpio_common_4bit; 
nr_chips = ARRAY_SIZE(exynos4_gpio_common_4bit); 
for (i = 0; i < nr_chips; i++, chip++) { 
if (chip->config == NULL) 
chip->config = &gpio_cfg; 
if (chip->base == NULL) 
pr_err("No allocation of base address for [common gpio]"); 

samsung_gpiolib_add_4bit_chips(exynos4_gpio_common_4bit, nr_chips); 
变量exynos4_gpio_common_4bit是一个数组,定义了一些通用的GPIO,nr_chips是记录的exynos4_gpio_common_4bit数组里面元素个数。 
首先使用for循环遍历exynos4_gpio_common_4bit所有的元素,为每个元素的config结构赋值: 
if (chip->config == NULL) 
chip->config = &gpio_cfg; 
gpio_cfg是类型为s3c_gpio_cfg的结构体,这个结构体的定义如下: 
struct s3c_gpio_cfg { 
unsigned int cfg_eint; 
s3c_gpio_pull_t (*get_pull)(struct s3c_gpio_chip *chip, unsigned offs); 
int (*set_pull)(struct s3c_gpio_chip *chip, unsigned offs, 
s3c_gpio_pull_t pull); 
unsigned (*get_config)(struct s3c_gpio_chip *chip, unsigned offs); 
int (*set_config)(struct s3c_gpio_chip *chip, unsigned offs, 
unsigned config); 
}; 
通过上面的代码我们可以看到这个结构体里主要是一些函数指针,get_pull是获取GPIO的上拉状态,set_pull是设置GPIO上拉或下拉的,set_config是设置GPIO的工作模式,例如:输出/输入/其他功能。下面我们来看看gpio_cfg变量的定义,如下: 
static struct s3c_gpio_cfg gpio_cfg = { 
.set_config = s3c_gpio_setcfg_s3c64xx_4bit, 
.set_pull = s3c_gpio_setpull_exynos4, 
.get_pull = s3c_gpio_getpull_exynos4, 
}; 
通过上面的代码,可以看到分别对gpio_cfg结构的三个函数指针赋值,这三个函数的定义是在gpio-config.c里面实现的,这个文件在内核源码arch/arm/plat-samsung目录下,这三个函数的作用就是根据传进来的参数,配置GPIO相应的寄存器,从而实现对GPIO的操作。 
然后我们回到gpio-exynos4.c,接着看下面的代码,完成了exynos4_gpio_common_4bit中每个元素的config结构赋值后,接着会调用函数samsung_gpiolib_add_4bit_chips(exynos4_gpio_common_4bit, 
nr_chips)来向系统注册GPIO结构体。代码如下: 
void __init samsung_gpiolib_add_4bit_chips(struct s3c_gpio_chip *chip, 
int nr_chips) 

for (; nr_chips > 0; nr_chips--, chip++) { 
samsung_gpiolib_add_4bit(chip); 
s3c_gpiolib_add(chip); 


上面的代码主要有两个函数组成分别是samsung_gpiolib_add_4bit(chip)和s3c_gpiolib_add(chip),首先我们来看下samsung_gpiolib_add_4bit(chip)函数的实现: 
void __init samsung_gpiolib_add_4bit(struct s3c_gpio_chip *chip) 

chip->chip.direction_input = samsung_gpiolib_4bit_input; 
chip->chip.direction_output = samsung_gpiolib_4bit_output; 
chip->pm = __gpio_pm(&s3c_gpio_pm_4bit); 

这个函数也是为函数指针赋值,direction_input是设置GPIO为输入模式,direction_output是设置GPIO为输出。 
s3c_gpiolib_add(chip)函数主要作用是给一些函数指针赋值,然后根据传进来的参数把对应的GPIO的信息保存到gpio_desc结构里,gpio_desc是内核里面定义的一个全局变量,用来保存每个GPIO的信息。至此GPIO的驱动初始化就完成了,其他它主要完成的功能就是为每个GPIO的结构体里面的函数指针赋值,最后把每个GPIO结构信息保存到全局变量gpio_desc里面。
上面已经完成了一些通用的GPIO驱动的初始化,我们在回到gpio-exynos4.c,下面是根据CPU的型号初始化CPU特定的GPIO了,代码如下: 
/* Only 4210 GPIO part */ 
if (soc_is_exynos4210()) { 
chip = exynos4210_gpio_4bit; 
nr_chips = ARRAY_SIZE(exynos4210_gpio_4bit); 
for (i = 0; i < nr_chips; i++, chip++) { 
if (chip->config == NULL) 
chip->config = &gpio_cfg; 
if (chip->base == NULL) 
pr_err("No allocation of base address [4210 gpio]"); 

samsung_gpiolib_add_4bit_chips(exynos4210_gpio_4bit, nr_chips); 
} else { 
/* Only 4212/4412 GPIO part */ 
chip = exynos4212_gpio_4bit; 
nr_chips = ARRAY_SIZE(exynos4212_gpio_4bit); 
for (i = 0; i < nr_chips; i++, chip++) { 
if (chip->config == NULL) 
chip->config = &gpio_cfg; 
if (chip->base == NULL) 
pr_err("No allocation of base address [4212 gpio]"); 

samsung_gpiolib_add_4bit_chips(exynos4212_gpio_4bit, nr_chips); 

通过看上面的代码,初始化过程与前面介绍的初始化通用GPIO原理是一样的,这里我们不在详细介绍。对所有GPIO的初始化完成以后内核中的其他驱动模块就可以方便的使用我们注册到gpio_desc里面的GPIO了。内核提供了几个全局函数来操作这些GPIO: 
int gpio_request(unsigned gpio, const char *label) 
void gpio_free(unsigned gpio) 
int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull) 
int s3c_gpio_cfgpin(unsigned int pin, unsigned int config) 
int gpio_direction_input(unsigned gpio) 
int gpio_direction_output(unsigned gpio, int value) 
gpio_request函数是申请GPIO操作,根据传递进来的参数gpio,会去全局变量gpio_desc里面找到对应的GPIO结构,判断desc的标志位flag有没有被设置FLAG_REQUESTED,如果有设置说明其他地方在使用这个GPIO,程序返回-EBUSY错误,如果没有设置就设置flags的标记为FLAG_REQUESTED。 
gpio_free函数是释放GPIO操作,根据传递进来的参数,在gpio_desc全局变量找到对应的GPIO结构,清除掉desc的flag标志变量的FLAG_REQUESTED位。 
s3c_gpio_setpull函数是设置GPIO的上拉或下拉的,变量pull的取值范围如下定义: 
#define S3C_GPIO_PULL_NONE ((__force s3c_gpio_pull_t)0x00) 
#define S3C_GPIO_PULL_DOWN ((__force s3c_gpio_pull_t)0x01) 
#define S3C_GPIO_PULL_UP ((__force s3c_gpio_pull_t)0x02) 
S3C_GPIO_PULL_NONE是悬空 
S3C_GPIO_PULL_DOWN是下拉 
S3C_GPIO_PULL_UP是上拉 
s3c_gpio_cfgpin函数是设置GPIO的功能:输入/输出/其他功能,第二个参数config取值范围如下: 
#define S3C_GPIO_INPUT (S3C_GPIO_SPECIAL(0)) 
#define S3C_GPIO_OUTPUT (S3C_GPIO_SPECIAL(1)) 
#define S3C_GPIO_SFN(x) (S3C_GPIO_SPECIAL(x)) 
S3C_GPIO_INPUT是输入模式,S3C_GPIO_OUTPUT是输出模式,S3C_GPIO_SFN(x)是其他模式,例如中断模式等。 
gpio_direction_input函数设置GPIO是输入功能。 
gpio_direction_output设置GPIO输出,第二个参数value取值0或1,0代表输出低电平,1代表输出高电平。 
下面我们来看几个GPIO操作的例子: 
if (gpio_request(EXYNOS4_GPX3(3), "MPU6050 INT")) 
printk(KERN_WARNING "MPU6050 INT(GPX3.3) Port request error!!!\n"); 
else{ 
s3c_gpio_setpull(EXYNOS4_GPX3(3), S3C_GPIO_PULL_NONE); 
s3c_gpio_cfgpin(EXYNOS4_GPX3(3), S3C_GPIO_SFN(0)); 
gpio_direction_input(EXYNOS4_GPX3(3)); 
gpio_free(EXYNOS4_GPX3(3)); 

上面的代码是设置GPIO引脚GPX3_3为输入模式,悬空。 
err = gpio_request_one(EXYNOS4_GPX0(0), GPIOF_IN, "mcp251x_INT"); 
if (err) { 
printk(KERN_ERR "failed to request mcp251x_INT\n"); 
return -1; 

s3c_gpio_cfgpin(EXYNOS4_GPX0(0), S3C_GPIO_SFN(0xf)); 
s3c_gpio_setpull(EXYNOS4_GPX0(0), S3C_GPIO_PULL_NONE); 
gpio_free(EXYNOS4_GPX0(0)); 
上面的代码设置GPIO引脚GPX0_0为中断模式。 
if(gpio_request(EXYNOS4_GPK1(0), "GPK1_0")) 

printk(KERN_ERR "failed to request GPK1_0 for " 
"USI control\n"); 
return err; 

gpio_direction_output(EXYNOS4_GPK1(0), 1); 
s3c_gpio_cfgpin(EXYNOS4_GPK1(0), S3C_GPIO_OUTPUT); 
gpio_free(EXYNOS4_GPK1(0)); 
上面的代码设置GPIO引脚GPK1_0为输出模式,并且输出高电平。 
iTOP-4412的GPIO驱动就介绍到这里,大家有兴趣的话可以去内核里面详细的查看一下整个驱动的详细实现。

时间: 2024-10-11 10:40:57

学习嵌入式-迅为4412开发板的GPIO是怎么操作的?的相关文章

Linux系统基础知识-嵌入式迅为4412开发板学习笔记

1. 什么是Linux系统编程 详情了解:http://topeetboard.com  更多了解:https://arm-board.taobao.com Linux系统编程分为三个部分:系统调用.C库和C编译器. 系统调用系统编程的基础是系统调用,也结束于系统调用.在带有操作系统的嵌入式开发中,需要从操作系统申请一些服务和资源,从用户空间向内核发起的一些函数调用.系统调用包括对文件的读写.进程的控制等等.在Linux中,系统的实现少于其它内核.例如在Windows下有几千个系统调用,但是在L

嵌入式开发板 迅为4412开发板 初学ARM开发板首选!提供教学视频!

选择迅为4412开发板无论是学习ARM技术还是开发产品都无须担心,迅为4412开发板提供了丰富的例程源码实例和视频,只需要你有C语言基础,就可以快速学习嵌入式高端技术开发! 搭载三星Exynos四核处理器,配备1GB内存,4GB固态硬盘EMMC存储,兼具快速读取与超大容量,纵使海量思考也能及时处理. 详情了解: http://topeetboard.com   更多了解:https://arm-board.taobao.com

嵌入式开发-迅为4412开发板QT鼠标和触摸的问题解决方案

迅为4412开发板-QT鼠标和触摸的问题解决方案: 一. 背景 在使用迅为提供的QT4.7的时候,鼠标可以正常使用,有触摸但是触摸会出现问题.尤其是在左右滑动qt界面的时候,总是会出现往左滑动,画面急速往右走,然而往右滑动,画面急速的往左走. 在使用迅为提供的Qtopia4的时候,只能用触摸不能用鼠标. 二.解决办法 ① QT4.7系统 打开/bin/qt4 找到这句话: export QWS_MOUSE_PROTO='MouseMan:/dev/input/mice Tslib:/dev/in

迅为4412开发板学习之win8下基础软件的安装和学习

平台:迅为4412开发板 详情了解:http://topeetboard.com更多了解:https://arm-board.taobao.com 一.超级终端的安装和使用 1 关闭 win8 的自动更新 如果用户使用的 PC 机没有串口,就需要用到 USB转串口驱动.我们给用户配套的硬件是 PL 2303, 提供的驱动也是 PL2303. 如果用户使用其它的设备, 那么所需要的驱动就不一样了. 本来驱动安装后直接使用,但是在 win8 下有自动更新,默认自动更新的,它会更新到最 新的版本,最新

新手如何学习嵌入式开发板-迅为4412开发板

网站:http://www.topeetboard.com Q Q:2551456065 产品优势: 1. 涵盖当在嵌入式技术热点:Linux,Android,QT,Ubuntu系统 2. 专为iTOP-4412量身打造,手把手全视频讲义,让学习嵌入式ARM开发像单片机一样简单!3. 完善的售后支持:提供论坛.认证QQ. 当前ARM处理器参数对比: 4412开发板介绍: 1. iTOP-4412精英版:搭载三星Exynos四核处理器,配备1GB内存,4GB固态硬盘EMMC存储,兼具快速读取与超大

[学习开发板怎么选]迅为4412开发板帮你入门嵌入式

丰富选配模块 入门视频教程(购买后提供完整版高清教程)部分视频观看地址: [视频教程]iTOP-4412开发板之学习方法--致初学者 http://v.youku.com/v_show/id_XNzQ5MDA4NzM2.html [视频教程]三星Exynos 4412处理器开发要点 http://v.youku.com/v_show/id_XNjIwODA0MTY4.html [视频教程]iTOP-4412开发板之如何扩展不同型号LCD屏 http://v.youku.com/v_show/id

迅为4412开发板平台-嵌入式开源平台

转载:http://www.topeetboard.com/ 4412核心板介绍 两种封装形式:Exynos4412有两种封装形式, 其中POP封装的芯片内含1GB内存, 所以不需要外扩DDR, 可大大节省 PCB 面积,功耗控制方面也更好,多用于手持设备当中: SCP 封装优点是内存扩展更灵活,生产工艺相对更容易控制. 4412POP 封装 长宽:5CM * 6CM,高度 1.5MM,320 个引脚(80 * 4): 板载 1GB 内存,电源管理: 和底板装配的时候注意“防呆箭头”. 4412

【学习/研发】嵌入式Linux/Android开发有它就够了——迅为4412开发板

网站:http://www.topeetboard.com 光盘资料+网盘资料+配套视频+售后支持,助您加速学习研发的进程 产品介绍 iTOP-Exynos4412开发板采用 Exynos4412的主芯片,具有更高的主频和更丰富外设,配置 2GB 双通道 DDR3的内存及 16GB 存储,具有稳定性强.可靠性高,能适用于对性能和处理能力有更高要求的嵌入式系统应用场合. iTOP-Exynos4412开发板内置有无线 WIFI 模块.Bluetooth.GPS.Camera.3G等模组,支持 HD

嵌入式学习-4412开发板学习-迅为4412开发板can测试技术分享

迅为CAN 测试 详情了解:http://topeetboard.com  更多了解:https://arm-board.taobao.com 本文档适用的范围 ① 硬件平台 :4412精英版以及全能版开发板.(4418/6818开发板以及imx6q开发板测试的道理是一样的可能细节有些不同,在这里我没有做实验,感兴趣的可以按照这个文档测试一下) ②软件平台 :Android4.0.Android4.4.QT.ubuntu 测试程序: 这个在网盘上有提供,另外我也会上传 一.硬件连接 can 通信