Linux内核文档:GPIO接口

合集下载

linux中gpio的判断方式

linux中gpio的判断方式

linux中gpio的判断方式Linux中的GPIO(General Purpose Input/Output)是一种通用输入/输出接口,允许用户通过控制电平来与外部电子设备进行通信。

在本文中,我们将探讨如何通过Linux中的GPIO判断外部设备的状态。

GPIO的判断方式主要通过读取相应的GPIO引脚的电平状态来实现。

在Linux中,可以通过/sys/class/gpio目录下的文件进行GPIO的控制和读取。

首先,我们需要将GPIO引脚导出为可控制的文件,可以通过以下命令完成:```echo [GPIO编号] > /sys/class/gpio/export```其中,[GPIO编号]代表需要操作的GPIO引脚的编号。

导出后,系统会在/sys/class/gpio目录下生成相应的文件夹,包含了与该GPIO 引脚相关的文件。

接下来,我们可以通过读取/sys/class/gpio/gpio[GPIO编号]/value 文件来获取GPIO引脚的电平状态。

该文件中的内容为0或1,分别表示低电平和高电平。

我们可以使用类似如下的命令来读取GPIO 引脚的状态:```cat /sys/class/gpio/gpio[GPIO编号]/value```通过读取该文件的内容,我们可以判断GPIO引脚的电平状态,并根据需要进行相应的处理。

例如,可以根据GPIO引脚的状态来控制外部设备的开关,或者根据不同的状态执行不同的程序。

在使用完GPIO引脚后,为了释放相关资源,我们需要将其取消导出。

可以通过以下命令完成:```echo [GPIO编号] > /sys/class/gpio/unexport```总结一下,通过读取/sys/class/gpio/gpio[GPIO编号]/value文件,我们可以方便地判断Linux中的GPIO引脚的电平状态,进而实现与外部设备的通信和控制。

这种方式简单、灵活,并且可以与其他Linux命令和脚本结合使用,为嵌入式系统开发和物联网应用提供了便利。

linux gpio编号

linux gpio编号

linux gpio 编号
在 Linux 系统中,GPIO(通用输入输出)引脚使用不同的编号 方式,具体取决于所使用的硬件平台和驱动程序。以下是常见的两 种 GPIO 编号方式:
1. 基于内核编号(Kernel nபைடு நூலகம்mbering):这是最常用的 GPIO 编号 方式,在该方式下,每个 GPIO 引脚都有一个唯一的整数编号, 从 0 开始递增。可以通过查看 /sys/class/gpio 目录下的文 件 来 获 取 和 管 理 GPIO 引 脚 。 例 如 , GPIO0 的 文 件 路 径为 /sys/class/gpio/gpio0 。
2. 基于物理板编号(Board numbering):这种编号方式与硬件平 台的物理引脚布局直接对应。每个 GPIO 引脚都会被分配一个特 定的标识符,如"P9_12"或"GPIO1_28"等。可以通过查找对应的 文档或参考资料来获取特定硬件平台上的 GPIO 编号。
请注意,具体的 GPIO 编号方式可能因使用的硬件平台和操作系统版 本而异。在实际使用时,可以根据硬件平台和操作系统的要求选择适 合的 GPIO 编号方式,并参考相应的文档来确定正确的 GPIO 引脚编 号。

Linux中的gpio口使用方法

Linux中的gpio口使用方法

Linux中的gpio⼝使⽤⽅法Linux中的IO使⽤⽅法应该是新版本内核才有的⽅法。

请参考:./Documentation/gpio.txt⽂件提供的API:驱动需要包含 #include <linux/gpio.h>判断⼀个IO是否合法:int gpio_is_valid(int number);设置GPIO的⽅向,如果是输出同时设置电平:/* set as input or output, returning 0 or negative errno */int gpio_direction_input(unsigned gpio);int gpio_direction_output(unsigned gpio, int value);获取输⼊引脚的电平:/* GPIO INPUT: return zero or nonzero */int gpio_get_value(unsigned gpio);/* GPIO OUTPUT */void gpio_set_value(unsigned gpio, int value);int gpio_cansleep(unsigned gpio);To access such GPIOs, a different set of accessors is defined:/* GPIO INPUT: return zero or nonzero, might sleep */int gpio_get_value_cansleep(unsigned gpio);/* GPIO OUTPUT, might sleep */void gpio_set_value_cansleep(unsigned gpio, int value);获取⼀个GPIO并声明标签:/* request GPIO, returning 0 or negative errno.* non-null labels may be useful for diagnostics.*/int gpio_request(unsigned gpio, const char *label);/* release previously-claimed GPIO */void gpio_free(unsigned gpio);将GPIO映射为IRQ中断:/* map GPIO numbers to IRQ numbers */int gpio_to_irq(unsigned gpio);/* map IRQ numbers to GPIO numbers (avoid using this) */int irq_to_gpio(unsigned irq);设置GPIO IRQ中断类型:if (!sw->both_edges) {if (gpio_get_value(sw->gpio))set_irq_type(gpio_to_irq(sw->gpio), IRQ_TYPE_EDGE_FALLING);elseset_irq_type(gpio_to_irq(sw->gpio), IRQ_TYPE_EDGE_RISING);在驱动中使⽤延时函数mdelay,需要包含<linux/delay.h>⽂件。

linuxgpio口测试程序,gpio接口测试

linuxgpio口测试程序,gpio接口测试

linuxgpio⼝测试程序,gpio接⼝测试GPIO(General Purpose I/O Ports)意思为通⽤输⼊/输出端⼝,通俗地说,就是⼀些引脚,可以通过它们输出⾼低电平或者通过它们读⼊引脚的状态-是⾼电平或是低电平。

GPIO⼝⼀是个⽐较重要的概念,⽤户可以通过GPIO⼝和硬件进⾏数据交互(如UART),控制硬件⼯作(如LED、蜂鸣器等),读取硬件的⼯作状态信号(如中断信号)等。

GPIO⼝的使⽤⾮常⼴泛。

⼀、 设置硬件环境连接VS⼦板 从dm8168扩展出来的GPIO连接到了VS⼦板的J1接⼝⼆、配置编译linux内核1》 在linux-2.6.37-psp04.00.00.12/arch/arm/mach-omap2/ board-TI8168evm.c⽂件的558⾏添加TI816X_MUX(SC1_DATA, OMAP_MUX_MODE2),TI816X_MUX(SC0_DET, OMAP_MUX_MODE2),配置GP0[24] GP1[9]管脚为GPIO管脚2》 配置linux内核 使能Device Drivers –》 GPIO Support –》 /sys/class/gpio三、启动开发板四、创建GPIO节点echo 24 》 /sys/class/gpio/exportecho 41 》 /sys/class/gpio/export五、设置GPIO⽅向cd /sys/class/gpio/gpio24echo “out” 》 direcTIoncd /sys/class/gpio/gpio41echo “out” 》 direction六、改变GPIO值cd /sys/class/gpio/gpio24echo 1 》 valuecd /sys/class/gpio/gpio41echo 1 》 value使⽤万⽤表测量VS⼦板 –》JP1 –》1 或3管脚为⾼电平cd /sys/class/gpio/gpio24echo 0 》 valuecd /sys/class/gpio/gpio41echo 0 》 value使⽤万⽤表测量VS⼦板 –》JP1 –》1 或3管脚为低电平七、运⾏C测试程序运⾏gpio0-24-test 或gpio1-9-test测试例程,使⽤⽰波器可以看到频率为1HZ的⽅波⼀、Follow these steps for controlling the GPIO lines from sysfs entriesa. Export, which GPIO pin you want to control. Below steps are done with respect to GPIO30 (an example$ echo 30 》 /sys/class/gpio/exportb. Change the GPIO pin direction to in/out$ echo “out” 》 /sys/class/gpio/gpio30/direction$ echo “in” 》 /sys/class/gpio/gpio30/directionc. Changing the value$ echo 1 》 /sys/class/gpio/gpio30/value$ echo 0 》 /sys/class/gpio/gpio30/valued. Unexport the GPIO pin$ echo 30 》 /sys/class/gpio/unexportSysfs entries are created from 0 - 63 in case of DM816X because it has two GPIO banks 0 and 1.Note: GPIO‘s which are used already in the drivers can not be control from sysfs, unless untill driver export that particular pin.Run these commands for knowing what are the GPIO’s already requested in the drivers.$ mount -t debugfs debugfs /sys/kernel/debug$ cat /sys/kernel/debug/gpio。

Linux用户态设置GPIO控制

Linux用户态设置GPIO控制

Linux⽤户态设置GPIO控制Linux ⽤户态设置GPIO控制linux内核提供了⼀套在⽤户态配置GPIO的接⼝,在/sys/class/gpio/⽬录下可以发现其中包含有两个⽂件export、unexport和若⼲gpiochipN类型⽂件夹export⽤于将指定编号的引脚导出,作为GPIO使⽤unexport⽤于将导出的GPIO删除掉gpiochipN当前芯⽚中包含的GPIO控制器GPIO使⽤⽅法添加设备接⼝GPIO167输⼊:echo 167 > export可以发现,⽬录下出现了gpio167,如果执⾏命令后没有反应,表⽰当前的GPIO已经⽤作其他的功能,例如作为IIC的引脚等删除设备接⼝GPIO167输⼊:echo 167 > unexport可以发现当前导出的接⼝被删除控制设备接⼝GPIO167输⼊:echo 167 > unexportdirection设置输出还是输⼊模式设置为输⼊:echo “in” > direction设置为输出:echo “out” > directionvalue输出时,控制⾼低电平;输⼊时,获取⾼低电平⾼电平:echo 1 > value低电平:echo 0 > valueedge控制中断触发模式,引脚被配置为中断后可以使⽤poll()函数监听引脚⾮中断引脚: echo “none” > edge上升沿触发:echo “rising” > edge下降沿触发:echo “falling” > edge边沿触发:echo “both” > edgegpiochipN⽬录⽤来管理和控制⼀组gpio端⼝的控制器base和N相同,表⽰控制器管理的最⼩的端⼝编号。

lable诊断使⽤的标志(并不总是唯⼀的)ngpio控制器管理的gpio端⼝数量(端⼝范围是:N ~ N+ngpio-1)⽤户态使⽤gpio监听中断⽐如我想监听PA7上的电平变化(也就是边沿触发),那么应该先向“/sys/class/gpio/gpio7/direction”写⼊“in”,然后向“/sys/class/gpio/gpio7/edge”写⼊“both”,然后对”/sys/class/gpio/gpio7/value”执⾏select/poll操作。

linux内核的gpiolib详解

linux内核的gpiolib详解

linux内核的gpiolib详解#include <linux/init.h> // __init __exit#include <linux/module.h> // module_init module_exit#include <mach/regs-gpio.h>#include <mach/gpio-bank.h>#include <asm/io.h> //writel#include <mach/gpio.h>#include <linux/leds.h>#include <asm/string.h>#define X210_LED_OFF 1U#define X210_LED_ON 0Ustruct led_classdev cdev1;struct led_classdev cdev2;struct led_classdev cdev3;void s5pv210_led1_set(struct led_classdev *led_cdev,enum led_brightness brightness);void s5pv210_led2_set(struct led_classdev *led_cdev,enum led_brightness brightness);void s5pv210_led3_set(struct led_classdev *led_cdev,enum led_brightness brightness);static struct gpio x210_led_gpio[] ={{ S5PV210_GPJ0(3), GPIOF_OUT_INIT_HIGH, "LED1" }, /* default to OFF */{ S5PV210_GPJ0(4), GPIOF_OUT_INIT_HIGH, "LED2" }, /* default to OFF */{ S5PV210_GPJ0(5), GPIOF_OUT_INIT_HIGH, "LED3" } /* default to OFF */};void s5pv210_led1_set(struct led_classdev *led_cdev,enum led_brightness brightness){printk(KERN_INFO "s5pv210_led1_set successful %d\n",brightness);if(brightness == LED_OFF){gpio_set_value(x210_led_gpio[0].gpio,X210_LED_OFF);}else{gpio_set_value(x210_led_gpio[0].gpio,X210_LED_ON);}}void s5pv210_led2_set(struct led_classdev *led_cdev,enum led_brightness brightness){printk(KERN_INFO "s5pv210_led2_set successful %d\n",brightness);if(brightness == LED_OFF){gpio_set_value(x210_led_gpio[1].gpio,X210_LED_OFF);}else{gpio_set_value(x210_led_gpio[1].gpio,X210_LED_ON);}}void s5pv210_led3_set(struct led_classdev *led_cdev,enum led_brightness brightness){printk(KERN_INFO "s5pv210_led3_set successful %d\n",brightness);if(brightness == LED_OFF){gpio_set_value(x210_led_gpio[2].gpio,X210_LED_OFF);}else{gpio_set_value(x210_led_gpio[2].gpio,X210_LED_ON);}}static int __init s5pv210_led_init(void){int ret = -1;printk(KERN_INFO "s5pv210_led_init successful \n");cdev1.brightness_set = s5pv210_led1_set; = "led1";ret = led_classdev_register(NULL, &cdev1);if (ret < 0){printk(KERN_WARNING "led_classdev_register fail \n");goto reg_err1;}cdev2.brightness_set = s5pv210_led2_set; = "led2";ret = led_classdev_register(NULL, &cdev2);if (ret < 0){printk(KERN_WARNING "led_classdev_register fail \n");goto reg_err2;}cdev3.brightness_set = s5pv210_led3_set; = "led3";ret = led_classdev_register(NULL, &cdev3);if (ret < 0){printk(KERN_WARNING "led_classdev_register fail \n");goto reg_err3;}ret = gpio_request_array(x210_led_gpio, ARRAY_SIZE(x210_led_gpio));if (ret){goto gpio_err;}return0;gpio_err:led_classdev_unregister(&cdev3);reg_err3:led_classdev_unregister(&cdev2);reg_err2:led_classdev_unregister(&cdev1);reg_err1:return ret;}static void __exit s5pv210_led_exit(void){printk(KERN_INFO "s5pv210_led_exit successful \n");gpio_free_array(x210_led_gpio, ARRAY_SIZE(x210_led_gpio));led_classdev_unregister(&cdev1);led_classdev_unregister(&cdev2);led_classdev_unregister(&cdev3);}module_init(s5pv210_led_init);module_exit(s5pv210_led_exit);// MODULE_xxx这种宏作⽤是⽤来添加模块描述信息MODULE_LICENSE("GPL"); // 描述模块的许可证MODULE_AUTHOR("musk"); // 描述模块的作者MODULE_DESCRIPTION("x210 LED driver"); // 描述模块的介绍信息MODULE_ALIAS("led_driver"); // 描述模块的别名信息View Code⼀. 什么是gpiolib1.1. linux中从2.6.35以后就开始有gpiolib库了,gpiolib的作⽤是对所有的gpio实⾏统⼀管理,因为驱动在⼯作的时候,会出现好⼏个驱动共同使⽤同⼀个gpio的情况;这会造成混乱。

linux内核gpio用法

linux内核gpio用法

linux内核gpio用法Linux内核对GPIO的使用是非常广泛的,本文将会通过几个步骤来解释如何在Linux内核中使用GPIO,包括GPIO的基本知识、配置GPIO、读取GPIO值、设置GPIO值和释放GPIO资源。

一、GPIO的基本知识GPIO(General Purpose Input/Output)是一种通用的输入/输出接口,它可以与各种设备进行连接,比如传感器、开关、LED等。

在Linux内核中,GPIO 被抽象为一个特殊的设备,可以通过相应的驱动程序进行读写操作。

每个GPIO引脚都被赋予了一个唯一的数字编号,这个编号称为GPIO号。

在不同的硬件平台上,GPIO号可能不同,因此在使用GPIO之前,需要先了解具体的GPIO号对应关系。

二、配置GPIO在使用GPIO之前,需要先配置GPIO的功能和方向,可以通过以下步骤来实现。

步骤1:加载GPIO驱动程序在Linux内核中,GPIO驱动程序以模块的形式存在,首先需要加载相应的GPIO 驱动程序。

可以使用如下命令加载GPIO驱动程序:modprobe gpio步骤2:导出GPIO引脚在Linux内核中,GPIO引脚默认是不可用的,需要先导出GPIO引脚,才能使用。

可以使用如下命令导出GPIO引脚:echo GPIO号> /sys/class/gpio/export其中,GPIO号为需要导出的GPIO引脚的编号。

步骤3:配置GPIO方向GPIO引脚有输入和输出两种方向,需要根据实际需求选择。

可以使用如下命令配置GPIO方向:echo in/out > /sys/class/gpio/gpioGPIO号/direction其中,in表示输入方向,out表示输出方向。

三、读取GPIO值配置好GPIO方向后,就可以读取GPIO引脚的值了。

可以使用如下命令读取GPIO值:cat /sys/class/gpio/gpioGPIO号/value其中,GPIO号为需要读取值的GPIO引脚的编号。

基于rk3568的linux驱动开发——gpio知识点

基于rk3568的linux驱动开发——gpio知识点

基于rk3568的linux驱动开发——gpio知识点基于rk3568的Linux驱动开发——GPIO知识点一、引言GPIO(General Purpose Input/Output)通用输入/输出,是现代计算机系统中的一种常用接口,它可以根据需要配置为输入或输出。

通过GPIO 接口,我们可以与各种外设进行通信,如LED灯、按键、传感器等。

在基于Linux系统的嵌入式设备上开发驱动程序时,熟悉GPIO的使用是非常重要的一环。

本文将以RK3568芯片为例,详细介绍GPIO的相关知识点和在Linux驱动开发中的应用。

二、GPIO概述GPIO是系统中的一个基本的硬件资源,它可以通过软件的方式对其进行配置和控制。

在嵌入式设备中,通常将一部分GPIO引脚连接到外部可编程电路,以实现与外部设备的交互。

在Linux中,GPIO是以字符设备的形式存在,对应的设备驱动为"gpiolib"。

三、GPIO的驱动开发流程1. 导入头文件在驱动程序中,首先需要导入与GPIO相关的头文件。

对于基于RK3568芯片的开发,需要导入头文件"gpiolib.h"。

2. 分配GPIO资源在驱动程序中,需要使用到GPIO资源,如GPIO所在的GPIO Bank和GPIO Index等。

在RK3568芯片中,GPIO资源的分配是通过设备树(Device Tree)来进行的。

在设备树文件中,可以定义GPIO Bank和GPIO Index等信息,以及对应的GPIO方向(输入或输出)、电平(高电平或低电平)等属性。

在驱动程序中,可以通过设备树接口(Device Tree API)来获取这些GPIO资源。

3. GPIO的配置与控制在驱动程序中,首先要进行GPIO的初始化与配置。

可以通过函数"gpiod_get()"来打开指定的GPIO,并判断其是否有效。

如果成功打开GPIO,则可以使用函数"gpiod_direction_output()"或"gpiod_direction_input()"来设置GPIO的方向,分别作为输出或输入。

linux中gpio的判断方式

linux中gpio的判断方式

linux中gpio的判断方式在Linux中,GPIO(通用输入输出)的判断方式通常涉及到以下几个方面:1. 文件系统方式,在Linux中,GPIO可以通过文件系统进行控制和读取。

通常情况下,GPIO会映射到/dev目录下的GPIO设备文件中,用户可以通过读写这些文件来控制GPIO的状态。

例如,可以通过echo命令向相应的GPIO设备文件写入"1"或"0"来设置GPIO 的输出状态,也可以通过cat命令读取GPIO设备文件的内容来获取GPIO的输入状态。

2. 使用GPIO库,在Linux中,也可以使用各种GPIO库来方便地对GPIO进行操作。

这些库通常提供了更加友好和高级的接口,能够简化GPIO的控制和读取操作。

常见的GPIO库包括libgpiod、WiringPi等,用户可以根据自己的需求选择合适的库来操作GPIO。

3. 硬件设备树(Device Tree),在嵌入式Linux系统中,GPIO的定义和控制通常会通过硬件设备树来进行。

硬件设备树是一种描述硬件信息和配置的数据结构,通过编辑硬件设备树文件可以定义和配置系统中的GPIO资源,从而实现对GPIO的控制和读取。

4. 使用命令行工具,在Linux中,还可以通过一些命令行工具来对GPIO进行操作和读取。

例如,可以使用gpio命令行工具来设置和读取GPIO的状态,这些工具通常提供了简单易用的命令行接口,方便用户进行GPIO操作。

总的来说,在Linux中,GPIO的判断方式可以通过文件系统方式、使用GPIO库、硬件设备树以及命令行工具等多种途径来实现。

用户可以根据自己的需求和应用场景选择合适的方式来对GPIO进行操作和读取。

linux设备树gpio管脚

linux设备树gpio管脚

Linux设备树GPIO管脚是一种描述硬件配置的数据结构,用于在Linux内核中配置和管理GPIO(General Purpose Input/Output)引脚。

GPIO引脚是一种通用输入/输出接口,通常用于连接微控制器、传感器、执行器等外部设备。

在Linux设备树中,GPIO管脚可以通过特定的节点进行描述。

这些节点通常具有以下属性:1. `compatible`:用于描述该GPIO控制器与哪些设备或驱动程序兼容。

2. `gpio-controller`:标记该节点为一个GPIO控制器节点。

3. `#gpio-cells`:指定每个GPIO描述需要的整数值的数量。

4. `gpio-controller-data`:用于描述GPIO控制器的特定配置,例如引脚数量、引脚布局等。

在具体的GPIO节点中,可以进一步描述每个GPIO的属性,例如:* `reg`:描述GPIO寄存器的布局和大小。

* `bank`:指定GPIO的寄存器组。

* `label`:为GPIO分配一个标签,以便在驱动程序中使用。

* `gpios`:列出连接到该节点的所有GPIO编号。

例如,以下是一个描述具有两个GPIO管脚的节点的设备树片段:```dts/dts-v1/;/plugin/;/ {compatible = "myboard";my_gpio: my_gpio {compatible = "gpio-controller";#gpio-cells = <2>;status = "okay";pinctrl-names = "default";pinctrl-0 = <&pinctrl_gpio>;};my_led: my_led {compatible = "led";reg = <0>;label = "my_led";gpios = <&my_gpio 0>;};};```在上述示例中,`my_gpio`节点被标记为一个GPIO控制器节点,具有两个整数值的描述符。

linux gpio代码

linux gpio代码

linux gpio代码在Linux 系统上,你可以使用sysfs 接口来操作GPIO(通用输入输出)引脚。

下面是一个简单的例子,演示如何使用 C 语言编写一个基本的GPIO 控制程序。

```c#include <stdio.h>#include <stdlib.h>#include <string.h>#include <fcntl.h>#include <unistd.h>#define GPIO_PATH "/sys/class/gpio/"// 导出GPIO 引脚int export_gpio(int gpio_pin) {int fd, len;char buffer[3];fd = open(GPIO_PATH "export", O_WRONLY);if (fd == -1) {perror("Error opening export file");return -1;}len = snprintf(buffer, sizeof(buffer), "%d", gpio_pin);write(fd, buffer, len);close(fd);return 0;}// 设置GPIO 方向(输入/输出)int set_gpio_direction(int gpio_pin, char *direction) {char path[50];int fd;snprintf(path, sizeof(path), GPIO_PATH "gpio%d/direction", gpio_pin);fd = open(path, O_WRONLY);if (fd == -1) {perror("Error opening direction file");return -1;}write(fd, direction, strlen(direction));close(fd);return 0;}// 控制GPIO 状态(高电平/低电平)int set_gpio_value(int gpio_pin, int value) {char path[50];int fd;char buffer[2];snprintf(path, sizeof(path), GPIO_PATH "gpio%d/value", gpio_pin);fd = open(path, O_WRONLY);if (fd == -1) {perror("Error opening value file");return -1;}snprintf(buffer, sizeof(buffer), "%d", value);write(fd, buffer, 1);close(fd);return 0;}int main() {int gpio_pin = 17; // 你要控制的GPIO 引脚号int export_result, direction_result, value_result;// 导出GPIO 引脚export_result = export_gpio(gpio_pin);if (export_result != 0) {fprintf(stderr, "Error exporting GPIO pin\n");return 1;}// 设置GPIO 方向为输出direction_result = set_gpio_direction(gpio_pin, "out");if (direction_result != 0) {fprintf(stderr, "Error setting GPIO direction\n");return 1;}// 控制GPIO 输出为高电平value_result = set_gpio_value(gpio_pin, 1);if (value_result != 0) {fprintf(stderr, "Error setting GPIO value\n");return 1;}// 程序延时,保持GPIO 输出状态sleep(5);// 控制GPIO 输出为低电平value_result = set_gpio_value(gpio_pin, 0);if (value_result != 0) {fprintf(stderr, "Error setting GPIO value\n");return 1;}// 清理:取消导出GPIO 引脚int fd;char buffer[3];fd = open(GPIO_PATH "unexport", O_WRONLY);if (fd == -1) {perror("Error opening unexport file");return 1;}snprintf(buffer, sizeof(buffer), "%d", gpio_pin);write(fd, buffer, 3);close(fd);return 0;}```这是一个基本的GPIO 控制程序,演示了导出GPIO 引脚、设置方向(输入/输出)、设置状态(高电平/低电平)以及取消导出的过程。

Linux内核驱动之GPIO子系统(一)GPIO的使用

Linux内核驱动之GPIO子系统(一)GPIO的使用

Linux内核驱动之GPIO子系统(一)GPIO的使用Linux内核驱动之GPIO子系统(一)GPIO的使用一概述Linux内核中gpio是最简单,最常用的资源(和interrupt ,dma,timer一样)驱动程序,应用程序都能够通过相应的接口使用gpio,gpio使用0~MAX_INT之间的整数标识,不能使用负数,gpio与硬件体系密切相关的,不过linux有一个框架处理gpio,能够使用统一的接口来操作gpio.在讲gpio核心(gpiolib.c)之前先来看看gpio是怎么使用的二内核中gpio的使用1 测试gpio端口是否合法int gpio_is_valid(int number); 2 申请某个gpio端口当然在申请之前需要显示的配置该gpio端口的pinmux int gpio_request(unsigned gpio, const char *label)3 标记gpio的使用方向包括输入还是输出/*成功返回零失败返回负的错误值*/ intgpio_direction_input(unsigned gpio); intgpio_direction_output(unsigned gpio, int value);4 获得gpio引脚的值和设置gpio引脚的值(对于输出)int gpio_get_value(unsigned gpio); voidgpio_set_value(unsigned gpio, int value); 5 gpio当作中断口使用int gpio_to_irq(unsigned gpio); 返回的值即中断编号可以传给request_irq()和free_irq() 内核通过调用该函数将gpio端口转换为中断,在用户空间也有类似方法6 导出gpio端口到用户空间int gpio_export(unsigned gpio, bool direction_may_change); 内核可以对已经被gpio_request()申请的gpio端口的导出进行明确的管理,参数direction_may_change表示用户程序是否允许修改gpio的方向,假如可以则参数direction_may_change为真/* 撤销GPIO的导出*/ void gpio_unexport(); 三用户空间gpio的调用用户空间访问gpio,即通过sysfs接口访问gpio,下面是/sys/class/gpio目录下的三种文件:--export/unexport文件--gpioN指代具体的gpio引脚--gpio_chipN指代gpio控制器必须知道以上接口没有标准device文件和它们的链接。

Linux下的gpio,gpiod教程

Linux下的gpio,gpiod教程

GPIO 应该是每个嵌入式设备都避免不了的。

最近在做项目的时候,也遇到这方面的问题,所以简单总结一下:现在内核里面多了gpiod的来控制gpio口,相对于原来的形式,使用gpiod的好处是我们申请后不进行free也没有什么问题。

但是你要是使用原来的方式后,一定要记得释放。

不释放的话可能会有问题。

#旧的GPIO使用实例DTS文件驱动文件调用# 新的GPIOD文档#头文件我们需要包含头文件#include <linux/gpio/consumer.h>看头文件里面包含的函数列表desc_to_gpiodevm_get_gpiod_from_chidevm_gpiod_getdevm_gpiod_get_arraydevm_gpiod_get_array_opdevm_gpiod_get_indexdevm_gpiod_get_index_opdevm_gpiod_get_optionaldevm_gpiod_putdevm_gpiod_put_arrayfwnode_get_named_gpiodgpio_to_descgpiod_cansleepgpiod_countgpiod_direction_inputgpiod_direction_outputgpiod_direction_output_gpiod_exportgpiod_export_linkgpiod_getgpiod_get_arraygpiod_get_array_optionagpiod_get_directiongpiod_get_indexgpiod_get_index_optionagpiod_get_optionalgpiod_get_raw_valuegpiod_get_raw_value_cangpiod_get_valuegpiod_get_value_cansleegpiod_is_active_lowgpiod_putgpiod_put_arraygpiod_set_array_valuegpiod_set_array_value_cgpiod_set_debouncegpiod_set_raw_array_valgpiod_set_raw_array_valgpiod_set_raw_valuegpiod_set_raw_value_cangpiod_set_valuegpiod_set_value_cansleegpiod_to_irqgpiod_unexport#获取gpio描述符和释放使用一下两个函数获取GPIO设备,多个设备时需要附带index参数。

linux中gpio的判断方式

linux中gpio的判断方式

linux中gpio的判断方式Linux中的GPIO(通用输入输出)是一种用于与外部设备进行通信的接口。

它允许我们通过控制引脚的电平来读取输入信号或输出信号,从而实现与其他硬件设备的交互。

在本文中,我将介绍Linux 中GPIO的判断方式,并针对不同的应用场景进行分析。

在Linux中,我们可以通过/sys/class/gpio目录下的文件来对GPIO 进行操作。

首先,我们需要将GPIO引脚导出为GPIO文件系统的一部分。

这可以通过echo命令将GPIO的编号写入/export文件来实现。

例如,要导出GPIO17,我们可以执行以下命令:```echo 17 > /sys/class/gpio/export```导出成功后,系统会在/sys/class/gpio目录下生成一个以gpio17命名的文件夹。

我们可以通过更改gpio17文件夹中的direction文件来设置GPIO引脚的方向。

如果我们希望将GPIO17设置为输入引脚,可以执行以下命令:```echo in > /sys/class/gpio/gpio17/direction```同样,如果我们希望将GPIO17设置为输出引脚,可以执行以下命令:```echo out > /sys/class/gpio/gpio17/direction```一旦GPIO引脚的方向设置好了,我们就可以通过读取value文件来判断GPIO引脚的状态。

如果GPIO17是一个输入引脚,我们可以通过cat命令读取value文件的内容来获取GPIO的状态。

例如,如果我们希望获取GPIO17的状态,可以执行以下命令:```cat /sys/class/gpio/gpio17/value```value文件中的内容将会是0或1,分别表示GPIO引脚的低电平和高电平状态。

通过读取value文件,我们可以判断GPIO引脚当前的状态。

如果GPIO17是一个输出引脚,我们可以通过echo命令将0或1写入value文件来设置GPIO引脚的状态。

linux下控制gpio 种方法

linux下控制gpio 种方法

linux下控制gpio 种方法在Linux系统下,有多种方法可以控制GPIO(通用输入输出)端口。

这些方法可用于控制外部设备,如LED灯、传感器、继电器等等。

以下是几种常用的方法:1. 使用/sys/class/gpio接口:Linux内核提供了/sys/class/gpio 目录,通过在该目录下的文件中设置特定的值,可以控制GPIO引脚。

首先,需要导出所需的GPIO引脚,通过执行以下命令可以导出一个GPIO:```shellecho <gpio号> > /sys/class/gpio/export```然后,可以通过修改/sys/class/gpio/gpioX/*文件的值,其中X是所需的GPIO引脚号码。

例如,通过修改/sys/class/gpio/gpioX/direction文件,可以设置引脚为输入或输出。

2. 使用C/C++编程语言:通过编写C/C++程序,可以使用GPIO库函数来控制GPIO。

一个常用的库是WiringPi,它提供了简单易用的函数来操作GPIO引脚。

安装WiringPi库后,可以编写程序来设置引脚模式、读取输入和控制输出等。

以下是一个简单的示例:```c#include <wiringPi.h>int main() {wiringPiSetup(); // 初始化WiringPi库pinMode(17, OUTPUT); // 设置GPIO17为输出模式digitalWrite(17, HIGH); // 将GPIO17输出高电平return 0;}```3. 使用Python编程语言:类似地,在Python中也有一些库可用于控制GPIO。

其中一个常用的库是RPi.GPIO。

安装RPi.GPIO后,可以使用Python编写脚本来控制GPIO。

以下是一个简单的示例:```pythonimport RPi.GPIO as GPIOGPIO.setmode(GPIO.BCM) # 使用GPIO BCM模式GPIO.setup(17, GPIO.OUT) # 设置GPIO17为输出模式GPIO.output(17, GPIO.HIGH) # 将GPIO17输出高电平```需要注意的是,使用这些方法进行GPIO控制需要具有相应的权限。

linux gpio get value 说明

linux gpio get value 说明

linux gpio get value 说明GPIO(General Purpose Input/Output)是一种通用输入/输出端口,广泛应用于嵌入式系统和微控制器中。

在Linux系统中,GPIO可以通过sysfs接口进行访问和控制。

通过sysfs接口,用户空间程序可以读取或设置GPIO的值,从而实现与硬件设备的交互。

在Linux中,GPIO的值通常通过/sys/class/gpio目录下的文件来表示。

每个GPIO引脚都对应一个目录,目录名通常是gpioX,其中X是GPIO引脚的编号。

在这个目录下,有几个重要的文件用于获取和设置GPIO的值:direction:该文件用于设置GPIO的方向,即输入(input)或输出(output)。

当GPIO 作为输入时,可以通过读取value文件来获取其当前的值;当GPIO作为输出时,可以通过写入value文件来设置其输出的值。

value:该文件用于获取或设置GPIO的值。

当GPIO方向为输入时,读取该文件可以得到当前引脚的状态(高电平或低电平)。

当GPIO方向为输出时,向该文件写入1或0可以分别设置引脚为高电平或低电平。

使用Linux GPIO接口获取GPIO值的步骤如下:导出GPIO引脚:首先,需要将GPIO引脚导出到用户空间,以便通过sysfs接口进行访问。

这可以通过向/sys/class/gpio/export文件写入GPIO编号来实现。

设置GPIO方向:在导出GPIO引脚后,需要设置其方向为输入。

这可以通过向对应GPIO 目录下的direction文件写入in来实现。

读取GPIO值:设置好GPIO方向后,就可以通过读取对应GPIO目录下的value文件来获取其当前的值。

该文件的内容将是一个0或1,表示GPIO引脚当前的状态。

需要注意的是,Linux GPIO接口的具体实现可能因不同的硬件平台和内核版本而有所差异。

因此,在使用时,建议参考相关的硬件和内核文档,以确保正确地获取和设置GPIO 的值。

Linux下操作GPIO(两种方法,驱动和mmap)

Linux下操作GPIO(两种方法,驱动和mmap)

Linux下操作GPIO(两种方法,驱动和mmap)目前我所知道的在Linux下操作GPIO有两种方法:1.编写驱动,这当然要熟悉Linux下驱动的编写方法和技巧,在驱动里可以使用ioremap函数获得GPIO物理基地址指针,然后使用这个指针根据ioctl命令进行GPIO寄存器的读写,并把结果回送到应用层。

这里提供一点程序片断供大家参考:int init_module(void){printk(KERN_ALERT "ioctl load.\r\n");register_chrdev(254,"ioreg",&fops);stb_gpio = (STBX25XX_GPIO_REG *)ioremap(GPIO_BASE,GPIO_LEN);if(stb_gpio == NULL){printk(KERN_ALERT "can''t get io base.\r\n");return -1;}return 0;}int io_ioctl (struct inode *inode, struct file *filp,unsigned int cmd, unsigned long arg){unsigned long uGpio;printk(KERN_ALERT "io_ioctl cmd=%04x,arg=%04x.\r\n",cmd,(int)arg);switch(cmd){case SET_IO_DIR:{printk(KERN_ALERT "SET_IO_DIR\r\n");break;}case SET_IO_VALUE:{printk(KERN_ALERT "SET_IO_VALUE\r\n");break;}case GET_IO_VALUE:{printk(KERN_ALERT "GET_IO_VALUE\r\n");uGpio = stb_gpio->GPI;printk(KERN_ALERT "GPIO = %08x",(int)uGpio);copy_to_user((void *)arg,(const void *) &uGpio,sizeof(uGpio));break;}case GET_IO_DIR:{printk(KERN_ALERT "GET_IO_DIR\r\n");break;}}return 0;}2.在应用层使用mmap函数在应用层获得GPIO物理基地址对应的虚拟地址指针,然后使用这个指针来读写GPIO寄存器,这里提供一点程序片断供大家参考:char dev_name[] = "/dev/mem";GPIO_REGISTER *gpio_base;fd = open(dev_name,O_RDWR);if(fd<0){printf("open %s is error\n",dev_name);return -1 ;}gpio_base = (GPIO_REGISTER *)mmap( 0, 0x32, PROT_READ | PROT_WRITE, MAP_SHARED,fd, 0x40060000 );if(gpio_base == NULL){printf("gpio base mmap is error\n");close(fd);return -1;}gpio_base->or = (gpio_base->or & 0x7fffffff);mmap功能描述:mmap将一个文件或者其它对象映射进内存。

linux gpio使用方法

linux gpio使用方法

linux gpio使用方法摘要:1.Linux GPIO概述2.配置GPIO引脚3.读取和控制GPIO状态4.示例:GPIO应用5.总结与建议正文:**一、Linux GPIO概述**Linux GPIO(通用输入输出)是一种在操作系统中操作硬件设备的方法。

在Linux系统中,GPIO通常指的是硬件平台上可用的输入输出引脚。

通过GPIO,开发者可以实现对各种硬件设备的管理和控制,如LED、开关、传感器等。

GPIO在Linux系统中的使用方法丰富多样,具有较高的灵活性。

**二、配置GPIO引脚**要在Linux系统中使用GPIO,首先需要配置GPIO引脚。

常用的配置工具有sysfs、gpiochip和wiringPi。

以下以sysfs为例进行说明:1.导出GPIO引脚:`echo 1 > /sys/class/gpio/export/GPIO_引脚编号`2.设置GPIO引脚方向(输入或输出):`echo "in" >/sys/class/gpio/direction/GPIO_引脚编号`3.读取GPIO状态:`cat /sys/class/gpio/value/GPIO_引脚编号`4.设置GPIO状态(高或低):`echo 1 > /sys/class/gpio/value/GPIO_引脚编号`5.取消导出GPIO引脚:`echo 0 > /sys/class/gpio/export/GPIO_引脚编号`**三、读取和控制GPIO状态**GPIO引脚配置完成后,可以通过读取和控制GPIO状态来实现对硬件设备的操作。

以下是一些常用的GPIO操作命令:1.读取GPIO引脚状态:`cat /sys/class/gpio/value/GPIO_引脚编号`2.设置GPIO引脚状态(高或低):`echo 1 >/sys/class/gpio/value/GPIO_引脚编号`、`echo 0 >/sys/class/gpio/value/GPIO_引脚编号`**四、示例:GPIO应用**以下以LED灯为例,展示GPIO在Linux系统中的实际应用:1.配置GPIO引脚:导出GPIO引脚、设置为输出模式2.控制LED灯:通过设置GPIO引脚状态来控制LED灯的开启与关闭3.循环控制LED灯:使用while循环,实现LED灯的闪烁**五、总结与建议**Linux GPIO为开发者提供了一种便捷的硬件控制方法。

linux gpio get value 说明

linux gpio get value 说明

linux gpio get value 说明全文共四篇示例,供读者参考第一篇示例:GPIO(General Purpose Input/Output)是Linux系统中的一种常见的外设,它可以灵活地连接到不同的外部设备,用来进行数字输入与输出操作。

在Linux系统中,GPIO的操作是通过/sys/class/gpio 目录下的文件进行的,其中含有GPIO的相关信息。

在Linux系统中,通过/sys/class/gpio目录下的相应文件,可以对GPIO进行读取和设置操作。

gpiochipN文件夹中的gpioN文件代表着具体的GPIO引脚,可以进行读取和写入操作。

获取GPIO的当前值有很多方法,可以使用cat命令读取gpioN文件夹中的value文件,也可以直接读取/sys/class/gpio/gpioN/value文件。

要获取GPIO引脚当前的值,首先需要确认该引脚已经被导出(export)并且方向为输入(input)。

如果没有导出该引脚,可以通过echo命令将引脚号写入/export文件,如:```bashecho GPIO_Number > /sys/class/gpio/export```然后,确认引脚方向为输入,可以通过echo命令将引脚的方向设置为in,如:接着,可以读取该引脚的值。

通过cat命令读取gpioN文件夹中的value文件,可以获取该GPIO引脚的当前值,如:如果返回值为0,则表示引脚当前的电平为低电平(0V),如果返回值为1,则表示引脚当前的电平为高电平(3.3V或5V,具体取决于硬件)。

除了使用cat命令读取value文件外,还可以直接读取/sys/class/gpio/gpioN/value文件的内容,来获取GPIO引脚的当前值。

这种方法更加直接简洁,相对于cat命令,效率更高。

第二篇示例:GPIO(General Purpose Input/Output)是Linux系统中对外部设备进行输入输出的接口。

Linux内核文档:GPIO接口

Linux内核文档:GPIO接口

原文:Documentation/gpio.txt翻译:tekkamanninja@翻译完成时间:2012年2月18日星期六V1.0目录什么是GPIO? (3)GPIO公约 (3)标识GPIO (3)使用 GPIO (4)访问自旋锁安全的GPIO (4)访问可能休眠的GPIO (5)声明和释放GPIO (5)GPIO映射到IRQ (7)模拟开漏信号 (7)GPIO实现者的框架 (可选) (8)控制器驱动: gpio_chip (8)平台支持 (8)板级支持 (9)用户空间的Sysfs接口(可选) (9)Sysfs中的路径 (9)从内核代码中导出 (10)本文档提供了一个在Linux下访问GPIO的公约概述。

这些函数以gpio_* 作为前缀。

其他的函数不允许使用这样的前缀或相关的__gpio_* 前缀。

什么是GPIO?"通用输入/输出口"(GPIO)是一个灵活的由软件控制的数字信号。

他们可由多种芯片提供,且对于从事嵌入式和定制硬件的Linux开发者来说是比较熟悉。

每个GPIO都代表一个连接到特定引脚或球栅阵列(BGA)封装中“球珠”的一个位。

电路板原理图显示了GPIO与外部硬件的连接关系。

驱动可以编写成通用代码,以使板级启动代码可传递引脚配置数据给驱动。

片上系统(SOC) 处理器对GPIO有很大的依赖。

在某些情况下,每个非专用引脚都可配置为GPIO,且大多数芯片都最少有一些GPIO。

可编程逻辑器件(类似FPGA) 可以方便地提供GPIO。

像电源管理和音频编解码器这样的多功能芯片经常留有一些这样的引脚来帮助那些引脚匮乏的SOC。

同时还有通过I2C或SPI串行总线连接的"GPIO扩展器"芯片。

大多数PC的南桥有一些拥有GPIO能力的引脚(只有BIOS固件才知道如何使用他们)。

GPIO的实际功能因系统而异。

通常的用法有:- 输出值可写(高电平=1, 低电平=0)。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

原文:Documentation/gpio.txt翻译:tekkamanninja@翻译完成时间:2012年2月18日星期六V1.0目录什么是GPIO? (3)GPIO公约 (3)标识GPIO (3)使用 GPIO (4)访问自旋锁安全的GPIO (4)访问可能休眠的GPIO (5)声明和释放GPIO (5)GPIO映射到IRQ (7)模拟开漏信号 (7)GPIO实现者的框架 (可选) (8)控制器驱动: gpio_chip (8)平台支持 (8)板级支持 (9)用户空间的Sysfs接口(可选) (9)Sysfs中的路径 (9)从内核代码中导出 (10)本文档提供了一个在Linux下访问GPIO的公约概述。

这些函数以gpio_* 作为前缀。

其他的函数不允许使用这样的前缀或相关的__gpio_* 前缀。

什么是GPIO?"通用输入/输出口"(GPIO)是一个灵活的由软件控制的数字信号。

他们可由多种芯片提供,且对于从事嵌入式和定制硬件的Linux开发者来说是比较熟悉。

每个GPIO都代表一个连接到特定引脚或球栅阵列(BGA)封装中“球珠”的一个位。

电路板原理图显示了GPIO与外部硬件的连接关系。

驱动可以编写成通用代码,以使板级启动代码可传递引脚配置数据给驱动。

片上系统(SOC) 处理器对GPIO有很大的依赖。

在某些情况下,每个非专用引脚都可配置为GPIO,且大多数芯片都最少有一些GPIO。

可编程逻辑器件(类似FPGA) 可以方便地提供GPIO。

像电源管理和音频编解码器这样的多功能芯片经常留有一些这样的引脚来帮助那些引脚匮乏的SOC。

同时还有通过I2C或SPI串行总线连接的"GPIO扩展器"芯片。

大多数PC的南桥有一些拥有GPIO能力的引脚(只有BIOS固件才知道如何使用他们)。

GPIO的实际功能因系统而异。

通常的用法有:- 输出值可写(高电平=1, 低电平=0)。

一些芯片也有如何驱动这些值的选项,例如只允许输出一个值、支持“线与”及其他取值类似的模式(值得注意的是“开漏”信号)。

- 输入值可读(1、0)。

一些芯片支持引脚在配置为“输出”时回读,这对于类似“线与”的情况(以支持双向信号)是非常有用的。

GPIO 控制器可能有输入去毛刺/消抖逻辑,这有时需要软件控制。

- 输入通常可作为IRQ信号,一般是沿触发,但有时是电平触发。

这样的IRQ 可能配置为系统唤醒事件,以将系统从低功耗状态下唤醒。

- 通常一个GPIO根据不同产品电路板的需求,可以配置为输入或输出,也有仅支持单向的。

- 大部分GPIO 可以在持有自旋锁时访问,但是通常由串行总线扩展的GPIO不允许持有自旋锁。

但某些系统也支持这种类型。

对于给定的电路板,每个GPIO都用于某个特定的目的,如监控MMC/SD卡的插入/移除、检测卡的写保护状态、驱动LED、配置收发器、模拟串行总线、复位硬件看门狗、感知开关状态等等。

GPIO公约注意,这个叫做“公约”,因为这不是强制性的,不遵循这个公约是无伤大雅的,因为此时可移植性并不重要。

GPIO常用于板级特定的电路逻辑,甚至可能随着电路板的版本而改变,且不可能在不同走线的板子上使用。

仅有在很少的功能上才具有可移植性,其他功能是平台特定。

这也是由于“胶合”的逻辑造成的。

此外,这不需要任何的执行框架,只是一个接口。

某个平台可能通过一个简单的访问芯片寄存器的内联函数来实现它,其他平台可能通过委托一系列不同的GPIO控制器的抽象函数来实现它。

(有一些可选的代码能支持这种策略的实现,本文档后面会介绍,但作为GPIO接口的客户端驱动程序必须与它的实现无关。

)也就是说,如果在他们的平台上支持这个公约,驱动应该尽可能的使用它。

平台必须在Kconfig中声明对GENERIC_GPIO 的支持(布尔型true),并提供一个<asm/gpio.h> 文件。

那些调用标准GPIO函数的驱动应该在Kconfig 入口中声明依赖GENERIC_GPIO。

当驱动包含文件:#include <linux/gpio.h>GPIO函数是可用,无论是“真实代码”还是经优化过的语句。

如果你遵守这个公约,当你的代码完成后,对其他的开发者来说会更容易看懂和维护。

注意,这些操作包含所用平台的I/O 屏障代码,驱动无须显式地调用他们。

标识GPIOGPIO是通过无符号整型来标识的,范围是0到MAX_INT。

保留“负”数用于其他目的,例如标识信号“在这个板子上不可用”或指示错误。

未接触底层硬件的代码会忽略这些整数。

平台会定义这些整数的用法,且通常使用#define 来定义GPIO ,这样板级特定的启动代码可以直接关联相应的原理图。

相对来说,驱动应该仅使用启动代码传递过来的GPIO 编号,使用platform_data 保存板级特定引脚配置数据(同时还有其他须要的板级特定数据),避免可能出现的问题。

例如一个平台使用编号32-159 来标识GPIO,而在另一个平台使用编号0-63 标识一组GPIO 控制器,64-79 标识另一类GPIO 控制器, 且在一个含有FPGA的特定板子上使用80-95 。

编号不一定要连续,那些平台中,也可以使用编号2000-2063 来标识一个I2C接口的GPIO扩展器中的GPIO。

如果你要初始化一个带有无效GPIO编号的结构体,可以使用一些负编码(比如"-EINV AL"),那将永远不会是有效。

来测试这样一个结构体中的编号是否关联一个GPIO,你可使用以下断言:int gpio_is_valid(int number);如果编号不存在,则请求和释放GPIO的函数将拒绝执行相关操作(见下文)。

其他编号也可能被拒绝,比如一个编号可能存在,但暂时在给定的板子上不可用。

一个平台是否支持多个GPIO控制器是平台特定的实现问题,就像是否可以在GPIO编号空间中有“空洞”和是否可以在运行时添加新的控制器一样。

这些问题会影响其他事情,包括相邻的GPIO编号是否存在等。

使用 GPIO对于一个GPIO,系统应该做的第一件事情就是通过gpio_request() 函数分配他,见下文。

而接下来要做的是标识它的方向,这通常是在板级启动代码中为GPIO设置一个platform_device时做的。

/* 设置为输入或输出, 返回0 或负的错误代码*/int gpio_direction_input(unsigned gpio);int gpio_direction_output(unsigned gpio, int value);返回值为零代表成功,否则返回一个负的错误代码。

这个返回值需要检查,因为get/set(获取/设置)函数调用没法返回错误,且有可能是配置错误。

通常,你应该在进程上下文中调用这些函数。

然而,对于自旋锁安全的GPIO,在板子启动的早期、进程启动前使用他们也是可以的。

对于作为输出的GPIO,为其提供初始输出值,对于避免在系统启动期间出现信号毛刺是很有帮助的。

为了与传统的GPIO接口兼容, 在设置一个GPIO方向时,如果它还未被申请,则隐含了申请那个GPIO的操作(见下文)。

这种兼容性正在从可选的gpiolib框架中移除。

如果这个GPIO编码不存在或特定的GPIO不能用于那种模式,则方向设置可能失败。

依赖启动固件来正确地设置方向通常是一个坏主意,因为它可能除了启动Linux,并没有做更多的验证工作。

(类似地, 板子的启动代码可能需要将这个复用的引脚设置为GPIO,并正确地配置上拉/下拉电阻。

)访问自旋锁安全的GPIO大多数GPIO控制器可以通过内存读/写指令来访问。

这些指令不会休眠,可以安全地在硬(非线程)中断例程和类似的上下文中完成。

对于那些用gpio_cansleep()测试总是返回失败的GPIO(见下文),使用以下的函数访问:/* GPIO 输入:返回零或非零*/int gpio_get_value(unsigned gpio);/* GPIO 输入*/void gpio_set_value(unsigned gpio, int value);返回值是布尔值,零表示低电平,非零表示高电平。

当读取一个输出引脚的值时,返回值应该是引脚上的值。

这个值不总是和输出值相符,因为存在开漏输出信号和输出潜伏期的问题。

以上的get/set函数不会对早期已经通过gpio_direction_*()报告“无效的GPIO”返回错误。

此外,还需要注意的是并不是所有平台都可以从输出引脚中读取数据的,那些引脚也不总是返回零。

且对那些无法安全访问(可能会休眠)的GPIO(见下文)使用这些函数是错误的。

在GPIO编号(还有输出、值)为常数的情况下,鼓励通过平台特定的实现来优化这两个函数来访问GPIO值。

这种情况(读写一个硬件寄存器)下只需要几条指令是很正常的,且无须自旋锁。

这种优化函数比起那些在子程序上花费许多指令的函数可以使得模拟接口(译者注:例如GPIO模拟I2C、1-wire或SPI)的应用(在空间和时间上都)更具效率。

访问可能休眠的GPIO某些GPIO控制器必须通过基于总线(如I2C或SPI)的消息访问。

读或写这些GPIO值的命令需要等待其信息排到队首才发送命令,再获得其反馈。

期间需要休眠,这不能在IRQ例程(中断上下文)中执行。

支持此类GPIO的平台通过以下函数返回非零值来区分出这种GPIO。

(此函数需要一个之前通过gpio_request分配到的有效的GPIO编号):int gpio_cansleep(unsigned gpio);为了访问这种GPIO,内核定义了一套不同的函数:/* GPIO 输入:返回零或非零,可能会休眠*/int gpio_get_value_cansleep(unsigned gpio);/* GPIO 输入,可能会休眠*/void gpio_set_value_cansleep(unsigned gpio, int value);访问这样的GPIO需要一个允许休眠的上下文,例如线程IRQ处理例程,并用以上的访问函数替换那些没有cansleep()后缀的自旋锁安全访问函数。

除了这些访问函数可能休眠,且它们操作的GPIO不能在硬件IRQ处理例程中访问的事实,这些处理例程实际上和自旋锁安全的函数是一样的。

** 除此之外** 调用设置和配置此类GPIO的函数也必须在允许休眠的上下文中,因为它们可能也需要访问GPIO控制器芯片:(这些设置函数通常在板级启动代码或者驱动探测/断开代码中,所以这是一个容易满足的约束条件。

) gpio_direction_input()gpio_direction_output()gpio_request()## gpio_request_one()## gpio_request_array()## gpio_free_array()gpio_free()gpio_set_debounce()声明和释放GPIO为了有助于捕获系统配置错误,定义了两个函数。

相关文档
最新文档