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
验证方法
- 视觉验证:运行程序后,LED应以1Hz频率闪烁(每500ms翻转一次状态),持续10个周期后程序自动退出。
- 逻辑验证:程序退出时输出"LED闪烁测试完成",且无错误信息。
- 手动验证:程序运行期间,可用
gpioset命令(若已安装libgpiod工具)检查引脚状态:gpioset --mode=time --usec=100 0 10=1(将GPIO0_B2拉高1秒后恢复),观察LED是否点亮。
常见问题
- 打开gpiochip失败:确认设备节点存在(
ls /dev/gpiochip*),若无则需加载gpio_rk3588内核模块。 - 行偏移量错误:不同开发板的GPIO编号映射可能不同,用
gpioinfo命令查看实际偏移量。 - 权限不足:确保以root用户运行,或将当前用户加入
gpio组。