1. GPIO输出控制LED闪烁

任务目标

在RK3588平台上,通过Linux GPIO子系统控制一个连接到GPIO引脚的LED灯,使其以1Hz频率(亮500ms、灭500ms)持续闪烁。本案例聚焦于GPIO字符设备接口(/dev/gpiochipN)的使用,不涉及设备树配置。

硬件连接

将LED正极(长脚)通过220Ω限流电阻连接到RK3588开发板的GPIO引脚(本例使用GPIO0_B2,对应芯片引脚编号10),LED负极接地。实际引脚号请根据你的开发板原理图确认。

环境依赖

  • RK3588 Linux开发板,内核版本≥5.10(支持标准GPIO字符设备接口)
  • 交叉编译工具链(若在主机上编译)或板载GCC(若在板端直接编译)
  • libgpiod库(可选,若使用gpioset命令行工具验证)

关键完整代码

以下程序直接操作GPIO字符设备,不依赖外部库,仅使用Linux系统调用:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/gpio.h>
#include <errno.h>

#define GPIO_CHIP_DEV   "/dev/gpiochip0"
#define LED_LINE_OFFSET 10      // GPIO0_B2 在gpiochip0中的偏移量
#define TOGGLE_INTERVAL_MS 500  // 500ms翻转一次,实现1Hz闪烁

int main(void)
{
    int fd, ret;
    struct gpiohandle_request req;
    struct gpiohandle_data data;

    // 打开GPIO控制器
    fd = open(GPIO_CHIP_DEV, O_RDONLY);
    if (fd < 0) {
        perror("打开gpiochip失败");
        return EXIT_FAILURE;
    }

    // 请求LED引脚为输出模式
    memset(&req, 0, sizeof(req));
    req.lineoffsets[0] = LED_LINE_OFFSET;
    req.flags = GPIOHANDLE_REQUEST_OUTPUT;
    req.default_values[0] = 0;   // 初始状态:低电平(LED灭)
    req.lines = 1;
    strcpy(req.consumer_label, "led_blink");

    ret = ioctl(fd, GPIO_GET_LINEHANDLE_IOCTL, &req);
    if (ret < 0) {
        perror("请求GPIO行失败");
        close(fd);
        return EXIT_FAILURE;
    }
    close(fd);  // chip fd在获取line handle后可关闭

    // 循环翻转LED状态
    for (int i = 0; i < 20; i++) {  // 闪烁10次后退出
        data.values[0] = (i % 2 == 0) ? 1 : 0;  // 偶数次亮,奇数次灭
        ret = ioctl(req.fd, GPIOHANDLE_SET_LINE_VALUES_IOCTL, &data);
        if (ret < 0) {
            perror("设置GPIO值失败");
            break;
        }
        usleep(TOGGLE_INTERVAL_MS * 1000);
    }

    // 清理:释放line handle
    close(req.fd);
    printf("LED闪烁测试完成\n");
    return EXIT_SUCCESS;
}

编译与运行

# 在板端直接编译
gcc -o led_blink led_blink.c

# 运行(需要root权限)
sudo ./led_blink

验证方法

  1. 视觉验证:运行程序后,LED应以1Hz频率闪烁(每500ms翻转一次状态),持续10个周期后程序自动退出。
  2. 逻辑验证:程序退出时输出"LED闪烁测试完成",且无错误信息。
  3. 手动验证:程序运行期间,可用gpioset命令(若已安装libgpiod工具)检查引脚状态:gpioset --mode=time --usec=100 0 10=1(将GPIO0_B2拉高1秒后恢复),观察LED是否点亮。

常见问题

  • 打开gpiochip失败:确认设备节点存在(ls /dev/gpiochip*),若无则需加载gpio_rk3588内核模块。
  • 行偏移量错误:不同开发板的GPIO编号映射可能不同,用gpioinfo命令查看实际偏移量。
  • 权限不足:确保以root用户运行,或将当前用户加入gpio组。