从设备树到驱动代码:在RK3566上点亮一个LED的完整实战流程(基于GPIO0_B4)

📅 2026/7/15 20:00:14 👁️ 阅读次数 📝 编程学习
从设备树到驱动代码:在RK3566上点亮一个LED的完整实战流程(基于GPIO0_B4)

从设备树到驱动代码:在RK3566上点亮一个LED的完整实战流程(基于GPIO0_B4)

嵌入式开发中,点亮LED是最经典的入门实验,但很多新手在从理论到实践的过程中会遇到各种障碍。本文将基于ROC-RK3566-PC开发板,以GPIO0_B4引脚为例,带你完成从硬件连接到驱动加载的全过程。不同于碎片化的知识点讲解,这里会呈现一个完整的项目闭环——包括设备树修改、驱动编写、内核编译和测试验证,让你获得真实的开发体验。

1. 硬件准备与环境搭建

在开始编码之前,我们需要确保硬件连接正确且开发环境就绪。ROC-RK3566-PC开发板提供了丰富的扩展接口,GPIO0_B4位于板载的40pin排针上,具体位置可以参考开发板的原理图。

所需材料清单

  • ROC-RK3566-PC开发板
  • LED灯(建议使用3mm或5mm普通发光二极管)
  • 220Ω限流电阻
  • 杜邦线若干
  • 万用表(可选,用于调试)

硬件连接示意图:

ROC-RK3566-PC GPIO0_B4 ----[220Ω]---- LED(+) ---- LED(-) ---- GND

注意:LED有正负极之分,长脚为正极。如果接反不会损坏器件,但不会发光。

开发环境配置要点:

# 安装交叉编译工具链 sudo apt install gcc-aarch64-linux-gnu # 获取内核源码(假设已下载RK3566 SDK) cd ~/rk3566_sdk/kernel make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- rockchip_defconfig

2. 设备树节点配置

设备树(Device Tree)是现代Linux内核管理硬件资源的核心机制。我们需要在设备树中声明GPIO的使用方式,让内核知道如何管理这个引脚。

找到设备树文件(通常位于kernel/arch/arm64/boot/dts/rockchip/rk356x-firefly-demo.dtsi),添加以下节点:

gpio_led: gpio_led { status = "okay"; compatible = "firefly,rk356x-gpio"; led-gpio = <&gpio0 RK_PB4 GPIO_ACTIVE_HIGH>; };

关键参数解析:

参数说明
&gpio0指定GPIO控制器
RK_PB4对应GPIO0_B4引脚的宏定义
GPIO_ACTIVE_HIGH高电平有效

GPIO编号计算小技巧:

  • GPIO0_B4 = bank(0) * 32 + group(B)8 + pin(4) = 0 + 18 + 4 = 12
  • 但实际使用时推荐直接使用RK_PB4宏,避免手动计算错误

3. 驱动代码实现

创建一个新的驱动文件gpio_led.c,实现最基本的LED控制功能:

#include <linux/module.h> #include <linux/platform_device.h> #include <linux/gpio/consumer.h> struct gpio_led_data { struct gpio_desc *led_gpio; }; static int gpio_led_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct gpio_led_data *data; int ret; data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); if (!data) return -ENOMEM; >obj-m := gpio_led.o KDIR := /path/to/your/kernel PWD := $(shell pwd) all: make -C $(KDIR) M=$(PWD) modules

4. 编译与加载测试

完成代码编写后,我们需要编译内核模块并加载测试:

# 编译内核模块 make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j$(nproc) # 将生成的gpio_led.ko拷贝到开发板 scp gpio_led.ko root@开发板IP:/root/ # 在开发板上加载模块 insmod gpio_led.ko # 查看驱动打印信息 dmesg | tail

如果一切正常,你应该能看到LED灯亮起,同时dmesg输出类似:

[ 123.456789] LED GPIO initialized

5. 进阶调试技巧

当驱动不工作时,可以尝试以下调试方法:

sysfs快速验证法

# 导出GPIO echo 12 > /sys/class/gpio/export # 设置方向为输出 echo out > /sys/class/gpio/gpio12/direction # 控制LED echo 1 > /sys/class/gpio/gpio12/value # 点亮 echo 0 > /sys/class/gpio/gpio12/value # 熄灭

常见问题排查表

现象可能原因解决方案
LED不亮GPIO被其他功能占用检查设备树中是否有冲突配置
驱动加载失败设备树节点未启用确认status = "okay"
权限不足未以root运行使用sudo或切换到root用户
GPIO值无法改变时钟未开启检查CRU_CLKGATE_CON寄存器

6. 项目扩展思路

掌握了基础LED控制后,可以尝试以下扩展:

  1. 添加用户空间接口

    • 创建字符设备实现ioctl控制
    • 通过sysfs属性添加亮度调节
  2. 实现呼吸灯效果

    // 简易PWM实现 for (int i = 0; i < 100; i++) { gpiod_set_value(led_gpio, 1); usleep(i * 100); gpiod_set_value(led_gpio, 0); usleep((100 - i) * 100); }
  3. 结合中断实现按键控制

    // 注册中断处理函数 request_irq(gpio_to_irq(button_gpio), button_handler, IRQF_TRIGGER_RISING, "gpio_button", NULL);

在实际项目中,GPIO操作往往只是起点。通过这个简单的LED实验,你已经掌握了嵌入式Linux开发中最核心的设备树配置、驱动编写和调试技能,这些方法同样适用于更复杂的传感器和外设开发。