LINUX --- echo修改GPIO状态
GPIO sysfs InterfaceThe GPIO sysfsinterface allows users to manipulate any GPIO fromuserspace (also known as programmable flags). Since it uses gpiolib, it is able to dynamically utilize all
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.
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
:
high | Set GPIO to an output with a starting value of 1 |
low | Set GPIO to an output with a starting value of 0 |
out | Same as low |
in | Set 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
更多推荐
所有评论(0)