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

从设备树到驱动代码:在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 ARCHarm64 CROSS_COMPILEaarch64-linux-gnu- rockchip_defconfig2. 设备树节点配置设备树(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) modules4. 编译与加载测试完成代码编写后我们需要编译内核模块并加载测试# 编译内核模块 make ARCHarm64 CROSS_COMPILEaarch64-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 initialized5. 进阶调试技巧当驱动不工作时可以尝试以下调试方法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控制后可以尝试以下扩展添加用户空间接口创建字符设备实现ioctl控制通过sysfs属性添加亮度调节实现呼吸灯效果// 简易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); }结合中断实现按键控制// 注册中断处理函数 request_irq(gpio_to_irq(button_gpio), button_handler, IRQF_TRIGGER_RISING, gpio_button, NULL);在实际项目中GPIO操作往往只是起点。通过这个简单的LED实验你已经掌握了嵌入式Linux开发中最核心的设备树配置、驱动编写和调试技能这些方法同样适用于更复杂的传感器和外设开发。