LINUX --- echo修改GPIO状态

本文详细介绍了GPIO sysfs接口的概念、用途、配置方法、用户空间接口、请求/释放GPIO、读写操作以及外部资源等内容。通过实例演示了如何在用户空间中请求、释放、设置方向和读取GPIO状态,提供了GPIO sysfs接口的全面指南。

GPIO sysfs Interface

The GPIO sysfs interface allows users to manipulate any GPIO from userspace (also known as programmable flags). Since it uses gpiolib, it is able to dynamically utilize all GPIOs on the system, even ones on expander cards (like the ADP5520).

Userspace utilizes a sysfs control interface to dynamically request and release individual GPIOs. Once a GPIO has been requested, writing to the newly created path allows you to control the direction and the data while reading from it returns the GPIO data (which usually corresponds to a 0 or 1 which represents the signal level).

GPIOs are referred to by their numeric value. You can refer to the GPIO pin table to quickly figure out what number is used for a specific pin on a specific port in the Blackfin processor.

If you need non-blocking reads, support for poll() and select() system calls, or similar features, please refer to the  gpio-keys input device driver

With recent kernels (2.6.33+) it is now possible to poll() on a GPIO simply set “rising”, “falling” or “both” to /sys/class/gpio/gpioX/edge then poll for POLLPRI on the relevant open+read fd.

Configuration

Since the pins are tied to a GPIO controller, there are no platform resources you need to declare. Simply enable the driver in your kernel configuration menu:

Device Drivers  --->
  [*] GPIO Support  --->
    [*]   /sys/class/gpio/... (sysfs interface)

Userspace Interface

All the GPIO interfaces are based in /sys/class/gpio/.

Request/Release

You first have to request a GPIO. So if we wanted to request GPIO 23, we would do:

root:/> echo 23 > /sys/class/gpio/export

If this process was successful, you would end up with a /sys/class/gpio/gpio23/ directory.

Then when we were done with it, we would release it by doing:

root:/> echo 23 > /sys/class/gpio/unexport

Reading/Writing

In the specific GPIO directory, there will be two files: direction and value. Reading from them returns the current state (direction / value) as you might expect. Writing to them sets the current state.

Possible commands for direction:

highSet GPIO to an output with a starting value of 1
lowSet GPIO to an output with a starting value of 0
outSame as low
inSet GPIO to an input

The value field simply uses numeric values, so 0 or 1.

Examples

To set GPIO 23 to an input:

root:/> echo in > /sys/class/gpio/gpio23/direction

To set GPIO 23 to a high output:

root:/> echo high > /sys/class/gpio/gpio23/direction

To set GPIO 23's value to 0:

root:/> echo 0 > /sys/class/gpio/gpio23/value

To read GPIO 23's current value:

root:/> cat /sys/class/gpio/gpio23/value
0

External Resources

The GPIO framework and GPIO sysfs interface are both documented in this file:

  • linux-2.6.x/Documentation/gpio.txt

GPIO Sysfs Helpers

Some simple example:

file: trunk/user/blkfin-test/ppifcd-test/gpio.h

/*
 * GPIO user space helpers
 *
 * Copyright 2009 Analog Devices Inc.
 * Michael Hennerich (hennerich@blackfin.uclinux.org)
 *
 * Licensed under the GPL-2 or later
 */
 
#ifndef GPIO_H
#define GPIO_H
int gpio_export(unsigned gpio);
int gpio_unexport(unsigned gpio);
int gpio_dir_out(unsigned gpio);
int gpio_dir_in(unsigned gpio);
int gpio_value(unsigned gpio, unsigned value);
#endif

file: trunk/user/blkfin-test/ppifcd-test/gpio.c

/*
 * GPIO user space helpers
 *
 * Copyright 2009 Analog Devices Inc.
 * Michael Hennerich (hennerich@blackfin.uclinux.org)
 *
 * Licensed under the GPL-2 or later
 */
 
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
 
#define GPIO_DIR_IN	0
#define GPIO_DIR_OUT	1
 
int gpio_export(unsigned gpio)
{
	int fd, len;
	char buf[11];
 
	fd = open("/sys/class/gpio/export", O_WRONLY);
	if (fd < 0) {
		perror("gpio/export");
		return fd;
	}
 
	len = snprintf(buf, sizeof(buf), "%d", gpio);
	write(fd, buf, len);
	close(fd);
 
	return 0;
}
 
int gpio_unexport(unsigned gpio)
{
	int fd, len;
	char buf[11];
 
	fd = open("/sys/class/gpio/unexport", O_WRONLY);
	if (fd < 0) {
		perror("gpio/export");
		return fd;
	}
 
	len = snprintf(buf, sizeof(buf), "%d", gpio);
	write(fd, buf, len);
	close(fd);
	return 0;
}
 
int gpio_dir(unsigned gpio, unsigned dir)
{
	int fd, len;
	char buf[60];
 
	len = snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%d/direction", gpio);
 
	fd = open(buf, O_WRONLY);
	if (fd < 0) {
		perror("gpio/direction");
		return fd;
	}
 
	if (dir == GPIO_DIR_OUT)
		write(fd, "out", 4);
	else
		write(fd, "in", 3);
 
	close(fd);
	return 0;
}
 
int gpio_dir_out(unsigned gpio)
{
	return gpio_dir(gpio, GPIO_DIR_OUT);
}
 
int gpio_dir_in(unsigned gpio)
{
	return gpio_dir(gpio, GPIO_DIR_IN);
}
 
int gpio_value(unsigned gpio, unsigned value)
{
	int fd, len;
	char buf[60];
 
	len = snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%d/value", gpio);
 
	fd = open(buf, O_WRONLY);
	if (fd < 0) {
		perror("gpio/value");
		return fd;
	}
 
	if (value)
		write(fd, "1", 2);
	else
		write(fd, "0", 2);
 
	close(fd);
	return 0;
}
 
#if 0
int main(int argc, char *argv[])
{
	int i = 20;
 
	gpio_export(6);
	gpio_dir_out(6);
 
	while(i--) {
		gpio_value(6, i & 1);
		sleep(1);
	}
 
	gpio_unexport(6);
}
#endif
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值