一、前言

  • 本文基于泰山派RK3566开发板为例
  • libgpiod 版本号为1.6.3
  • 嵌入式Linux学习交流群:1005210698
  • 本文相关源码以及更多免费资料可加群获取

二、简介

  • GPIO 是 General Purpose I/O 的缩写,即通用输入输出端口, 简单来说就是 MCU/CPU 可控制的引脚,这些引脚通常有多种功能, 最基本的是高低电平输入检测和输出, 部分引脚还会与主控器的片上外设绑定, 如作为串口、I2C、网络、电压检测的通讯引脚。
  • 在 Linux 中,最常见的读写GPIO方式就是用 GPIO sysfs interface, 是通过操作 /sys/class/gpio 目录下的 exportunexportgpio{N}/direction, gpio{N} /value (用实际引脚号替代{N})等文件实现的,经常出现 shell 脚本里面。 在 kernel 4.8 开始,加入了 libgpiod 的支持;而原有基于 sysfs 的访问方式,将被逐渐放弃。
  • libgpiod 是一种字符设备接口,GPIO访问控制是通过操作字符设备文件(比如 /dev/gpiodchip0 )实现的, 并通过 libgpiod 提供一些命令工具、c库以及python封装。

交叉编译libgpiod

1.下载源码

源码:https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git/refs/?h=v1.6.x
版本最好选择1.6.3,最新的函数有变动
在这里插入图片描述

2.交叉编译
  1. 下载好libgpiod,解压
tar -xzf libgpiod-1.6.3.tar.gz
  1. 进入 libgpiod 后,运行 autogen.sh,生成 configure 和 Makefile 文件
cd libgpiod-1.6.3
./autogen.sh         # 出现错误后一般是缺少相关的工具,可自行百度下载
  1. 先该目录下创建编译后生成文件的文件夹,然后运行 configure 配置文件
mkdir -p install

./configure CC=aarch64-linux-gnu-gcc --host=aarch64-linux-gnu --prefix=`pwd`/install --enable-tools --enable-share
  1. 无报错后可以编译安装了
make && make install
  1. 最终在 install 目录下会有三个文件夹
    在这里插入图片描述

  2. 将 lib 下后缀是 .so 的文件全部移植到开发板 /usr/lib/ 下(如果共享库的软链接没了,需要重新链接)
    在这里插入图片描述

rm libgpiod.so libgpiod.so.2
ln -s libgpiod.so.2.2.2 libgpiod.so
ln -s libgpiod.so.2.2.2 libgpiod.so.2
  1. 将 bin 下的可执行文件移植到开发板 /usr/bin/ 下,添加权限
    在这里插入图片描述
chmod 755 gpio*
命令 作用 使用举例 说明
gpiodetect 列出所有的GPIO控制器 gpiodetect(无参数) 列出所有的GPIO控制器
gpioinfo 列出gpio控制器的引脚情况 gpioinfo 1 列出第一组控制器引脚组情况
gpioset 设置gpio gpioset 1 4=0 设置第一组控制器编号4引脚为低电平
gpioget 获取gpio引脚状态 gpioget 1 4 获取第一组控制器编号4的引脚状态
gpiomon 监控gpio的状态 gpiomon 1 4 监控第一组控制器编号4的引脚状态
  1. 测试,运行 gpiodetect 或 gpioinfo
    在这里插入图片描述

三、libgpiod应用代码

常用的 libgpiod API
//成员变量
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);
程序编写
  • 这里控制的引脚是 GPIO1_A4
  • 编译时要依赖共享库和头文件
#include <gpiod.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int main(int argc, char **argv){
    int ret;
    struct gpiod_chip * chip;      //GPIO控制器句柄
    struct gpiod_line * line;      //GPIO引脚句柄

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

    /*获取GPIO引脚 GPIO1_A4*/
    line = gpiod_chip_get_line(chip, 4);
    if(line == NULL){
        printf("gpiod_chip_get_line error\n");
        goto release_line;
    }

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

    for(int 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;
}

四、参考

野火的《GPIO子系统
仰望&南极光的《交叉编译开源代码(以libgpiod为例)

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐