Zephyr中DTS文件与YAML文件的关系详解

Zephyr中DTS文件与YAML文件的关系详解

在Zephyr RTOS中,设备树源文件(DTS)与YAML文件构成了硬件描述与驱动程序之间的桥梁。这两种文件类型相互协作,形成了Zephyr的设备驱动框架的基础。下面我将详细分析它们的关系。

基本概念

DTS文件

  • 定义: 设备树源文件,描述硬件平台上实际存在的设备及其配置
  • 位置: 通常位于boards/目录下对应板子的文件夹,或dts/目录中
  • 作用: 详细定义板载设备的硬件参数、内存映射、中断关系等

YAML文件

  • 定义: 设备绑定(Device Bindings)文件,定义设备类型的属性规范
  • 位置: 通常位于dts/bindings/目录下
  • 作用: 定义DTS节点应该具有哪些属性,以及如何将DTS中的设备映射到驱动程序

核心关系

  1. 兼容性映射关系

    • DTS节点通过compatible属性引用特定的设备绑定
    • YAML文件定义了这些compatible字符串所代表的设备类型
    /* DTS文件中的节点 */
    i2c@40003000 {
        compatible = "nordic,nrf-twi";
        /* 其他属性... */
    };
    
    # 对应的YAML绑定文件
    description: Nordic nRF family TWI (I2C) node
    compatible: "nordic,nrf-twi"
    # 其他定义...
    
  2. 属性验证关系

    • YAML文件定义哪些属性是必需的,哪些是可选的
    • 编译时验证DTS中的节点是否符合YAML中定义的要求
    properties:
      reg:
        required: true
      interrupts:
        required: true
      label:
        required: true
      clock-frequency:
        type: int
        default: 100000
        description: Default I2C bus clock frequency in Hz
    
  3. 代码生成关系

    • DTS提供硬件实例数据
    • YAML提供数据解析和验证规则
    • Zephyr构建系统根据两者生成C头文件和设备实例

详细工作流程

  1. DTS处理流程:

    • 解析板级和SoC级DTS文件
    • 应用设备树覆盖(overlays)
    • 预处理并合并为一个统一的设备树
  2. 绑定匹配过程:

    • 对每个DTS节点,查找匹配其compatible属性的YAML绑定文件
    • 验证节点属性是否满足绑定要求
    • 处理默认值和派生值
  3. 代码生成:

    • 生成devicetree_unfixed.hdevicetree_fixups.h等头文件
    • 创建设备相关的宏和数据结构
    • 使驱动程序能够访问设备配置

实例分析

示例1: GPIO控制器

DTS节点:

&gpio0 {
    status = "okay";
    gpio-controller;
    #gpio-cells = <2>;
};

/ {
    buttons {
        compatible = "gpio-keys";
        button0: button_0 {
            gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
            label = "Push button 1";
        };
    };
};

对应YAML绑定:

# dts/bindings/gpio/gpio-controller.yaml
description: GPIO controller binding
compatible: "gpio-controller"
properties:
  "#gpio-cells":
    type: int
    required: true
    description: Number of cells in GPIO specifier

# dts/bindings/gpio/gpio-keys.yaml
description: GPIO Keys device binding
compatible: "gpio-keys"
child-binding:
  description: GPIO Key node
  properties:
    gpios:
      type: phandle-array
      required: true
    label:
      type: string
      required: true

生成的C代码宏:

/* 自动生成的devicetree.h中的代码 */
#define DT_N_S_buttons_S_button_0_LABEL "Push button 1"
#define DT_N_S_buttons_S_button_0_GPIOS_CONTROLLER "GPIO_0"
#define DT_N_S_buttons_S_button_0_GPIOS_PIN 13
#define DT_N_S_buttons_S_button_0_GPIOS_FLAGS GPIO_ACTIVE_LOW

示例2: I2C设备

DTS节点:

&i2c0 {
    status = "okay";
    clock-frequency = <400000>;
    
    bme280@76 {
        compatible = "bosch,bme280";
        reg = <0x76>;
        label = "BME280";
    };
};

对应YAML绑定:

# dts/bindings/i2c/i2c-controller.yaml
description: I2C controller binding
properties:
  clock-frequency:
    type: int
    default: 100000
    description: Default I2C bus clock frequency in Hz

# dts/bindings/sensor/bosch,bme280.yaml
description: Bosch BME280 temperature, pressure and humidity sensor
compatible: "bosch,bme280"
properties:
  reg:
    required: true
    description: I2C address
  label:
    required: true

特殊关系

  1. 继承关系

    • YAML文件可以通过include从其他YAML文件继承属性定义
    include: i2c-device.yaml
    compatible: "manufacturer,model"
    
  2. 子绑定关系

    • 通过child-binding定义子节点的规则
    child-binding:
      description: Child node binding
      properties:
        property-name:
          type: int
    
  3. 总线规范关系

    • 特定总线类型YAML定义了连接到该总线的设备应具有的属性
    on-bus: i2c
    properties:
      reg:
        required: true
    

总结

Zephyr中的DTS和YAML文件形成了一个完整的硬件描述系统:

  1. DTS文件描述了特定硬件平台上实际存在的设备实例及其配置
  2. YAML绑定文件定义了设备类型的规范和属性要求
  3. 构建系统使用YAML定义验证DTS内容并生成C代码
  4. 驱动程序通过生成的宏和API访问设备配置

这种设计使硬件描述与驱动实现分离,提高了代码的可移植性和可维护性,同时也简化了针对不同硬件平台的配置过程。通过DTS和YAML的协同工作,Zephyr能够在编译时刻就确定设备配置的正确性,减少了运行时错误。

你可能感兴趣的:(stm32,嵌入式硬件,单片机,linux,c++)