3. 设备树常用属性详解
设备树(Device Tree)中的属性(property)是描述硬件配置与连接关系的基本单元。每个节点通过一组标准化的属性向内核驱动传递关键信息,包括设备类型、地址映射、中断路由、电源状态及时钟依赖等。本章将逐一剖析最常用的核心属性,并结合实际案例说明其使用规范与常见陷阱。
学习提示: 设备树属性是驱动与硬件之间的“契约”。理解每个属性的语义与约束,是编写正确设备树文件的前提。建议在阅读本节时,对照实际开发板的手册或内核源码中的设备树绑定文档(Documentation/devicetree/bindings/)进行验证。
3.1 compatible 属性:设备识别与驱动匹配
compatible 是设备树中最关键的属性,它定义了设备与驱动之间的匹配关系。该属性是一个字符串列表,内核通过该列表查找对应的平台驱动(platform driver)。
- 格式:
"厂商,型号"或"通用型号",优先使用厂商前缀以避免命名冲突。 - 匹配顺序: 内核按照字符串在列表中的顺序依次尝试匹配,第一个匹配成功的驱动将被绑定。
- 回退机制: 通常将最具体的型号放在最前面,通用型号放在后面,以实现兼容性。
// 示例:I2C控制器节点
i2c@1c2ac00 {
compatible = "allwinner,sun8i-h3-i2c", "allwinner,sun6i-a31-i2c";
reg = <0x01c2ac00 0x400>;
interrupts = <0 6 4>;
status = "okay";
};
关键点: 驱动匹配时,内核会遍历
of_match_table 中的 .compatible 字符串,与设备树节点中的 compatible 列表逐一比对。因此,驱动中必须包含与设备树完全一致的字符串。
3.2 reg 属性:地址空间与内存映射
reg 属性用于描述设备在系统总线上的地址范围,通常由一组或多组 (地址, 长度) 对组成。其具体含义由父节点的 #address-cells 和 #size-cells 属性决定。
| 属性 | 含义 | 典型值 |
|---|---|---|
#address-cells |
地址字段占用的 32 位单元数 | 1(32位地址)或 2(64位地址) |
#size-cells |
长度字段占用的 32 位单元数 | 1(32位长度)或 2(64位长度) |
reg |
地址与长度交替排列的数组 | <0x10000000 0x1000> |
// 示例:SPI控制器,64位地址总线
spi@0x30000000 {
#address-cells = <1>;
#size-cells = <0>;
reg = <0x30000000 0x1000>; // 基地址0x30000000,范围4KB
...
// 子设备(SPI从设备)
device@0 {
reg = <0>; // 片选线0,无长度字段(size-cells=0)
compatible = "some,spi-device";
};
};
常见错误: 当父节点
#address-cells 或 #size-cells 设置错误时,内核解析 reg 会得到错误的地址或长度,导致驱动访问错误的物理地址。务必与硬件手册中的地址总线宽度保持一致。
3.3 interrupts 属性:中断信号描述
interrupts 属性用于描述设备产生的中断信号,其格式由父节点的 #interrupt-cells 属性定义。常见的中断控制器(如 GIC)使用 3 个 cell 来描述中断:中断类型、中断号、触发方式。
| 中断类型(cell 1) | 含义 | 典型值 |
|---|---|---|
| 0 | SPI(共享外设中断) | 用于外设共享中断 |
| 1 | PPI(私有外设中断) | 用于 CPU 私有中断 |
| 2 | 虚拟中断 | 用于虚拟化场景 |
// 示例:UART设备,使用GIC中断控制器
uart@1c28000 {
compatible = "ns16550a";
reg = <0x01c28000 0x400>;
interrupts = <0 1 4>; // SPI类型,中断号1,高电平触发
interrupt-parent = <&gic>; // 指定中断控制器
status = "okay";
};
注意:
interrupt-parent 属性用于指定该设备连接的中断控制器节点。如果未显式指定,则默认继承父节点的中断控制器。在多层中断控制器级联时,务必明确指定。
3.4 status 属性:设备状态控制
status 属性用于控制设备是否启用。该属性在设备树 overlay 中尤为重要,因为 overlay 常通过修改 status 来动态启用或禁用设备。
| 状态值 | 含义 | 使用场景 |
|---|---|---|
"okay" |
设备已启用且正常工作 | 默认启用状态 |
"disabled" |
设备被禁用,驱动不会 probe | 硬件存在但未使用,或 overlay 启用前 |
"reserved" |
设备保留,不由本系统管理 | 固件或安全世界占用 |
"fail" |
设备检测失败 | 由 bootloader 设置,内核跳过 |
// 基础设备树中禁用,overlay 中启用
// 基础 DTS
&uart1 {
status = "disabled";
};
// Overlay DTSO
&uart1 {
status = "okay";
pinctrl-0 = <&uart1_pins>;
};
最佳实践: 在基础设备树中,将所有未使用的外设默认设为
disabled,然后在 overlay 或板级配置中按需启用。这样可以避免未使用的外设占用中断、时钟等资源。
3.5 clocks 属性:时钟依赖与频率配置
clocks 属性用于指定设备所需的时钟源,通常与 clock-names 配合使用。时钟框架是 Linux 设备驱动中管理时钟频率与使能的核心机制。
- clocks: 一个 phandle 列表,指向时钟提供者节点。
- clock-names: 可选的字符串列表,为每个时钟指定名称,便于驱动通过名称查找。
- clock-frequency: 可选属性,直接指定时钟频率(用于固定频率时钟)。
// 示例:以太网控制器时钟配置
ethernet@1c30000 {
compatible = "allwinner,sun8i-h3-emac";
reg = <0x01c30000 0x1000>;
interrupts = <0 82 4>;
clocks = <&ccu CLK_BUS_EMAC>, <&ccu CLK_EMAC>;
clock-names = "bus", "mac";
status = "okay";
};
驱动开发提示: 在驱动中通过
devm_clk_get(dev, "bus") 获取名为 "bus" 的时钟,然后调用 clk_prepare_enable() 使能时钟。时钟框架会自动处理时钟树的上游使能。
3.6 其他常用属性速查
| 属性名 | 作用 | 典型示例 |
|---|---|---|
pinctrl-0 / pinctrl-names |
引脚复用配置 | pinctrl-0 = <&uart0_pins>; |
dmas / dma-names |
DMA 通道配置 | dmas = <&dma 2>; |
power-domains |
电源域控制 | power-domains = <&pd_core>; |
resets |
复位信号控制 | resets = <&rst 5>; |
phy-handle |
PHY 设备连接 | phy-handle = <&phy0>; |
memory-region |
预留内存区域 | memory-region = <&reserved_mem>; |
避坑指南: 使用
pinctrl 属性时,必须确保引脚配置节点中的 pins、function、bias-pull-up 等子属性与 SoC 手册完全一致。错误的引脚复用配置可能导致外设无法正常工作,甚至损坏硬件。
3.7 属性组合使用案例:完整设备节点
以下是一个完整的 SPI 控制器节点,展示了多个核心属性的组合使用方式:
spi@1c68000 {
compatible = "allwinner,sun8i-h3-spi", "allwinner,sun6i-a31-spi";
reg = <0x01c68000 0x1000>;
interrupts = <0 65 4>;
clocks = <&ccu CLK_BUS_SPI0>, <&ccu CLK_SPI0>;
clock-names = "bus", "mod";
resets = <&ccu RST_BUS_SPI0>;
pinctrl-0 = <&spi0_pins>;
pinctrl-names = "default";
status = "disabled"; // 默认禁用,由 overlay 启用
#address-cells = <1>;
#size-cells = <0>;
flash@0 {
compatible = "jedec,spi-nor";
reg = <0>;
spi-max-frequency = <50000000>;
status = "okay";
};
};
总结: 设备树属性是驱动与硬件之间的桥梁。掌握
compatible(驱动匹配)、reg(地址映射)、interrupts(中断路由)、status(设备状态)和 clocks(时钟依赖)这五大核心属性,是编写正确设备树文件的基础。在后续章节中,我们将基于这些属性,深入讲解设备树 overlay 的动态配置技术。