Linux下如何获取GPIO引脚的具体编号?

在Linux系统中,GPIO(General Purpose Input/Output,通用输入输出)是一种常见的硬件接口,用于控制外部设备或读取外部信号,要正确操作GPIO,首先需要获取其对应的GPIO号,Linux内核通过多种方式管理和暴露GPIO,用户或开发者可通过设备树、sysfs接口或编程库(如libgpiod)来获取GPIO号,本文将详细介绍这些方法的具体步骤和原理。

linux如何获得gpio号

GPIO号的基本概念

Linux中的GPIO号并非硬件上的固定编号,而是内核根据GPIO控制器的层级结构分配的逻辑编号,常见的编号方式有两种:线性编号分层编号

  • 线性编号:早期Linux版本采用全局线性编号,所有GPIO控制器的GPIO统一从0开始连续编号,例如GPIO 0、GPIO 1……GPIO 100,这种方式简单直接,但在多控制器系统中容易冲突,且难以追溯GPIO所属的控制器。
  • 分层编号:现代Linux内核推荐分层编号,格式为<chip_name>:<offset>,其中chip_name是GPIO控制器的名称(如gpiochip0),offset是该GPIO在控制器内的偏移量(从0开始),例如gpiochip0:18表示gpiochip0控制器的第18个GPIO,这种编号方式清晰且可扩展,是当前的主流方式。

通过设备树获取GPIO号

设备树(Device Tree, DT)是描述硬件结构的数据结构,Linux内核通过解析设备树来识别硬件资源,包括GPIO,在设备树中,GPIO通常通过gpio属性或pinctrl属性定义,开发者可通过以下步骤获取GPIO号:

定位设备树中的GPIO定义

在设备树源文件(.dts)中,外设节点(如LED、按键)会通过gpio属性引用GPIO,格式为:

led-gpio = <&gpio1 18 GPIO_ACTIVE_HIGH>;
  • &gpio1:引用名为gpio1的GPIO控制器节点(需在设备树中定义gpio-controller属性);
  • 18:GPIO在控制器内的偏移量;
  • GPIO_ACTIVE_HIGH:GPIO的有效电平(高电平有效,可选参数)。

解析控制器节点获取基址

GPIO控制器节点(如gpio1)通常包含#gpio-cellsreg属性:

  • #gpio-cells:指定GPIO描述符的元数(通常为2,分别对应偏移量和有效电平);
  • reg:控制器的寄存器基地址,用于内核分配线性编号时的基址计算。

内核在启动时会解析设备树,为每个GPIO控制器分配线性编号的基址(base)和GPIO数量(ngpio),例如gpio1base为32,ngpio为32,则其管理的GPIO线性编号为32-63。

计算线性GPIO号

若需线性编号,可通过公式计算:
线性GPIO号 = 控制器基址(base) + 偏移量(offset)
例如gpio1base为32,偏移量为18,则线性GPIO号为32+18=50。

查看设备树解析后的GPIO信息

内核启动后,可通过/proc/device-treelibfdt工具查看解析后的GPIO信息,查看gpio1控制器的基址和数量:

cat /sys/class/gpio/gpiochip32/base  # 输出基址(如32)
cat /sys/class/gpio/gpiochip32/ngpio # 输出GPIO数量(如32)

通过sysfs接口获取GPIO号

sysfs是Linux内核提供的虚拟文件系统,用于导出硬件信息,虽然新版本内核推荐使用libgpiod,但sysfs仍可用于获取GPIO号,尤其适用于快速调试。

查看GPIO控制器信息

所有GPIO控制器位于/sys/class/gpio/目录下,名称格式为gpiochipNN为控制器编号),通过以下命令列出所有控制器:

ls /sys/class/gpio/ | grep gpiochip

进入某个控制器目录(如gpiochip0),可查看其管理的GPIO范围:

linux如何获得gpio号

cat /sys/class/gpio/gpiochip0/base  # 控制器起始GPIO号(线性编号)
cat /sys/class/gpio/gpiochip0/ngpio # 控制器管理的GPIO总数

gpiochip0base为0,ngpio为64,则其管理的GPIO号为0-63。

导出并获取GPIO号

若需操作特定GPIO,可通过export文件导出(需root权限):

echo <gpio_number> > /sys/class/gpio/export

导出后,系统会在/sys/class/gpio/下创建gpioN目录(N为线性GPIO号),例如导出GPIO 18后,路径为/sys/class/gpio/gpio18

通过GPIO属性验证

gpioN目录中,label文件可能包含GPIO的硬件描述(若设备树中定义),可用于确认GPIO号是否正确:

cat /sys/class/gpio/gpio18/label

若输出类似GPIO18或外设名称(如LED_GREEN),则说明GPIO号正确。

sysfs关键文件说明

下表总结了sysfs中与GPIO相关的关键文件及其作用:

文件路径 作用说明
/sys/class/gpio/export 导出GPIO,写入线性GPIO号后创建gpioN目录
/sys/class/gpio/unexport 取消导出GPIO,写入线性GPIO号删除gpioN目录
/sys/class/gpio/gpiochipN/base GPIO控制器gpiochipN的起始线性GPIO号
/sys/class/gpio/gpiochipN/ngpio GPIO控制器gpiochipN管理的GPIO总数
/sys/class/gpio/gpioN/value GPIO的值(0/1,输出模式时写入,输入模式时读取)
/sys/class/gpio/gpioN/direction GPIO方向(in输入/out输出)

通过libgpiod库获取GPIO号

libgpiod是Linux官方推荐的GPIO操作库,支持分层编号,功能更完善且安全,以下以C语言为例,说明如何通过libgpiod获取GPIO号:

安装libgpiod工具和库

sudo apt install gpiod libgpiod-dev  # 安装工具和开发库

使用命令行工具查看GPIO信息

  • gpiodetect:列出所有GPIO控制器及其名称和偏移量范围:

    gpiodetect
    # 输出示例:gpiochip0 [gpio0] (32 lines), gpiochip1 [gpio1] (32 lines)

    其中gpiochip0 [gpio0]表示控制器名称为gpiochip0,管理的GPIO偏移量为0-31。

  • gpioinfo:查看指定控制器的GPIO线信息(包括偏移量、名称、方向等):

    linux如何获得gpio号

    gpioinfo gpiochip0
    # 输出示例:
    # line 0:      "GPIO0"       unused input active-high
    # line 1:      "GPIO1"       unused input active-high
    # ...
    # line 18:     "LED_GREEN"   output active-high [used]

    输出中的line 18即偏移量为18的GPIO,结合控制器名称gpiochip0,分层编号为gpiochip0:18

编程获取GPIO号

使用libgpiod库打开控制器并获取GPIO线的偏移量:

#include <gpiod.h>
#include <stdio.h>
int main() {
    const char *chipname = "gpiochip0"; // 控制器名称
    struct gpiod_chip *chip;
    struct gpiod_line *line;
    int offset = 18; // 目标GPIO偏移量
    // 打开GPIO控制器
    chip = gpiod_chip_open_by_name(chipname);
    if (!chip) {
        perror("Failed to open chip");
        return 1;
    }
    // 获取GPIO线
    line = gpiod_chip_get_line(chip, offset);
    if (!line) {
        perror("Failed to get line");
        gpiod_chip_close(chip);
        return 1;
    }
    // 输出GPIO信息
    printf("Controller: %sn", gpiod_chip_name(chip));
    printf("Offset: %dn", gpiod_line_offset(line));
    printf("Name: %sn", gpiod_line_name(line) ? gpiod_line_name(line) : "unnamed");
    gpiod_line_release(line);
    gpiod_chip_close(chip);
    return 0;
}

编译并运行:

gcc -o gpio_info gpio_info.c -lgpiod
./gpio_info

输出将包含控制器名称、偏移量及GPIO名称,通过控制器名称:偏移量即可得到分层GPIO号。

获取Linux GPIO号的方法需根据场景选择:

  • 设备树开发:通过解析设备树中的gpio属性和控制器节点,结合基址和偏移量计算线性编号,或直接使用分层编号<chip_name>:<offset>
  • 快速调试:使用sysfs接口,通过gpiochipN目录的basengpio确定GPIO范围,或导出GPIO后查看label文件验证。
  • 编程开发:推荐使用libgpiod库,通过gpiodetectgpioinfo命令查看GPIO信息,或调用API获取控制器和偏移量,形成分层编号。

随着Linux内核的发展,分层编号和libgpiod已成为主流,建议新项目优先采用,以提高代码的可读性和可维护性。

相关问答FAQs

Q1: 为什么在设备树中定义了GPIO,但通过gpioinfo却找不到对应的GPIO线?
A: 可能的原因包括:

  1. 设备树未正确编译到内核或设备树文件(.dtb)未加载到系统中,可通过fdt addr命令检查设备树地址;
  2. GPIO控制器驱动未加载,可通过lsmod | grep <controller_driver>查看驱动是否加载,或手动加载(如modprobe gpio_ich);
  3. GPIO已被其他设备占用,可通过gpioinfo查看[used]标记,或检查/sys/class/gpio/gpioN目录是否存在。

Q2: sysfs和libgpiod有什么区别?什么场景下使用哪种?
A: 区别如下:

  • sysfs:是传统接口,通过文件操作GPIO,简单直观,但功能有限(如不支持原子操作),且存在并发安全问题(多进程同时操作同一GPIO时易冲突)。
  • libgpiod:是现代库,基于字符设备(/dev/gpiochipN),支持分层编号、原子操作、多线程安全,并提供命令行工具和API接口。

场景选择

  • 快速调试或简单脚本操作,可使用sysfs;
  • 驱动开发、复杂应用程序或需要稳定性的项目,推荐使用libgpiod。

原创文章,发布者:酷番叔,转转请注明出处:https://cloud.kd.cn/ask/34996.html

(0)
酷番叔酷番叔
上一篇 2025年10月3日 10:55
下一篇 2025年10月3日 11:13

相关推荐

  • 修改Linux防火墙规则?firewalld/ufw/iptables全指南

    修改前的关键准备备份现有规则 sudo iptables-save > ~/iptables_backup.txt # iptables备份sudo cp /etc/ufw/user.rules ~/ufw_backup.rules # ufw备份查看当前规则 sudo firewall-cmd –li……

    2025年8月8日
    17400
  • 自研Linux程序如何实现版本升级?

    自己编写的Linux程序升级是一个涉及版本管理、代码更新、编译构建、部署策略、回滚机制等多环节的系统工程,合理的升级流程能确保程序稳定性并减少服务中断风险,以下从实际操作角度详细拆解升级全流程,版本规划与代码管理升级前需明确版本规则,通常采用“主版本号.次版本号.修订号”(如1.2.3),主版本号表示重大功能变……

    2025年9月29日
    17600
  • 笔记本如何安装Linux系统?

    安装Linux系统到笔记本是许多用户追求个性化、高性能或学习开源技术的选择,整个过程可分为准备工作、制作启动介质、安装系统、后续配置等步骤,以下是详细指南:安装前的准备工作选择Linux发行版不同发行版适合不同用户群体,需根据需求选择:Ubuntu:对新手友好,软件生态丰富,社区支持完善,适合日常办公和娱乐,F……

    2025年9月25日
    17700
  • Linux应用开发如何入门?步骤、工具与环境全解析

    Linux下开发应用是一个系统化工程,涉及环境搭建、语言选择、工具链使用、调试优化及部署等多个环节,其核心优势在于开源生态的丰富性、系统级访问能力以及跨平台兼容性,适合从系统底层到高层应用的全场景开发,以下从关键步骤展开说明,开发环境搭建开发环境是应用开发的基础,需根据目标应用类型(如系统工具、Web服务、桌面……

    2025年9月23日
    15900
  • linux如何修改本机ip地址

    在Linux系统中修改本机IP地址是日常运维和开发中的常见操作,根据不同的Linux发行版和网络管理工具,操作方法略有差异,本文将详细介绍通过命令行、配置文件及图形界面三种主流方式修改IP地址的具体步骤,并对比不同发行版的配置差异,通过命令行临时修改IP地址命令行修改IP地址分为ifconfig(传统工具)和i……

    2025年9月16日
    16200

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

联系我们

400-880-8834

在线咨询: QQ交谈

邮件:HI@E.KD.CN

关注微信