1. GPIO LED控制
任务目标
在RK3588开发板上编写Linux内核GPIO驱动,控制一个LED引脚实现亮灭与闪烁功能,并提供用户空间验证路径。本案例采用sysfs接口作为控制通道,驱动注册后在 /sys/class/leds/ 下生成设备节点,用户通过写入 brightness 和 trigger 属性即可控制LED。
环境与依赖
- 内核源码树:RK3588 Linux SDK(内核版本5.10或更高)
- 交叉编译工具链:
aarch64-linux-gnu-gcc - 开发板已能启动Linux并支持模块动态加载(
CONFIG_MODULES=y) - 硬件连接:LED正极经限流电阻接GPIO引脚(本例以GPIO0_B2为例,对应引脚编号计算见下文),负极接GND
GPIO编号计算
RK3588使用GPIO控制器分组管理引脚,每组包含A/B/C/D四组,每组8个引脚。GPIO0_B2的编号计算方式为:组基数 + 组内偏移。RK3588的GPIO0基数为32,B组偏移为8,B2即偏移8+2=10,因此GPIO0_B2对应系统GPIO编号为 32 + 8 + 2 = 42。若使用其他引脚,请按此公式换算。
关键完整代码
以下驱动基于LED子系统(leds-gpio),利用内核标准框架避免重复实现字符设备操作,代码短且完整:
// rk3588_led.c
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/leds.h>
#include <linux/gpio.h>
#include <linux/of_gpio.h>
#define LED_GPIO 42 // GPIO0_B2
static struct gpio_led led_data = {
.name = "rk3588:user",
.default_trigger = "none",
.gpio = LED_GPIO,
.active_low = 0,
};
static struct gpio_led_platform_data led_pdata = {
.num_leds = 1,
.leds = &led_data,
};
static struct platform_device led_device = {
.name = "leds-gpio",
.id = -1,
.dev = {
.platform_data = &led_pdata,
},
};
static int __init led_init(void)
{
return platform_device_register(&led_device);
}
static void __exit led_exit(void)
{
platform_device_unregister(&led_device);
}
module_init(led_init);
module_exit(led_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("RK3588 GPIO LED driver");
该驱动注册一个 leds-gpio 平台设备,内核的 leds-gpio 驱动会接管该设备,自动完成GPIO申请、方向设置和sysfs节点创建。无需手动实现文件操作接口。
编译与部署
# 在SDK内核目录下创建驱动文件后,添加Makefile条目
obj-m += rk3588_led.o
# 编译(使用SDK提供的环境脚本)
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- M=$(pwd) modules
# 将生成的 rk3588_led.ko 拷贝到开发板,加载
insmod rk3588_led.ko
验证方法
加载模块后执行以下命令验证功能:
# 1. 确认设备节点已创建
ls /sys/class/leds/
# 预期输出包含:rk3588:user
# 2. 点亮LED
echo 255 > /sys/class/leds/rk3588:user/brightness
# 观察LED应常亮
# 3. 熄灭LED
echo 0 > /sys/class/leds/rk3588:user/brightness
# 观察LED应熄灭
# 4. 闪烁(使用内核心跳触发器)
echo "heartbeat" > /sys/class/leds/rk3588:user/trigger
# 观察LED应以约1Hz频率闪烁
# 5. 恢复手动控制
echo "none" > /sys/class/leds/rk3588:user/trigger
echo 255 > /sys/class/leds/rk3588:user/brightness
通过判定标准:上述5步操作中,LED状态与写入值一一对应,且 trigger 切换后闪烁行为正确,即表示驱动工作正常。若LED无响应,请检查GPIO编号是否与硬件连接一致,以及 dmesg 中是否有GPIO占用冲突提示。
常见问题
- GPIO被占用:使用
cat /sys/kernel/debug/gpio查看引脚状态,确认无其他驱动占用。 - 引脚编号错误:RK3588的GPIO编号需按
组基数(32×组号) + 组内偏移计算,不同Bank基数为32的整数倍。 - LED不亮但无报错:检查
active_low字段,若LED共阳接法需设为1。