设备树驱动代码解析:从结构到实践(一)—— 初识设备树
2026/6/1 19:15:03 网站建设 项目流程

本文是设备树驱动修改系列的第一篇,旨在帮助新手理解设备树(Device Tree)的基本结构、常见节点含义以及修改设备树的通用流程。下一篇将结合具体修改案例,手把手演示如何修改设备树驱动。

一、为什么需要设备树?

在 Linux 内核中,设备树(Device Tree)是一种描述硬件配置的数据结构。它告诉内核:板子上有哪些硬件(如 CPU、内存、I2C 设备、SPI 设备、GPIO 等),它们之间如何连接,占用哪些资源(中断号、地址、引脚复用等)。

简单说:设备树是“硬件的说明书”,内核启动时读取它,就知道该怎么初始化各个外设。

与传统的硬编码方式相比,设备树使得同一份内核可以支持多种不同的板子,只需更换设备树文件即可。


二、设备树文件的基本结构

以你提供的OK3568-C-common-old.txt为例,一个典型的设备树文件包含以下几大部分:

2.1 头文件包含(#include

dts

#include <dt-bindings/gpio/gpio.h> #include <dt-bindings/pwm/pwm.h> #include <dt-bindings/input/rk-input.h> #include "rk3568.dtsi"
  • dt-bindings/...:这些是设备树中常用的宏定义文件,例如GPIO_ACTIVE_HIGHKEY_VOLUMEUP等。

  • rk3568.dtsi:这是 Rockchip 官方提供的 SoC(片上系统)级设备树包含文件,定义了 RK3568 芯片内部的所有外设(如 I2C、SPI、UART、PWM 控制器等)及其默认配置。板级设备树通过&引用这些节点并覆盖属性。

2.2 根节点/和板级描述

dts

/ { model = "Forlinx OK3568-C Board"; compatible = "forlinx,ok3568", "rockchip,rk3568-evb1-ddr4-v10", "rockchip,rk3568"; ... };
  • model:板子的名称,仅用于人类阅读。

  • compatible:内核用来匹配设备驱动的字符串,通常格式为厂商,板名。多个值表示兼容多种板型。

2.3 板级自定义设备(如面板、背光、按键等)

dts

edp-panel { ... }; panel { ... }; rgb-panel { ... }; adc_keys { ... }; leds { ... }; hdmi_sound { ... }; ...

这些节点描述了板子上额外的硬件,它们不是 SoC 内部集成的外设,而是通过 GPIO、PWM、I2C 等总线连接的外部器件。

例如edp-panel节点定义了一个 eDP 显示屏:

  • compatible = "simple-panel"表示这是一个通用面板,驱动由内核的simple-panel驱动处理。

  • backlight = <&edp_backlight>引用了一个背光节点,用于控制亮度。

  • enable-gpios指定了控制面板使能的 GPIO 引脚。

2.4 电源管理节点(regulator-fixed

dts

vcc12v: vcc-12v { ... }; vcc5v0_sys: vcc5v0-sys { ... }; 5g-rst { ... }; 5g-pwr { ... }; ...

这些节点用于描述板上的固定电压稳压器或电源控制开关。例如5g-rst节点:

  • compatible = "regulator-fixed"表示这是一个输出电压固定的稳压器。

  • gpio = <&gpio1 RK_PB2 GPIO_ACTIVE_LOW>表示通过 GPIO 控制该稳压器的使能。

  • enable-active-low表示 GPIO 低电平时使能。

  • regulator-boot-onregulator-always-on表示系统启动时自动打开且一直保持。

2.5 引用 SoC 外设并覆盖属性

dts

&i2c2 { status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&i2c2m1_xfer>; ... };
  • &i2c2表示引用rk3568.dtsi中定义的 I2C2 控制器节点。

  • status = "okay"启用该 I2C 总线(disabled表示禁用)。

  • pinctrl-0指定引脚复用配置(例如使用哪一组引脚作为 I2C 的 SCL/SDA)。

  • 大括号内定义的是挂载在该 I2C 总线上的设备(如摄像头、触摸屏、对焦马达等)。

2.6 引脚复用配置(&pinctrl

dts

&pinctrl { touch { touch_gpio: touch-gpio { rockchip,pins = <1 RK_PA4 RK_FUNC_GPIO &pcfg_pull_up>, <1 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>; }; }; ... };
  • rockchip,pins是 Rockchip 平台特有的属性,用于配置引脚功能。

  • 格式:<bank pin func config>。例如<1 RK_PA4 RK_FUNC_GPIO &pcfg_pull_up>表示将 GPIO1_A4 设置为普通 GPIO 功能,并使能上拉。

  • 这些引脚组可以在外设节点中通过pinctrl-0 = <&touch_gpio>引用。


三、常见节点类型及含义

节点类型作用关键属性
simple-panel显示屏面板backlight,enable-gpios,display-timings
pwm-backlight背光控制器pwms = <&pwmX 0 周期 0>,brightness-levels
regulator-fixed固定电压稳压器gpio,enable-active-high/low,regulator-boot-on
adc-keysADC 按键io-channels,keyup-threshold,press-threshold
gpio-ledsGPIO 控制的 LEDgpios,linux,default-trigger
i2c节点下的子设备挂载在 I2C 总线上的设备reg(I2C 地址),compatible
spi节点下的子设备挂载在 SPI 总线上的设备reg(片选号),spi-max-frequency
pinctrl中的组定义引脚复用rockchip,pins

四、编写或修改设备树的通用规则

4.1 语法规则

  • 每个节点以节点名 { ... };形式定义,必须以分号结束。

  • 属性赋值:属性名 = 值;

  • 值可以是数字(<123>)、字符串("string")、数组(<1 2 3>)、引用(&标签)。

  • 标签(标签: 节点名 { ... })方便其他节点引用。

4.2 引脚复用的核心原则

  • 一个引脚在同一时间只能被一个外设使用。如果你把某个引脚配置为 I2C 的 SCL,就不能再把它当作 GPIO 或 UART 的 TX。

  • 修改引脚功能时,必须找到原功能所在的节点并禁用或移除其pinctrl引用,然后为新功能配置新的pinctrl组。

4.3 节点状态的默认值

  • SoC 级 dtsi 中的大部分外设默认是status = "disabled",板级 dts 中根据需要启用(okay)。

  • 如果某个外设你不需要,可以保持disabled或显式地禁用。

4.4 覆盖节点属性

  • 使用&标签 { 新属性; };来覆盖或追加属性。

  • 如果你重复定义同一个属性,后面的会覆盖前面的。

4.5 常用宏和头文件

  • 使用#include <dt-bindings/...>引入预定义的宏,避免硬编码数字。

  • 例如GPIO_ACTIVE_HIGH比直接写0更可读。


五、工作中修改设备树驱动的标准流程

当你需要修改设备树来适配新的硬件或释放某个引脚时,建议按以下步骤操作:

步骤 1:理解需求

  • 明确你要修改的硬件是什么?例如:要把 I2C2 引脚改为 CAN2 功能,或者禁用某个 GPIO 输出。

  • 查阅原理图和芯片数据手册,确认引脚编号和功能号(Alt 值)。

步骤 2:找到原始设备树文件

  • 通常内核源码中arch/arm64/boot/dts/rockchip/下有板级 dts 文件。

  • 你可以用findgrep搜索节点名。

步骤 3:备份原始文件

  • 使用版本控制(如 Git)或直接复制备份。

步骤 4:定位要修改的节点

  • 如果是修改某个外设的引脚,找到该外设的节点(例如&i2c2)。

  • 如果是释放某个 GPIO,找到占用该 GPIO 的节点(如5g-rst)。

步骤 5:进行修改

  • 禁用旧功能:将冲突外设的status改为disabled,或删除其pinctrl-0中的引脚组。

  • 新增 pinctrl 组:在&pinctrl节点中定义新的引脚组,指定正确的引脚和功能号。

  • 启用新功能:将外设节点的status改为okay,并添加正确的pinctrl-0引用。

步骤 6:编译设备树

cd /home/forlinx/3568/OK3568-linux-source
./build.sh kernel
生成boot.img

步骤 7:烧写并测试

步骤 8:验证功能

  • 如果是新启用的外设(如 CAN2),使用candumpcansend等工具测试通信。

  • 如果是释放的 GPIO,通过/sys/class/gpio测试输入输出。


六、常见问题与技巧

Q1:如何知道某个引脚当前被谁使用?

  • 运行cat /sys/kernel/debug/pinctrl/pinctrl-rockchip-pinctrl/pinmux-pins

  • 输出会显示每个引脚当前的 owner(哪个驱动)和功能。


七、结语

本文从设备树的基本结构出发,介绍了常见节点类型、修改规则和实际工作流程,希望对初次接触设备树的开发者有所帮助。下一篇我们将基于具体的修改案例(例如:把 I2C2 改为 CAN2、禁用 5G 电源控制、释放 SPI 片选等),手把手演示每一步的修改细节,敬请期待。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询