简介
相信大家在进行嵌入式linux设备开发时,会多或少都会涉及到对gpio的控制。以前通用的方式是在内核中增加一个gpio驱动,然后再在上端条用它从而实现对gpio的控制。
今天我给大家介绍一个简单的方式(不用写代码)用以控制gpio。该方式主要基于内核提供的gpio控制接口文件。也就是通过读写/sys/class/gpio目录下的文件来控制对应的gpio接口。
使用该方法去控制某个gpio接口主要分为三个步骤:
1、导出相应的gpio接口。
2、设置相应gpio接口的方向。(in or out)
3、设置相应gpio的值。
导出GPIO
echo $gpio_num > /sys/class/gpio/export
eg: echo 1 > /sys/class/gpio/export
执行完以上命令后,如果该gpio接口存在且未被占用则会出现如下目录:/sys/class/gpio/gpio1
设置方向
gpio的方向分为两类:in和out
in:表示该gpio用于输入。(如该gpio连接一个按钮)
out:表示该gpio用于输出。(如该gpio连接一个led灯)
指定为in模式的命令:echo in > /sys/class/gpio/gpio1/direction
指定为out模式的命令如下:
echo out > /sys/class/gpio/gpio1/direction //默认value为0
echo low > /sys/class/gpio/gpio1/direction //指定方向为out且value为0
echo high > /sys/class/gpio/gpio1/direction //指定方向为out且value为1
设置高低
只用当方向为out模式时才能指定gpio接口的电压的高低。这个很容易理解,因为如果是in模式的话,它的电平高低取决于所连接外设的电平高低,我们只能读取它的值,不能更改它的值。
echo 1 > /sys/class/gpio/gpio1/value //指定gpio1为高电平。
echo 0 > /sys/class/gpio/gpio1/value //指定gpio1为低电平。
获取当前值
cat /sys/class/gpio/gpio1/value //用以获取gpio1的当前值。
cat /sys/kernel/debug/gpio //用以获取系统中所有正在使用的gpio的值。
linux C实现代码
gpio.h#ifndef GPIO_H_
#define GPIO_H_
int gpio_is_requested(unsigned int gpio);
int gpio_request(unsigned int gpio);
int gpio_free(unsigned int gpio);
int gpio_direction_input(unsigned int gpio);
int gpio_direction_output(unsigned int gpio, int value);
int gpio_get_value(unsigned int gpio);
int gpio_set_value(unsigned int gpio, int value);
#endif
gpio.cinclude
#include
#include
#include
#include
#include
#include
#include
#include "gpio.h"
#define GPIO_ROOT "/sys/class/gpio"
#define GPIO_EXPORT GPIO_ROOT "/export"
#define GPIO_UNEXPORT GPIO_ROOT "/unexport"
#define GPIO_DIRECTION GPIO_ROOT "/gpio%d/direction"
#define GPIO_ACTIVELOW GPIO_ROOT "/gpio%d/active_low"
#define GPIO_VALUE GPIO_ROOT "/gpio%d/value"
static int gpio_write_value(const char *pathname, const char *buf, size_t count)
{
int fd;
if ((fd = open(pathname, O_WRONLY)) == -1)
return -1;
if (write(fd, buf, count) != count) {
close(fd);
return -1;
}
return close(fd);
}
int gpio_is_requested(unsigned int gpio)
{
int rv;
char pathname[255];
snprintf(pathname, sizeof(pathname), GPIO_VALUE, gpio);
if ((rv = access(pathname, R_OK)) == -1)
return -1;
return (rv == 0);
}
int gpio_request(unsigned int gpio)
{
char buffer[16];
snprintf(buffer, sizeof(buffer), "%d\n", gpio);
return gpio_write_value(GPIO_EXPORT, buffer, strlen(buffer));
}
int gpio_free(unsigned int gpio)
{
char buffer[16];
snprintf(buffer, sizeof(buffer), "%d\n", gpio);
return gpio_write_value(GPIO_UNEXPORT, buffer, strlen(buffer));
}
int gpio_direction_input(unsigned int gpio)
{
char pathname[255];
snprintf(pathname, sizeof(pathname), GPIO_DIRECTION, gpio);
return gpio_write_value(pathname, "in", 3);
}
int gpio_direction_output(unsigned int gpio, int value)
{
char pathname[255];
char *val;
snprintf(pathname, sizeof(pathname), GPIO_DIRECTION, gpio);
val = value ? "high" : "low";
return gpio_write_value(pathname, val, strlen(val) + 1);
}
int gpio_get_value(unsigned int gpio)
{
int fd;
char pathname[255];
char buffer;
snprintf(pathname, sizeof(pathname), GPIO_VALUE, gpio);
if ((fd = open(pathname, O_RDONLY)) == -1)
return -1;
if (read(fd, &buffer, sizeof(buffer)) != sizeof(buffer)) {
close(fd);
return -1;
}
if (close(fd) == -1)
return -1;
return buffer - '0';
}
int gpio_set_value(unsigned int gpio, int value)
{
char pathname[255];
snprintf(pathname, sizeof(pathname), GPIO_VALUE, gpio);
return gpio_write_value(pathname, value ? "1" : "0", 2);
}
test.c#include
#include
#include "gpio.h"
#define GPIO_MODEM_POWER 11
#define GPIO_MODEM_RESET 2
#define GPIO_SIM_EN 9
#define GPIO_SIM_SEL 8
int main(int argc, char **argv)
{
if (gpio_is_requested(GPIO_SIM_EN) != 1) {
gpio_request(GPIO_SIM_EN);
gpio_direction_output(GPIO_SIM_EN, 1);
}
if (gpio_is_requested(GPIO_SIM_SEL) != 1) {
gpio_request(GPIO_SIM_SEL);
gpio_direction_output(GPIO_SIM_SEL, 0);
}
if (gpio_is_requested(GPIO_MODEM_RESET) != 1) {
gpio_request(GPIO_MODEM_RESET);
gpio_direction_output(GPIO_MODEM_RESET, 1);
}
if (gpio_is_requested(GPIO_MODEM_POWER) != 1) {
gpio_request(GPIO_MODEM_POWER);
gpio_direction_output(GPIO_MODEM_POWER, 1);
}
}