第四节:设备树绑定文档——从阅读到编写

设备树绑定文档,说白了就是硬件描述语言的“说明书”。

我刚开始接触设备树时,最头疼的就是看那些密密麻麻的文本。后来发现,只要掌握了套路,绑定文档其实比芯片手册好读多了。今天我就带你走一遍——怎么读、怎么理解、怎么写。

4.1 绑定文档到底长什么样?

绑定文档通常放在内核源码的 Documentation/devicetree/bindings/ 目录下。每个硬件IP都会有一个对应的YAML文件或纯文本描述。

我个人习惯先看文件头。它一般会告诉你:

  • 这个设备是干什么的
  • 它挂在哪个总线上
  • 需要哪些必须的属性

举个例子,一个典型的I2C设备绑定文档开头是这样的:

# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/i2c/foo,bar.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#

title: Foo Bar I2C Sensor

maintainers:
  - John Doe <john@example.com>

description: |
  This binding describes the Foo Bar temperature and humidity sensor.
  It communicates over I2C bus at addresses 0x48-0x4b.

嗯,这里要注意——maintainers字段很重要。如果你发现文档有问题,可以直接找维护者。我曾经就靠这个字段找到了一个文档错误的原作者,省了我两天排查时间。

4.2 常见绑定格式解析

现在的内核主流格式是YAML,但老一些的文档还是纯文本。我建议你两种都要会看。

4.2.1 YAML格式(新标准)

YAML格式的核心是 properties 部分。它定义了每个属性的类型、是否必须、取值范围。

properties:
  compatible:
    const: foo,bar-sensor

  reg:
    maxItems: 1
    description: I2C slave address

  interrupts:
    maxItems: 1

  vdd-supply:
    description: Power supply regulator

required:
  - compatible
  - reg
  - vdd-supply

你看,required 列表里列出的属性,一个都不能少。少了内核就会报错。我在项目中遇到过有人漏了 vdd-supply,结果设备驱动加载时一直报电源错误,查了两天才发现是绑定文档里写了必须,但设备树里没配。

4.2.2 纯文本格式(老标准)

老格式虽然不推荐了,但很多成熟IP还在用。它长这样:

Required properties:
- compatible: Should be "foo,bar-sensor"
- reg: I2C address of the device
- interrupts: Interrupt specifier

Optional properties:
- vdd-supply: Phandle to the regulator node
- wakeup-source: Mark the device as wakeup capable

说白了,老格式就是“人写的说明书”,新格式是“机器能校验的说明书”。我个人更推荐新格式,因为它能自动检查错误。

4.3 如何高效阅读绑定文档?

我总结了一个三步法:

  1. 先看compatible —— 找到设备树里对应的字符串
  2. 再看required —— 确保所有必须属性都配了
  3. 最后看examples —— 大部分文档末尾都有完整示例

举个例子,假设你要配一个温度传感器。先搜 compatible = "foo,bar-sensor",然后看required里要 reg 和 vdd-supply,最后抄一下example里的写法。十分钟就能搞定。

小技巧: 我习惯把绑定文档和芯片手册放在一起看。绑定文档告诉你“要配什么”,芯片手册告诉你“为什么这么配”。两个对照着读,理解会深很多。

4.4 编写自己的绑定文档

当你需要为一个新硬件写绑定时,别慌。我一般按这个流程走:

4.4.1 确定compatible字符串

格式是 厂商,设备名。比如 ti,ads1115、nxp,pca9685。注意厂商名要小写,设备名用短横线连接。

4.4.2 列出所有属性

先列必须的,再列可选的。我建议你画个表格:

属性名 类型 必须/可选 说明
compatible string 必须 设备标识
reg uint32 必须 I2C地址或片选号
interrupts uint32 可选 中断号
reset-gpios gpio 可选 复位引脚

4.4.3 编写YAML文件

这里我直接给个完整模板:

# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/i2c/my,device.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#

title: My Custom I2C Device

maintainers:
  - Your Name <your@email.com>

properties:
  compatible:
    const: my,device

  reg:
    maxItems: 1
    description: I2C slave address

  interrupts:
    maxItems: 1

  my,threshold:
    $ref: /schemas/types.yaml#/definitions/uint32
    description: Threshold value for the device
    default: 100

required:
  - compatible
  - reg

additionalProperties: false

examples:
  - |
    i2c {
        #address-cells = <1>;
        #size-cells = <0>;

        sensor@48 {
            compatible = "my,device";
            reg = <0x48>;
            interrupts = <13 2>;
            my,threshold = <200>;
        };
    };
注意: additionalProperties: false 这个字段很关键。它告诉校验工具:除了我列出的属性,其他的一律不认。我曾经没加这个,结果设备树里写了个拼写错误的属性名,内核默默忽略了,查了半天才发现。

4.5 知识体系总览

下面这张图帮你理清绑定文档的整个知识脉络:

设备树绑定文档知识体系 如何阅读 常见格式 编写自己的 三步法:compatible → required → examples 对照芯片手册理解 YAML格式(新标准) 纯文本格式(老标准) properties / required / examples 确定compatible字符串 列出所有属性(必须/可选) 编写YAML文件 添加example示例 核心原则:准确、完整、可校验

4.6 避坑指南

最后分享几个我踩过的坑:

  • compatible字符串别写错 —— 大小写、标点符号都要和驱动里完全一致。我曾经把 foo,bar 写成了 foo-bar,驱动死活不认。
  • reg属性注意地址格式 —— I2C设备用7位地址,SPI设备用片选号。别搞混了。
  • 别忘了加 additionalProperties: false —— 这个能帮你发现拼写错误。
  • example一定要能通过校验 —— 我见过很多文档的example本身就是错的,抄了就会翻车。

总结一下: 绑定文档是设备树和驱动之间的桥梁。读懂了它,你就能理解硬件是怎么被软件描述的;写好了它,别人就能正确使用你的硬件。说白了,这就是嵌入式开发者的“契约精神”。

可可精品资料库