linux gpio 控制 基于 sysfs

2019-07-13 08:02发布

简介
    相信大家在进行嵌入式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 1 2 3 4 5 6 7 8 9 10 11 12 #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.c 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 include  #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 ", gpio);     return gpio_write_value(GPIO_EXPORT, buffer, strlen(buffer)); }   int gpio_free(unsigned int gpio) {     char buffer[16];     snprintf(buffer, sizeof(buffer), "%d ", 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 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 #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);     } }
本文出自 “记录点滴收获成长” 博客,请务必保留此出处http://gofly.blog.51cto.com/4344767/1685747