IMX6ULL|libgpiod控制IO

一.为何使用libgpiod控制IO

在Linux中,最常见的读写GPIO方式就是用GPIO sysfs interface, 是通过操作 /sys/class/gpio 目录下的 export 、 unexport 、gpio{N}/direction, gpio{N} /value (用实际引脚号替代{N})等文件实现的,经常出现shell脚本里面。 在kernel 4.8开始,加入了libgpiod的支持;而原有基于sysfs的访问方式,将被逐渐放弃。

二.如何安装libgpiod控制IO

libgpiod是一种字符设备接口,GPIO访问控制是通过操作字符设备文件(比如 /dev/gpiodchip0 )实现的, 并通过libgpiod提供一些命令工具、c库以及python封装。

想要使用libgpiod,需要在开发板上安装libgpiod库。

 #安装libgpiod库及头文件
 sudo apt install  libgpiod-dev vim

 #安装gpiod 命令行工具
 sudo apt install gpiod

三.命令行控制

常用的命令行如下,可使用 -h 查看命令相对应的使用说明

命令 作用 使用举例
gpiodetect 列出所有的 GPIO 控制器 gpiodetect
gpioinfo 列出 GPIO 控制器的引脚情况 gpioinfo 4
gpioset 设置 GPIO 引脚的状态 gpioset 4 19=0
gpioget 获取 GPIO 引脚状态 gpioget 4 1
gpiomon 监控 GPIO 引脚状态并整理成表格 gpiomon 4 1

查看数据手册可知在imx6ull中GPIO组的编号从1开始,而libgpiod引脚组从0开始, 因此 gpioset 4 19=0
,则表示的是GPIO5组编号为19的引脚。 并不是所有的引脚都能够使用libgpiod控制,例如led之类的一些已经被使用的引脚。

四.使用libgpiod编程

若想要在PC上交叉编译出能运行在板子的应用程序,交叉链接时使用的libgpiod库要与开发板的匹配, 可以直接把开发板的库拷贝到PC上链接使用。

开发板安装好ligpiod-dev后,可以通过以下命令找到具体的头文件和库文件:

 # 在开发板上查找libgpiod库
 dpkg -L libgpiod-dev
 # 以下是输出
 /usr/include/gpiod.h
 /usr/lib/arm-linux-gnueabihf/libgpiod.a
 /usr/lib/arm-linux-gnueabihf/libgpiod.so

查找结果中的gpiod.h、libgpiod.so和libgpiod.a就是开发板使用的头文件、动态和静态链接库, 它是debian 10 buster默认apt安装的版本。

常用的libgpiod API(C库)如下所示:

//成员变量
 struct gpiod_chip;      //GPIO组句柄
 struct gpiod_line;      //GPIO引脚句柄

 //获取GPIO控制器(GPIO组)
 struct gpiod_chip *gpiod_chip_open(const char *path);

 //获取GPIO引脚
 struct gpiod_line * gpiod_chip_get_line(struct gpiod_chip *chip, unsigned int offset);

 //设置引脚方向为输入模式
 int gpiod_line_request_input(struct gpiod_line *line,const char *consumer);

 //设置引脚为输出模式
 int gpiod_line_request_output(struct gpiod_line *line,const char *consumer, int default_val)

 //设置引脚的高低电平
 int gpiod_line_set_value(struct gpiod_line *line, int value);

 //读取引脚状态
 int gpiod_line_get_value(struct gpiod_line *line);

 //释放GPIO引脚
 void gpiod_line_release(struct gpiod_line *line);

 //关闭GPIO组句柄并释放所有分配的资源。
 void gpiod_chip_close(struct gpiod_chip *chip);

#include 
#include 
#include 
#include 

/*
 //获取GPIO控制器(GPIO组)
 struct gpiod_chip *gpiod_chip_open(const char *path);

 //获取GPIO引脚
 struct gpiod_line * gpiod_chip_get_line(struct gpiod_chip *chip, unsigned int offset);

 //设置引脚方向为输入模式
 int gpiod_line_request_input(struct gpiod_line *line,const char *consumer);

 int= gpiod_line_request_output(line,"beep",0);   //设置为输出模式,且为低电平,
 //读取引脚状态
 int gpiod_line_get_value(struct gpiod_line *line);



 //释放GPIO引脚
 void gpiod_line_release(struct gpiod_line *line);

 //关闭GPIO组句柄并释放所有分配的资源。
 void gpiod_chip_close(struct gpiod_chip *chip);



 */

int main(int argc, char **argv)
{
    int i;
    int ret;

    struct gpiod_chip * chip;      //GPIO控制器句柄
    struct gpiod_line * line;      //GPIO引脚句柄


    /*获取GPIO控制器*/
    chip = gpiod_chip_open("/dev/gpiochip0");  //第一组
    if(chip == NULL)
    {
        printf("gpiod_chip_open error\n");
        return -1;
    }

    /*获取GPIO引脚*/
    line = gpiod_chip_get_line(chip, 19);  //第一组的19号引脚
    if(line == NULL)
    {
        printf("gpiod_chip_get_line error\n");
        goto release_line; 
    }

    /*设置GPIO为输出模式*/
    ret = gpiod_line_request_output(line,"beep",0);   //设置为输出模式,且为低电平,
    if(ret < 0)
    {
        printf("gpiod_line_request_output error\n");
        goto release_chip; 
    }

    for(i = 0;i<10;i++)
    {
        gpiod_line_set_value(line,1);
        usleep(500000);  //延时0.5s
        gpiod_line_set_value(line,0);
        usleep(500000);
    }

    
release_line:  
    /*释放GPIO引脚*/
    gpiod_line_release(line);

release_chip:
    /*释放GPIO控制器*/
    gpiod_chip_close(chip);


    return 0;
}


编译程序时需指定libgpiod库及路径头文件路径(不使用交叉编译时并不需要指定路径)。

然后我们在开发板上执行方式一


 sudo arm-linux-gnueabihf-gcc  beep.c  -lgpiod -L./libgpiod/ -I./libgpiod/ -o beep
 sudo chmod 777 beep
 ./beep

你可能感兴趣的:(嵌入式)