4. 设备树基础:设备树语法入门
设备树(Device Tree)是 Linux 内核中用于描述硬件平台非可枚举设备的一种数据结构。在音频驱动开发中,I2S 接口、Codec、DMA 通道、时钟和 GPIO 等硬件资源都通过设备树节点进行描述和传递。掌握设备树语法是配置音频接口的前提。
核心概念:设备树将硬件描述与内核驱动代码分离。同一份内核镜像可以通过不同的设备树文件(.dtb)适配不同的硬件板卡,无需重新编译内核。
4.1 节点(Node)与属性(Property)
设备树的基本组成单元是节点,每个节点代表一个硬件设备或总线。节点内包含若干属性,用于描述设备的配置参数、寄存器地址、中断号、时钟频率等。
- 节点名称:格式为
node-name@unit-address,其中unit-address通常为设备基地址。 - 属性:键值对形式,值可以是字符串、32 位整数数组、64 位整数数组、字节串等。
- 根节点:
/,所有设备节点都挂载在根节点下。
/dts-v1/;
/ {
model = "MyAudioBoard";
compatible = "vendor,myboard-v1";
sound {
compatible = "simple-audio-card";
simple-audio-card,name = "My Audio Card";
simple-audio-card,format = "i2s";
simple-audio-card,bitclock-master = &cpu_dai;
simple-audio-card,frame-master = &cpu_dai;
};
i2s@ff890000 {
compatible = "vendor,i2s-controller";
reg = <0xff890000 0x1000>;
interrupts = <0 45 4>;
clocks = <&clk_i2s>;
#sound-dai-cells = <0>;
};
};
语法要点:
- 每个节点以分号
;结束。 - 属性值用尖括号
<>包裹 32 位整数数组,用双引号""包裹字符串。 compatible属性是驱动匹配的关键,格式为"厂商,设备型号"。
4.2 标签(Label)与引用(Reference)
标签为节点提供一个别名,方便在其他节点中引用。引用使用 &label 语法,在编译时会被替换为对应节点的路径。
| 语法元素 | 示例 | 说明 |
|---|---|---|
| 标签定义 | cpu_dai: i2s@ff890000 { ... }; |
为 i2s 节点定义标签 cpu_dai |
| 标签引用 | sound { ... bitclock-master = &cpu_dai; }; |
引用标签指向的节点路径 |
| 路径引用 | &{/soc/i2s@ff890000} |
直接使用完整路径引用 |
// 定义标签
cpu_dai: i2s@ff890000 {
compatible = "vendor,i2s-controller";
#sound-dai-cells = <0>;
};
// 引用标签
&cpu_dai {
status = "okay";
};
常见错误:标签引用时不要忘记
& 符号。如果直接写 cpu_dai 而不加 &,编译器会将其视为字符串,而不是节点引用。
4.3 包含文件(Include)与 dts/dtsi 结构
设备树源文件分为 .dts(板级描述文件)和 .dtsi(芯片级描述文件)。.dtsi 文件通过 #include 指令被包含到 .dts 中,实现代码复用。
// soc.dtsi — 芯片级描述
/ {
cpu: cpu@0 {
compatible = "arm,cortex-a7";
};
i2s0: i2s@ff890000 {
compatible = "vendor,i2s-controller";
reg = <0xff890000 0x1000>;
status = "disabled";
};
};
// myboard.dts — 板级描述
/dts-v1/;
#include "soc.dtsi"
#include "audio-codec.dtsi"
/ {
model = "MyAudioBoard";
};
&i2s0 {
status = "okay";
pinctrl-0 = <&i2s0_pins>;
};
最佳实践:
- 芯片厂商提供
.dtsi文件,板卡厂商提供.dts文件。 - 在
.dts中通过&label方式覆盖.dtsi中的属性,如使能设备、配置引脚。 - 不要修改
.dtsi文件,通过.dts进行板级定制。
4.4 绑定文档(Binding Documentation)的重要性
绑定文档是设备树属性与内核驱动之间的“契约”。它定义了哪些属性是必需的、哪些是可选的、属性值的格式和含义。没有绑定文档,设备树配置将变成“猜谜游戏”。
| 绑定文档要素 | 说明 | 音频示例 |
|---|---|---|
| compatible 字符串 | 驱动匹配的唯一标识 | "simple-audio-card" |
| 必需属性列表 | 驱动正常工作必须提供的属性 | simple-audio-card,format |
| 可选属性列表 | 提供额外功能配置的属性 | simple-audio-card,bitclock-master |
| 属性值格式 | 字符串、整数、phandle 等类型定义 | <&cpu_dai> 为 phandle 引用 |
| 节点层级关系 | 子节点、父节点的约束 | codec 节点必须挂在 sound 节点下 |
实践建议:在编写音频设备树节点之前,务必先阅读对应驱动的绑定文档。Linux 内核源码中的
Documentation/devicetree/bindings/sound/ 目录下包含了所有音频相关绑定文档。例如 simple-audio-card.txt 定义了 simple-audio-card 驱动的所有可用属性。
4.5 本章小结
设备树语法是音频驱动开发的基石。通过节点描述硬件、属性传递参数、标签实现跨节点引用、包含文件实现代码复用,开发者可以灵活地配置 I2S 接口、Codec 和音频通路。绑定文档则是确保配置正确的“说明书”,必须养成查阅绑定文档的习惯。
关键记忆点:
- 节点 = 硬件设备,属性 = 设备参数
- 标签 + 引用 = 跨节点连接
- .dtsi 通用 + .dts 定制 = 高效复用
- 绑定文档 = 设备树与驱动的契约