RK平台操作GPIO的两种方法

RK平台操作GPIO的两种方法

在嵌入式开发调试过程中,操作 GPIO 是一个至关重要的技能。通过操作 GPIO,我们可以控制外部设备,比如开关LED灯、开关模块电源、复位外设等。本文将分享两种在 RK 平台上通过 ADB 或者调试串口就能操作 GPIO 的方法。

直接操作寄存器

这种方式可以直接通过操作 CPU 的寄存器,精准控制每一个 GPIO 引脚的状态,简单直接。缺点就是需要查阅芯片手册,并且要求板子上有 IO 指令,IO 指令的使用方法可以看前面的文章。
下面以拉高 RK3399 的 GPIO2_D3 为例来说明:

  • 查GRF基址
    从 RK3399 的 TRM 手册 Address Mapping 章节获得 GRF 基址为:0xFF770000:
    GRF 基址
  • 查IOMUX偏移址
    IOMUX 管理每个 GPIO 口的功能复用,从 GRF Register Description 章节找到 GRF_GPIO2D_IOMUX 偏移地址为 0x0000E00C:
    IOMUX 偏移址
  • 设置 IOMUX 寄存器
    找到 IOMUX 寄存器的描述:
    IOMUX 寄存器
    可以看到 bit[7:6] 设置为 2’b00 的时候,该 GPIO 为 GPIO 功能,由于 bit[31:16] 为写允许位,bit[7:6] 对应的写允许位 bit[23:22] 为2’b11,因此实际写入的寄存器值为0x00C00000:
io -4 0xFF77E00C 0x00C00000
  • 查 PU/PD 偏移址
    PU/PD 控制每个 GPIO 口的拉低和拉高,从 GRF Register Description 章节找到 GRF_GPIO2D_P 偏移地址为 0x0000E04C:
    PU/PD偏移址
  • 设置 PU/PD 寄存器
    找到 PU/PD 寄存器的描述:
    PU/PD 寄存器
    可以看到 bit[7:6] 设置为 2’b11 的时候,该 GPIO 是拉高状态(pull-up),由于 bit[31:16] 为写允许位,bit[7:6] 对应的写允许位 bit[23:22] 为2’b11,因此实际写入的寄存器值为0x00C000C0:
io -4 0xFF77E04C 0x00C000C0

通过 Sysfs 接口

Sysfs 接口是 kernel 给用户空间提供的接口,可以把设备和驱动程序从内核输出到用户空间,也可以用来对设备和驱动程序做设置,因此也为 GPIO 提供了简便的操作方式。通过文件系统对 GPIO 进行配置和控制,可以避免直接操作寄存器的复杂性。但是,要通过 Sysfs 接口来操作,前提是系统没有使用到对应的 GPIO 口,设备的 dts 文件也没有对该 GPIO 口有定义,否则可能会导致操作失败。
下面同样以拉高 RK3399 的 GPIO2_D3 为例来说明:

  • 计算 GPIO 编号
    GPIO 的编号计算公式为:GPIO2_D3=2x32+(D-A)x8+3=2x32+3x8+3=91,因此 GPIO2_D3 的编号是 91。
  • 导出GPIO
echo 91 > /sys/class/gpio/export
  • 配置为输出模式
echo "out" > /sys/class/gpio/gpio91/direction
  • 设置输出值
echo "1" > /sys/class/gpio/gpio91/value  # 高电平
echo "0" > /sys/class/gpio/gpio91/value  # 低电平

Sysfs 接口适合开发者快速上手 GPIO 控制,无需复杂的底层操作,适合简单的项目或测试使用。

总结

在 RK 平台上操作 GPIO 有多种方法,以上是个人在 RK 平台开发调试过程经常用到的方法,在项目开发中可以根据现场条件选择最适合的方式。

欢迎关注公众号“我的RK随记”,获取更多技术分享!

<think>好的,我现在需要帮助用户了解如何在RK3588平台上控制GPIO。用户还要求示例代码和配置教程。让我先理清楚已有的信息和需要补充的内容。 首先,根据提供的引用资料,特别是引用[3]和[4],RK3588的GPIO控制可以通过sysfs接口或新的字符设备接口(libgpiod)来实现。sysfs是比较传统的方法,而libgpiod提供了更多功能,比如更好的进程关联和事件处理。用户可能需要这两种方法的示例,所以应该都包括进去。 接下来,引用[5]提到了在内核阶段操作寄存器的方法,但用户可能更倾向于应用层的控制,所以暂时可以专注于用户空间的GPIO控制方法。不过,可能也需要简要提及内核驱动的方法,以备用户参考。 用户需要示例代码,所以我要确保代码部分正确,并且符合RK3588的平台特性。例如,GPIO编号的计算可能与其他平台不同,需要确认。根据引用[2],RK3399的GPIO分组是GPIO0~GPIO3,而RK3588可能有不同的分组方式,需要查阅相关手册。但用户提供的引用中没有RK3588的具体GPIO分组信息,可能需要假设或提醒用户查阅手册。 另外,引用[3]提到新的字符设备接口(libgpiod)的优势,比如使用gpiod命令行工具,所以应该包括使用libgpiod的示例,比如C代码和命令行操作。 步骤方面,sysfs的步骤通常包括导出GPIO、设置方向、读写值,而libgpiod则需要安装库并使用相应的函数或工具。需要确保步骤清晰,避免遗漏。 可能遇到的问题包括GPIO编号的计算错误、权限问题导致无法访问sysfs文件,或者libgpiod工具未安装。应该在注意事项中提到这些,比如使用sudo或修改权限。 示例代码部分,sysfs的Shell脚本和C程序,以及libgpiod的C代码都需要验证语法正确性,特别是路径和头文件是否正确。例如,sysfs的路径是/sys/class/gpio,而libgpiod需要包含正确的头文件。 配置教程方面,可能需要指导用户如何查找GPIO编号,例如通过芯片手册确定引脚对应的GPIO组和偏移量。引用[2]中提到RK3399的分组方式,但RK3588可能不同,所以需要提醒用户查阅RK3588的具体文档。 此外,引用[4]提到了GPIO输入输出实验的步骤,可以借鉴其中的步骤结构,比如导出、方向设置、读写操作。但需要注意sysfs接口在较新的内核中可能被标记为过时,推荐使用libgpiod,这需要明确说明。 最后,用户可能想知道如何在内核驱动中控制GPIO,但引用中提供的资料主要是用户空间的方法,所以可能需要简要提及设备树配置和驱动代码,但如果没有足够信息,应建议用户参考内核文档或具体示例,如引用[3]中的LED驱动示例。 总结一下,回答需要包括sysfs和libgpiod两种方法,各自的步骤、示例代码和注意事项,同时提醒用户查阅相关文档确认GPIO编号和配置。确保引用正确的资料,如引用[3]和[4]中的方法,并正确标注引用来源。</think>### RK3588 GPIO控制方法详解 在RK3588平台上控制GPIO主要有两种方式:**sysfs传统接口**和**libgpiod字符设备接口**[^3][^4]。以下是具体方法和示例代码: --- #### 一、通过sysfs接口控制GPIO *适用场景:快速调试、简单电平控制* ```bash # 1. 计算GPIO编号(需查阅芯片手册) # 公式:GPIO编号 = 组号×32 + 引脚号 # 例如GPIO4_A5:4×32 + 5 = 133 # 2. 导出GPIO echo 133 > /sys/class/gpio/export # 3. 设置方向 echo out > /sys/class/gpio/gpio133/direction # 4. 控制电平 echo 1 > /sys/class/gpio/gpio133/value # 输出高电平 echo 0 > /sys/class/gpio/gpio133/value # 输出低电平 # 5. 取消导出 echo 133 > /sys/class/gpio/unexport ``` --- #### 二、通过libgpiod接口控制GPIO(推荐) *适用场景:生产环境、复杂控制* 1. 安装依赖库 ```bash sudo apt install gpiod libgpiod-dev ``` 2. C语言示例代码(保存为gpio_ctrl.c) ```c #include <gpiod.h> #include <stdio.h> #include <unistd.h> int main() { const char *chipname = "gpiochip4"; // 对应GPIO组 struct gpiod_chip *chip; struct gpiod_line *line; int ret; // 打开GPIO控制器 chip = gpiod_chip_open_by_name(chipname); if (!chip) { perror("Open chip failed"); return 1; } // 获取GPIO线(A5对应偏移量5) line = gpiod_chip_get_line(chip, 5); if (!line) { perror("Get line failed"); gpiod_chip_close(chip); return 1; } // 设置为输出模式 ret = gpiod_line_request_output(line, "example", 0); if (ret < 0) { perror("Set output failed"); gpiod_chip_close(chip); return 1; } // 控制电平 for (int i=0; i<5; i++) { gpiod_line_set_value(line, 1); sleep(1); gpiod_line_set_value(line, 0); sleep(1); } // 释放资源 gpiod_line_release(line); gpiod_chip_close(chip); return 0; } ``` 3. 编译执行 ```bash gcc gpio_ctrl.c -o gpio_ctrl -lgpiod sudo ./gpio_ctrl ``` --- #### 三、通过gpiod命令行工具 ```bash # 查看可用GPIO控制器 gpiodetect # 设置GPIO4_A5输出高电平 gpioset gpiochip4 5=1 # 读取GPIO输入状态 gpioget gpiochip4 5 ``` --- ### 配置注意事项 1. **GPIO编号计算**:需根据芯片手册确定组号和引脚偏移量,公式为:`全局编号 = 组号×32 + 引脚偏移`[^2] 2. **权限问题**:操作GPIO需要root权限或配置用户组权限 3. **引脚复用**:需通过设备树确认GPIO未被其他功能占用[^2] 4. **内核版本**:Linux 5.x内核推荐使用libgpiod接口 --- ### 驱动开发进阶 对于需要内核级控制的场景,可通过设备树配置: ```dts // 设备树配置示例 leds { compatible = "gpio-leds"; user_led { label = "user_led"; gpios = <&gpio4 5 GPIO_ACTIVE_HIGH>; linux,default-trigger = "heartbeat"; }; }; ``` 配套驱动代码需使用`gpiod_get()`和`gpiod_direction_output()`等API ---
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值