【linux】 linux gpio操作
欢迎转载,转载时需保留作者信息,谢谢。
博客园地址:http://www.cnblogs.com/embedded-tzp
Csdn博客地址:http://blog.csdn.net/xiayulewa
是平时自己word离线做笔记的,当发在网上才发现写的太宏观,不怎么容易看懂,今后做笔记会注意多贴代码。
1. GPIO
1.1. 地址映射

如上所述:
#define S3C24XX_VA_GPIO ((S3C24XX_PA_GPIO - S3C24XX_PA_UART) + S3C24XX_VA_UART)
因为UART的物理地址和虚拟地址映射确定了,所以其它寄存器如GPIO映射关系也可以确定了
static struct map_desc s3c_iodesc[] __initdata = {
IODESC_ENT(GPIO),
IODESC_ENT(IRQ),
IODESC_ENT(MEMCTRL),
IODESC_ENT(UART)
};
#define IODESC_ENT(x) { (unsigned long)S3C24XX_VA_##x, __phys_to_pfn(S3C24XX_PA_##x), S3C24XX_SZ_##x, MT_DEVICE }
#define __phys_to_pfn(paddr) ((unsigned long)((paddr) >> PAGE_SHIFT))
#define __pfn_to_phys(pfn) ((phys_addr_t)(pfn) << PAGE_SHIFT)
#define PAGE_SHIFT 12
根据上述定义:gpio虚拟地址分配(S3C24XX_VA_GPIO)流程:MACHINE_START中mini2440_map_io→s3c24xx_init_io →iotable_init(s3c_iodesc, ARRAY_SIZE(s3c_iodesc));
1.2. 数据结构

上图可以看出,根据gpio_desc数组,还可以通过container_of还原出struct samsung_gpio_chip, 该结构体里面的base成员即为虚拟地址,在s3c24xx_gpiolib_add_chips中被赋值。最右边的.chip成员还有struct gpio_desc *desc;成员,其被赋值为chip->desc = &gpio_desc[chip->base]; 因此,通过gpio号可以索引到数组gpio_desc的成员,然后索引到.chip,进而索引所有gpio对象。
主要结构体:Gpiolib.c (src\drivers\gpio): struct gpio_desc gpio_desc[ARCH_NR_GPIOS]; // 每一个gpio管脚对应一个gpio_desc,gpio_desc的索引为linux虚拟的。
gpio_desc初始化:Gpio-samsung.c (src\drivers\gpio):core_initcall(samsung_gpiolib_init);(见MACHINE_START处理)
→ s3c24xx_gpiolib_add_chips(s3c24xx_gpios, ARRAY_SIZE(s3c24xx_gpios), S3C24XX_VA_GPIO)→ gpiochip_add, 所以最后gpio_desc内容与s3c24xx_gpios相关,同时在该函数中有chip->base = base + ((i) * 0x10); 对base赋值为虚拟地址,根据第一节gpio的虚拟地址和物理地址建立的映射,便可访问到物理地址。
struct samsung_gpio_chip s3c24xx_gpios[] = {
#ifdef CONFIG_PLAT_S3C24XX
{
.config = &s3c24xx_gpiocfg_banka,
.chip = {
.base = S3C2410_GPA(0),
.owner = THIS_MODULE,
.label = "GPIOA",
.ngpio = 24,
.direction_input = s3c24xx_gpiolib_banka_input,
.direction_output = s3c24xx_gpiolib_banka_output,
},
}, {
.chip = {
.base = S3C2410_GPB(0),
.owner = THIS_MODULE,
.label = "GPIOB",
.ngpio = 16,
},
},
.........................................
};
以gpio_direction_input为例说明 gpio驱动:
gpio_direction_input(unsigned gpio) → gpiod_direction_input(gpio_to_desc(gpio)); → chip = desc->chip; chip->direction_input(chip, offset); 在上述gpio_desc初始化或者s3c24xx_gpios结构体变量定义中,该函数被赋值,以samsung_gpiolib_2bit_input为例,最终执行
struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
void __iomem *base = ourchip->base; // base 为该gpio寄存器的虚拟地址。
....
con = __raw_readl(base + 0x00); //操纵实际寄存器
....
chip->direction_input,direction_output, get, set在s3c24xx_gpiolib_add_chips中被赋值。
gpio_direction_output→ Chip->direction_output 进行实际寄存器操纵。
1.3. 函数集合
gpio_request
gpio_free
gpio_get_direction
gpio_direction_input
gpio_direction_output
gpio_set_value
gpio_get_value
gpio_set_debounce
gpio_to_irq
gpiolib_dbg_show
1.4. 实例
根据上述讨论,通过gpio号可以索引到gpio所有相关对象(数据和函数),如S3C2410_GPA(0)
gpio_request(S3C2410_GPA(0), "KEY_UP");
gpio_direction_input(S3C2410_GPA(0)); /*2.配置为输入*/
【linux】 linux gpio操作的更多相关文章
- linux 标准 GPIO 操作
Linux 提供了GPIO 操作的 API,具体初始化及注册函数在 driver/gpio/lib_gpio.c 中实现. #include int gpio_request(unsigne ...
- Linux内核 GPIO操作部分API
内核中关于GPIO的操作API主要集中在<linux/of_gpio.h>和<linux/gpio.h>中,前者主要是GPIO直接与设备树相关的操作,在Linux 设备树操作A ...
- Linux应用层直接操作GPIO
Linux应用层直接操作GPIO 在一个老手的指导下,应用层可以直接操作GPIO,具体指设置GPIO的输入输出以及输出电平高或者低.这个大大地提高了灵活性,官方的文档有GPIO Sysfs Inter ...
- linux下GPIO的用户层操作(sysfs)
linux的GPIO通过sysfs为用户提供服务,下面是linux kernel里的说明文档,学习一下. GPIO Sysfs Interface for Userspace ============ ...
- Linux下GPIO驱动(三) ----gpio_desc()的分析
上篇最后提出的疑问是结构体gpio_chip中的成员函数set等是怎么实现的,在回答之前先介绍下gpio_desc这个结构体. 如上图所示,右上方部分为GPIO驱动对其它驱动提供的GPIO操作接口,其 ...
- 调试exynos4412—ARM嵌入式Linux—LEDS/GPIO驱动之二
/** ****************************************************************************** * @author 暴走的小 ...
- 调试exynos4412—ARM嵌入式Linux—LEDS/GPIO驱动之一
/** ****************************************************************************** * @author 暴走的小 ...
- 调试exynos4412—ARM嵌入式Linux—LEDS/GPIO驱动之三
/** ****************************************************************************** * @author 暴走的小 ...
- Android(Linux)控制GPIO方法二
前文<Android(Linux)控制GPIO的方法及实时性分析>主要使用Linux shell命令控制GPIO,该方法可在调试过程中快速确定GPIO硬件是否有问题,即对应的GPIO是否受 ...
- Linux 图形化操作
//Linux图形化操作 #include <stdio.h> #include <stdlib.h> #include <string.h> #include & ...
随机推荐
- Android应用开发基础篇(12)-----Socket通信
链接地址:http://www.cnblogs.com/lknlfy/archive/2012/03/03/2378669.html 一.概述 网络通信无论在手机还是其他设备上都应用得非常广泛,因此掌 ...
- VC++ 编译过程
一 前言 一开始编译C++代码的时候可能会对编译的错误觉得很难理解,搞不清楚究竟是哪里错了.了解编译过程,能够更好的处理编译错误. 二 名词解释 编译单元:当一个c或cpp文件在编译时,预处理器首先递 ...
- 微信公众号token验证失败的一些总结
这几天准备弄一个微信公众号,在进行服务器配置的时候出现总是出现token验证失败的报错. 实际上,这个问题很好解决.既然微信平台没有给我们很明确的报错提示,那么我们就可以通过跟踪获取到的请求参数进行分 ...
- java源码解析——Stack类
在java中,Stack类继承了Vector类.Vector类和我们经常使用的ArrayList是类似的,底层也是使用了数组来实现,只不过Vector是线程安全的.因此可以知道Stack也是线程安全的 ...
- 使用CarrierWave上传图片时,多版本文件名的统一
第一次使用CarrierWavewe做上传,不能不说,虽然Rails已经把上传变得超简单了,而CarrierWave则是把上传变成了一种享受,特别是做图片上传,现在这年代,图片展示平台已经不仅仅是电脑 ...
- Qt的“undefined reference to `vtable for”错误解决(手动解决,加深理解)
使用QT编程时,当用户自定义了一个类,只要类中使用了信号或槽. Code::Blocks编译就会报错(undefined reference to `vtable for). Google上有很多这个 ...
- BZOJ 2463 谁能赢呢? (博弈论)
题解:简单博弈论 #include <cstdio> int main(){ int n; while(scanf("%d",&n),n!=0) if (n&a ...
- HDU 1997 汉诺塔VII
题解参考博客: http://blog.csdn.net/hjd_love_zzt/article/details/9897281 #include <cstdio> ],yes; int ...
- struts2自己定义类型转换器
1.1. struts2自己定义类型转换器 1) 自定类型转换类,继承DefaultTypeConverter类 package com.morris.ticket.conversio ...
- sqlite性能简单測试
主要測试sqlite在大数据量下的插入及查询性能: 測试环境:Centos6.4 1G内存 单核 数据量 大小 索引字段检索(耗时) 非索引字段检索(耗时) 总插入时间 10W 19M 0.001 ...