Zephyr设备树完全指南

Zephyr设备树完全指南:作用、功能与使用方法

引言

在嵌入式系统开发中,硬件配置是一个复杂而关键的环节。不同的硬件平台有不同的外设配置、中断映射和内存布局。为了解决这个问题,Zephyr引入了设备树(Device Tree)机制,将硬件配置从代码中分离出来,实现了软件与硬件的解耦。

本文将深入介绍Zephyr中设备树的作用、功能和使用方法,帮助您全面理解和掌握这一重要技术。


一、设备树概述

1.1 什么是设备树

设备树(Device Tree,简称DT)是一种描述硬件设备信息的数据结构,起源于PowerPC架构,后来被Linux内核采用,现在广泛应用于嵌入式系统。
#mermaid-svg-QghTNS42dDFGPVZR{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-QghTNS42dDFGPVZR .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-QghTNS42dDFGPVZR .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-QghTNS42dDFGPVZR .error-icon{fill:#552222;}#mermaid-svg-QghTNS42dDFGPVZR .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-QghTNS42dDFGPVZR .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-QghTNS42dDFGPVZR .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-QghTNS42dDFGPVZR .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-QghTNS42dDFGPVZR .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-QghTNS42dDFGPVZR .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-QghTNS42dDFGPVZR .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-QghTNS42dDFGPVZR .marker{fill:#333333;stroke:#333333;}#mermaid-svg-QghTNS42dDFGPVZR .marker.cross{stroke:#333333;}#mermaid-svg-QghTNS42dDFGPVZR svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-QghTNS42dDFGPVZR p{margin:0;}#mermaid-svg-QghTNS42dDFGPVZR .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-QghTNS42dDFGPVZR .cluster-label text{fill:#333;}#mermaid-svg-QghTNS42dDFGPVZR .cluster-label span{color:#333;}#mermaid-svg-QghTNS42dDFGPVZR .cluster-label span p{background-color:transparent;}#mermaid-svg-QghTNS42dDFGPVZR .label text,#mermaid-svg-QghTNS42dDFGPVZR span{fill:#333;color:#333;}#mermaid-svg-QghTNS42dDFGPVZR .node rect,#mermaid-svg-QghTNS42dDFGPVZR .node circle,#mermaid-svg-QghTNS42dDFGPVZR .node ellipse,#mermaid-svg-QghTNS42dDFGPVZR .node polygon,#mermaid-svg-QghTNS42dDFGPVZR .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-QghTNS42dDFGPVZR .rough-node .label text,#mermaid-svg-QghTNS42dDFGPVZR .node .label text,#mermaid-svg-QghTNS42dDFGPVZR .image-shape .label,#mermaid-svg-QghTNS42dDFGPVZR .icon-shape .label{text-anchor:middle;}#mermaid-svg-QghTNS42dDFGPVZR .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-QghTNS42dDFGPVZR .rough-node .label,#mermaid-svg-QghTNS42dDFGPVZR .node .label,#mermaid-svg-QghTNS42dDFGPVZR .image-shape .label,#mermaid-svg-QghTNS42dDFGPVZR .icon-shape .label{text-align:center;}#mermaid-svg-QghTNS42dDFGPVZR .node.clickable{cursor:pointer;}#mermaid-svg-QghTNS42dDFGPVZR .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-QghTNS42dDFGPVZR .arrowheadPath{fill:#333333;}#mermaid-svg-QghTNS42dDFGPVZR .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-QghTNS42dDFGPVZR .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-QghTNS42dDFGPVZR .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-QghTNS42dDFGPVZR .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-QghTNS42dDFGPVZR .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-QghTNS42dDFGPVZR .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-QghTNS42dDFGPVZR .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-QghTNS42dDFGPVZR .cluster text{fill:#333;}#mermaid-svg-QghTNS42dDFGPVZR .cluster span{color:#333;}#mermaid-svg-QghTNS42dDFGPVZR div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-QghTNS42dDFGPVZR .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-QghTNS42dDFGPVZR rect.text{fill:none;stroke-width:0;}#mermaid-svg-QghTNS42dDFGPVZR .icon-shape,#mermaid-svg-QghTNS42dDFGPVZR .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-QghTNS42dDFGPVZR .icon-shape p,#mermaid-svg-QghTNS42dDFGPVZR .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-QghTNS42dDFGPVZR .icon-shape .label rect,#mermaid-svg-QghTNS42dDFGPVZR .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-QghTNS42dDFGPVZR .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-QghTNS42dDFGPVZR .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-QghTNS42dDFGPVZR :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 设备树
硬件描述语言
树形结构
平台无关
描述硬件组件
定义寄存器映射
配置中断
根节点
子节点
属性
同一代码适配多硬件
无需重新编译

1.2 设备树的作用

作用 说明
硬件抽象 将硬件信息从代码中分离
平台适配 一套代码支持多种硬件平台
配置灵活 修改配置无需重新编译代码
标准化 统一的硬件描述格式

1.3 设备树的优势

#mermaid-svg-XgkkWmobnhgreoM0{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-XgkkWmobnhgreoM0 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-XgkkWmobnhgreoM0 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-XgkkWmobnhgreoM0 .error-icon{fill:#552222;}#mermaid-svg-XgkkWmobnhgreoM0 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-XgkkWmobnhgreoM0 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-XgkkWmobnhgreoM0 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-XgkkWmobnhgreoM0 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-XgkkWmobnhgreoM0 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-XgkkWmobnhgreoM0 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-XgkkWmobnhgreoM0 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-XgkkWmobnhgreoM0 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-XgkkWmobnhgreoM0 .marker.cross{stroke:#333333;}#mermaid-svg-XgkkWmobnhgreoM0 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-XgkkWmobnhgreoM0 p{margin:0;}#mermaid-svg-XgkkWmobnhgreoM0 .pieCircle{stroke:#000000;stroke-width:2px;opacity:0.7;}#mermaid-svg-XgkkWmobnhgreoM0 .pieOuterCircle{stroke:#000000;stroke-width:1px;fill:none;}#mermaid-svg-XgkkWmobnhgreoM0 .pieTitleText{text-anchor:middle;font-size:25px;fill:#000000;font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-XgkkWmobnhgreoM0 .slice{font-family:"trebuchet ms",verdana,arial,sans-serif;fill:#000000;font-size:17px;}#mermaid-svg-XgkkWmobnhgreoM0 .legend text{fill:#000000;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:17px;}#mermaid-svg-XgkkWmobnhgreoM0 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 35% 25% 20% 20% 设备树优势 硬件解耦 配置灵活 代码复用 易于维护


二、设备树文件结构

2.1 文件类型

文件类型 后缀 说明
包含文件 .dtsi 可重用的设备树片段
设备树源文件 .dts 具体硬件的完整描述
覆盖文件 .overlay 修改或扩展现有配置

2.2 文件层次结构

#mermaid-svg-moaDuoYnMVwAwq3P{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-moaDuoYnMVwAwq3P .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-moaDuoYnMVwAwq3P .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-moaDuoYnMVwAwq3P .error-icon{fill:#552222;}#mermaid-svg-moaDuoYnMVwAwq3P .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-moaDuoYnMVwAwq3P .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-moaDuoYnMVwAwq3P .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-moaDuoYnMVwAwq3P .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-moaDuoYnMVwAwq3P .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-moaDuoYnMVwAwq3P .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-moaDuoYnMVwAwq3P .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-moaDuoYnMVwAwq3P .marker{fill:#333333;stroke:#333333;}#mermaid-svg-moaDuoYnMVwAwq3P .marker.cross{stroke:#333333;}#mermaid-svg-moaDuoYnMVwAwq3P svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-moaDuoYnMVwAwq3P p{margin:0;}#mermaid-svg-moaDuoYnMVwAwq3P .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-moaDuoYnMVwAwq3P .cluster-label text{fill:#333;}#mermaid-svg-moaDuoYnMVwAwq3P .cluster-label span{color:#333;}#mermaid-svg-moaDuoYnMVwAwq3P .cluster-label span p{background-color:transparent;}#mermaid-svg-moaDuoYnMVwAwq3P .label text,#mermaid-svg-moaDuoYnMVwAwq3P span{fill:#333;color:#333;}#mermaid-svg-moaDuoYnMVwAwq3P .node rect,#mermaid-svg-moaDuoYnMVwAwq3P .node circle,#mermaid-svg-moaDuoYnMVwAwq3P .node ellipse,#mermaid-svg-moaDuoYnMVwAwq3P .node polygon,#mermaid-svg-moaDuoYnMVwAwq3P .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-moaDuoYnMVwAwq3P .rough-node .label text,#mermaid-svg-moaDuoYnMVwAwq3P .node .label text,#mermaid-svg-moaDuoYnMVwAwq3P .image-shape .label,#mermaid-svg-moaDuoYnMVwAwq3P .icon-shape .label{text-anchor:middle;}#mermaid-svg-moaDuoYnMVwAwq3P .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-moaDuoYnMVwAwq3P .rough-node .label,#mermaid-svg-moaDuoYnMVwAwq3P .node .label,#mermaid-svg-moaDuoYnMVwAwq3P .image-shape .label,#mermaid-svg-moaDuoYnMVwAwq3P .icon-shape .label{text-align:center;}#mermaid-svg-moaDuoYnMVwAwq3P .node.clickable{cursor:pointer;}#mermaid-svg-moaDuoYnMVwAwq3P .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-moaDuoYnMVwAwq3P .arrowheadPath{fill:#333333;}#mermaid-svg-moaDuoYnMVwAwq3P .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-moaDuoYnMVwAwq3P .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-moaDuoYnMVwAwq3P .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-moaDuoYnMVwAwq3P .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-moaDuoYnMVwAwq3P .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-moaDuoYnMVwAwq3P .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-moaDuoYnMVwAwq3P .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-moaDuoYnMVwAwq3P .cluster text{fill:#333;}#mermaid-svg-moaDuoYnMVwAwq3P .cluster span{color:#333;}#mermaid-svg-moaDuoYnMVwAwq3P div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-moaDuoYnMVwAwq3P .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-moaDuoYnMVwAwq3P rect.text{fill:none;stroke-width:0;}#mermaid-svg-moaDuoYnMVwAwq3P .icon-shape,#mermaid-svg-moaDuoYnMVwAwq3P .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-moaDuoYnMVwAwq3P .icon-shape p,#mermaid-svg-moaDuoYnMVwAwq3P .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-moaDuoYnMVwAwq3P .icon-shape .label rect,#mermaid-svg-moaDuoYnMVwAwq3P .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-moaDuoYnMVwAwq3P .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-moaDuoYnMVwAwq3P .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-moaDuoYnMVwAwq3P :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 设备树文件层次
SoC级.dtsi
板级.dtsi
开发板.dts
应用.overlay
描述SoC外设
描述板级电路
具体开发板配置
应用特定配置

2.3 目录结构

复制代码
zephyr/
├── dts/
│   ├── bindings/           # 设备绑定文件
│   ├── common/             # 通用设备树
│   ├── arm/               # ARM架构
│   │   ├── nordic/        # Nordic SoC
│   │   │   ├── nrf52.dtsi
│   │   │   └── nrf52840.dtsi
│   │   └── st/            # STM32 SoC
│   │       └── stm32f4.dtsi
│   └── riscv/             # RISC-V架构
└── boards/
    └── arm/
        └── nrf52840dk_nrf52840/
            └── nrf52840dk_nrf52840.dts

三、设备树基本语法

3.1 节点定义

dts 复制代码
/* 设备树节点示例 */

/ {
    /* 根节点 */
    model = "Nordic nRF52840 DK";
    compatible = "nordic,nrf52840dk-nrf52840";
    
    /* 子节点 - 内存 */
    memory@20000000 {
        device_type = "memory";
        reg = <0x20000000 0x40000>;  /* 起始地址和大小 */
    };
    
    /* 子节点 - GPIO控制器 */
    gpio0: gpio@50000000 {
        compatible = "nordic,nrf-gpio";
        reg = <0x50000000 0x1000>;
        status = "okay";
        label = "GPIO_0";
    };
    
    /* 子节点 - UART */
    uart0: uart@40002000 {
        compatible = "nordic,nrf-uart";
        reg = <0x40002000 0x1000>;
        interrupts = <2 1>;
        status = "okay";
        current-speed = <115200>;
    };
};

3.2 属性类型

属性类型 语法 示例
字符串 name = "value"; model = "MyBoard";
32位整数 name = <value>; reg = <0x1000>;
整数数组 name = <v1 v2 v3>; reg = <0x20000000 0x40000>;
布尔值 name;name = "okay"; status = "okay";
字符串列表 name = "v1", "v2"; compatible = "a", "b";

3.3 特殊节点

dts 复制代码
/* 特殊节点示例 */

/ {
    /* chosen节点 - 运行时配置 */
    chosen {
        zephyr,console = &uart0;          /* 控制台串口 */
        zephyr,shell-uart = &uart0;       /* Shell串口 */
        zephyr,sram = &sram0;             /* SRAM区域 */
        zephyr,flash = &flash0;           /* Flash区域 */
        zephyr,code-partition = &code_partition;  /* 代码分区 */
    };
    
    /* aliases节点 - 别名定义 */
    aliases {
        led0 = &led0;
        sw0 = &sw0;
        uart0 = &uart0;
        i2c0 = &i2c0;
    };
    
    /* reserved-memory节点 - 保留内存 */
    reserved-memory {
        #address-cells = <1>;
        #size-cells = <1>;
        ranges;
        
        my_reserved: reserved@20001000 {
            reg = <0x20001000 0x1000>;
        };
    };
};

3.4 节点标签与引用

dts 复制代码
/* 节点标签与引用示例 */

/ {
    /* 定义带标签的节点 */
    gpio0: gpio@50000000 {
        compatible = "nordic,nrf-gpio";
        reg = <0x50000000 0x1000>;
        status = "okay";
    };
    
    /* 通过标签引用其他节点 */
    led0: led_0 {
        gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
        label = "LED0";
    };
    
    /* 通过路径引用 */
    &uart0 {
        current-speed = <9600>;  /* 修改uart0的属性 */
    };
};

四、设备树绑定

4.1 绑定文件概念

设备树绑定(Binding)定义了设备节点的属性规范,确保设备树的正确性和一致性。

复制代码
dts/bindings/
├── gpio/
│   ├── nordic,nrf-gpio.yaml
│   └── st,stm32-gpio.yaml
├── uart/
│   ├── nordic,nrf-uart.yaml
│   └── st,stm32-uart.yaml
└── i2c/
    └── nordic,nrf-twi.yaml

4.2 绑定文件示例

yaml 复制代码
# nordic,nrf-gpio.yaml

compatible: "nordic,nrf-gpio"

include: base.yaml

properties:
  reg:
    type: array
    description: |
      GPIO controller register space
      
  interrupts:
    type: array
    description: |
      Interrupt lines for each port
      
  label:
    type: string
    description: |
      Human readable string describing the device
      
  "#gpio-cells":
    const: 2
    description: |
      Number of cells in GPIO specifier
      
required:
  - reg
  - interrupts

4.3 绑定文件结构

字段 说明
compatible 兼容的设备列表
include 包含的基础绑定
properties 定义的属性列表
required 必填属性列表
description 属性描述

五、在代码中使用设备树

5.1 获取设备节点

c 复制代码
/* 获取设备节点示例 */

#include <zephyr/device.h>
#include <zephyr/devicetree.h>

/* 方式1:使用节点标签 */
#define UART_NODE DT_NODELABEL(uart0)

/* 方式2:使用别名 */
#define LED_NODE DT_ALIAS(led0)

/* 方式3:使用路径 */
#define GPIO_NODE DT_PATH(soc, gpio_50000000)

/* 获取设备指针 */
const struct device *uart_dev = DEVICE_DT_GET(UART_NODE);

/* 检查设备是否就绪 */
if (device_is_ready(uart_dev)) {
    printk("UART device is ready\n");
}

5.2 读取设备属性

c 复制代码
/* 读取设备属性示例 */

#include <zephyr/devicetree.h>

/* 读取整型属性 */
uint32_t baud_rate = DT_PROP(DT_NODELABEL(uart0), current_speed);
printk("Baud rate: %d\n", baud_rate);

/* 读取字符串属性 */
const char *label = DT_PROP(DT_NODELABEL(gpio0), label);
printk("GPIO label: %s\n", label);

/* 读取状态属性 */
if (DT_NODE_HAS_STATUS(DT_NODELABEL(uart0), okay)) {
    printk("UART is enabled\n");
}

5.3 GPIO配置

c 复制代码
/* GPIO设备树配置示例 */

#include <zephyr/drivers/gpio.h>

/* 使用别名获取LED节点 */
#define LED_NODE DT_ALIAS(led0)

/* 获取GPIO控制器和引脚 */
#define LED_GPIO DT_GPIO_CTLR(LED_NODE, gpios)
#define LED_PIN DT_GPIO_PIN(LED_NODE, gpios)
#define LED_FLAGS DT_GPIO_FLAGS(LED_NODE, gpios)

/* 获取设备 */
static const struct device *led_dev = DEVICE_DT_GET(LED_GPIO);

void led_init(void)
{
    /* 检查设备 */
    if (!device_is_ready(led_dev)) {
        printk("LED device not ready\n");
        return;
    }
    
    /* 配置引脚为输出 */
    gpio_pin_configure(led_dev, LED_PIN, GPIO_OUTPUT_INACTIVE | LED_FLAGS);
    
    /* 点亮LED */
    gpio_pin_set(led_dev, LED_PIN, 1);
}

5.4 中断配置

c 复制代码
/* 中断设备树配置示例 */

#include <zephyr/irq.h>

/* 获取中断号和优先级 */
#define MY_IRQ DT_IRQ_BY_IDX(DT_NODELABEL(my_device), 0, irq)
#define MY_IRQ_PRIORITY DT_IRQ_BY_IDX(DT_NODELABEL(my_device), 0, priority)

void my_interrupt_handler(const void *arg)
{
    printk("Interrupt triggered!\n");
}

void interrupt_init(void)
{
    /* 安装中断处理函数 */
    irq_connect(MY_IRQ, MY_IRQ_PRIORITY, my_interrupt_handler, NULL, 0);
    
    /* 使能中断 */
    irq_enable(MY_IRQ);
}

六、设备树覆盖文件

6.1 覆盖文件概念

设备树覆盖文件(Overlay)允许在不修改原始设备树的情况下,添加、修改或删除节点和属性。
#mermaid-svg-T7kjRsMrmd1VOTno{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-T7kjRsMrmd1VOTno .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-T7kjRsMrmd1VOTno .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-T7kjRsMrmd1VOTno .error-icon{fill:#552222;}#mermaid-svg-T7kjRsMrmd1VOTno .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-T7kjRsMrmd1VOTno .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-T7kjRsMrmd1VOTno .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-T7kjRsMrmd1VOTno .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-T7kjRsMrmd1VOTno .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-T7kjRsMrmd1VOTno .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-T7kjRsMrmd1VOTno .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-T7kjRsMrmd1VOTno .marker{fill:#333333;stroke:#333333;}#mermaid-svg-T7kjRsMrmd1VOTno .marker.cross{stroke:#333333;}#mermaid-svg-T7kjRsMrmd1VOTno svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-T7kjRsMrmd1VOTno p{margin:0;}#mermaid-svg-T7kjRsMrmd1VOTno .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-T7kjRsMrmd1VOTno .cluster-label text{fill:#333;}#mermaid-svg-T7kjRsMrmd1VOTno .cluster-label span{color:#333;}#mermaid-svg-T7kjRsMrmd1VOTno .cluster-label span p{background-color:transparent;}#mermaid-svg-T7kjRsMrmd1VOTno .label text,#mermaid-svg-T7kjRsMrmd1VOTno span{fill:#333;color:#333;}#mermaid-svg-T7kjRsMrmd1VOTno .node rect,#mermaid-svg-T7kjRsMrmd1VOTno .node circle,#mermaid-svg-T7kjRsMrmd1VOTno .node ellipse,#mermaid-svg-T7kjRsMrmd1VOTno .node polygon,#mermaid-svg-T7kjRsMrmd1VOTno .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-T7kjRsMrmd1VOTno .rough-node .label text,#mermaid-svg-T7kjRsMrmd1VOTno .node .label text,#mermaid-svg-T7kjRsMrmd1VOTno .image-shape .label,#mermaid-svg-T7kjRsMrmd1VOTno .icon-shape .label{text-anchor:middle;}#mermaid-svg-T7kjRsMrmd1VOTno .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-T7kjRsMrmd1VOTno .rough-node .label,#mermaid-svg-T7kjRsMrmd1VOTno .node .label,#mermaid-svg-T7kjRsMrmd1VOTno .image-shape .label,#mermaid-svg-T7kjRsMrmd1VOTno .icon-shape .label{text-align:center;}#mermaid-svg-T7kjRsMrmd1VOTno .node.clickable{cursor:pointer;}#mermaid-svg-T7kjRsMrmd1VOTno .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-T7kjRsMrmd1VOTno .arrowheadPath{fill:#333333;}#mermaid-svg-T7kjRsMrmd1VOTno .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-T7kjRsMrmd1VOTno .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-T7kjRsMrmd1VOTno .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-T7kjRsMrmd1VOTno .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-T7kjRsMrmd1VOTno .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-T7kjRsMrmd1VOTno .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-T7kjRsMrmd1VOTno .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-T7kjRsMrmd1VOTno .cluster text{fill:#333;}#mermaid-svg-T7kjRsMrmd1VOTno .cluster span{color:#333;}#mermaid-svg-T7kjRsMrmd1VOTno div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-T7kjRsMrmd1VOTno .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-T7kjRsMrmd1VOTno rect.text{fill:none;stroke-width:0;}#mermaid-svg-T7kjRsMrmd1VOTno .icon-shape,#mermaid-svg-T7kjRsMrmd1VOTno .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-T7kjRsMrmd1VOTno .icon-shape p,#mermaid-svg-T7kjRsMrmd1VOTno .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-T7kjRsMrmd1VOTno .icon-shape .label rect,#mermaid-svg-T7kjRsMrmd1VOTno .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-T7kjRsMrmd1VOTno .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-T7kjRsMrmd1VOTno .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-T7kjRsMrmd1VOTno :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 基础设备树
覆盖文件
合并后的设备树
SoC.dtsi
board.dts
修改节点
添加节点
禁用节点

6.2 覆盖文件示例

dts 复制代码
/* app.overlay - 应用覆盖文件 */

/ {
    /* 添加新节点 */
    my_sensor {
        compatible = "mycompany,my-sensor";
        reg = <0x40001000 0x100>;
        interrupts = <5 0>;
        status = "okay";
        label = "MY_SENSOR";
    };
    
    /* 修改现有节点 */
    &uart0 {
        current-speed = <9600>;  /* 修改波特率 */
        status = "okay";
    };
    
    /* 禁用节点 */
    &i2c0 {
        status = "disabled";  /* 禁用I2C0 */
    };
    
    /* 修改chosen节点 */
    &chosen {
        zephyr,console = &uart1;  /* 切换控制台到UART1 */
    };
};

6.3 使用覆盖文件

bash 复制代码
# 编译时指定覆盖文件
west build -b nrf52840dk_nrf52840 . -- -DDTC_OVERLAY_FILE=app.overlay

# 多个覆盖文件
west build -b nrf52840dk_nrf52840 . -- -DDTC_OVERLAY_FILE="app.overlay sensors.overlay"

七、设备树处理流程

7.1 编译流程

#mermaid-svg-iUPFYqyLYTktSOG4{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-iUPFYqyLYTktSOG4 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-iUPFYqyLYTktSOG4 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-iUPFYqyLYTktSOG4 .error-icon{fill:#552222;}#mermaid-svg-iUPFYqyLYTktSOG4 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-iUPFYqyLYTktSOG4 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-iUPFYqyLYTktSOG4 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-iUPFYqyLYTktSOG4 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-iUPFYqyLYTktSOG4 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-iUPFYqyLYTktSOG4 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-iUPFYqyLYTktSOG4 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-iUPFYqyLYTktSOG4 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-iUPFYqyLYTktSOG4 .marker.cross{stroke:#333333;}#mermaid-svg-iUPFYqyLYTktSOG4 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-iUPFYqyLYTktSOG4 p{margin:0;}#mermaid-svg-iUPFYqyLYTktSOG4 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-iUPFYqyLYTktSOG4 .cluster-label text{fill:#333;}#mermaid-svg-iUPFYqyLYTktSOG4 .cluster-label span{color:#333;}#mermaid-svg-iUPFYqyLYTktSOG4 .cluster-label span p{background-color:transparent;}#mermaid-svg-iUPFYqyLYTktSOG4 .label text,#mermaid-svg-iUPFYqyLYTktSOG4 span{fill:#333;color:#333;}#mermaid-svg-iUPFYqyLYTktSOG4 .node rect,#mermaid-svg-iUPFYqyLYTktSOG4 .node circle,#mermaid-svg-iUPFYqyLYTktSOG4 .node ellipse,#mermaid-svg-iUPFYqyLYTktSOG4 .node polygon,#mermaid-svg-iUPFYqyLYTktSOG4 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-iUPFYqyLYTktSOG4 .rough-node .label text,#mermaid-svg-iUPFYqyLYTktSOG4 .node .label text,#mermaid-svg-iUPFYqyLYTktSOG4 .image-shape .label,#mermaid-svg-iUPFYqyLYTktSOG4 .icon-shape .label{text-anchor:middle;}#mermaid-svg-iUPFYqyLYTktSOG4 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-iUPFYqyLYTktSOG4 .rough-node .label,#mermaid-svg-iUPFYqyLYTktSOG4 .node .label,#mermaid-svg-iUPFYqyLYTktSOG4 .image-shape .label,#mermaid-svg-iUPFYqyLYTktSOG4 .icon-shape .label{text-align:center;}#mermaid-svg-iUPFYqyLYTktSOG4 .node.clickable{cursor:pointer;}#mermaid-svg-iUPFYqyLYTktSOG4 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-iUPFYqyLYTktSOG4 .arrowheadPath{fill:#333333;}#mermaid-svg-iUPFYqyLYTktSOG4 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-iUPFYqyLYTktSOG4 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-iUPFYqyLYTktSOG4 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-iUPFYqyLYTktSOG4 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-iUPFYqyLYTktSOG4 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-iUPFYqyLYTktSOG4 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-iUPFYqyLYTktSOG4 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-iUPFYqyLYTktSOG4 .cluster text{fill:#333;}#mermaid-svg-iUPFYqyLYTktSOG4 .cluster span{color:#333;}#mermaid-svg-iUPFYqyLYTktSOG4 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-iUPFYqyLYTktSOG4 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-iUPFYqyLYTktSOG4 rect.text{fill:none;stroke-width:0;}#mermaid-svg-iUPFYqyLYTktSOG4 .icon-shape,#mermaid-svg-iUPFYqyLYTktSOG4 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-iUPFYqyLYTktSOG4 .icon-shape p,#mermaid-svg-iUPFYqyLYTktSOG4 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-iUPFYqyLYTktSOG4 .icon-shape .label rect,#mermaid-svg-iUPFYqyLYTktSOG4 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-iUPFYqyLYTktSOG4 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-iUPFYqyLYTktSOG4 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-iUPFYqyLYTktSOG4 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 设备树源文件
DTC编译
.dtb二进制文件
设备树解析
生成头文件
编译应用
.dtsi文件
.dts文件
.overlay文件
devicetree.h
devicetree_unfixed.h

7.2 生成的文件

文件 说明
devicetree.h 设备树常量定义
devicetree_unfixed.h 未固定的设备树定义
device_extern.h 设备外部声明

7.3 编译命令

bash 复制代码
# 查看设备树编译命令
west build -b <board> <app> -- -Dprintk-dtc

# 查看生成的设备树头文件
cat build/zephyr/include/generated/devicetree.h

# 验证设备树语法
dtc -I dts -O dtb -o test.dtb app.dts

八、常用设备树宏

8.1 节点访问宏

说明 示例
DT_NODELABEL(name) 通过标签获取节点 DT_NODELABEL(uart0)
DT_ALIAS(alias) 通过别名获取节点 DT_ALIAS(led0)
DT_PATH(...) 通过路径获取节点 DT_PATH(soc, uart)
DT_INST(n, compat) 通过实例号获取节点 DT_INST(0, nordic_nrf_uart)

8.2 属性访问宏

说明 示例
DT_PROP(node, prop) 读取属性值 DT_PROP(uart0, current_speed)
DT_NODE_HAS_PROP(node, prop) 检查属性是否存在 DT_NODE_HAS_PROP(uart0, status)
DT_NODE_HAS_STATUS(node, status) 检查状态 DT_NODE_HAS_STATUS(uart0, okay)

8.3 GPIO相关宏

说明 示例
DT_GPIO_CTLR(node, prop) 获取GPIO控制器 DT_GPIO_CTLR(led0, gpios)
DT_GPIO_PIN(node, prop) 获取GPIO引脚 DT_GPIO_PIN(led0, gpios)
DT_GPIO_FLAGS(node, prop) 获取GPIO标志 DT_GPIO_FLAGS(led0, gpios)

8.4 中断相关宏

说明 示例
DT_IRQ_BY_IDX(node, idx, prop) 获取中断属性 DT_IRQ_BY_IDX(dev, 0, irq)
DT_IRQ(node, prop) 获取中断 DT_IRQ(dev, interrupts)

九、设备树示例

9.1 完整设备树示例

dts 复制代码
/* nrf52840dk_nrf52840.dts */

#include <nrf52840.dtsi>

/ {
    model = "Nordic nRF52840 DK";
    compatible = "nordic,nrf52840dk-nrf52840";
    
    chosen {
        zephyr,console = &uart0;
        zephyr,shell-uart = &uart0;
        zephyr,sram = &sram0;
        zephyr,flash = &flash0;
    };
    
    aliases {
        led0 = &led0;
        led1 = &led1;
        led2 = &led2;
        led3 = &led3;
        sw0 = &sw0;
        sw1 = &sw1;
        sw2 = &sw2;
        sw3 = &sw3;
        uart0 = &uart0;
        i2c0 = &i2c0;
        spi0 = &spi0;
    };
    
    leds {
        compatible = "gpio-leds";
        led0: led_0 {
            gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
            label = "LED0";
        };
        led1: led_1 {
            gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
            label = "LED1";
        };
    };
    
    buttons {
        compatible = "gpio-keys";
        sw0: button_0 {
            gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
            label = "SW0";
        };
    };
};

/* 修改UART配置 */
&uart0 {
    current-speed = <115200>;
    status = "okay";
};

/* 配置I2C */
&i2c0 {
    clock-frequency = <I2C_BITRATE_FAST>;
    status = "okay";
};

9.2 覆盖文件示例

dts 复制代码
/* sensors.overlay - 传感器扩展 */

/ {
    /* 添加传感器节点 */
    hts221@5f {
        compatible = "st,hts221";
        reg = <0x5f>;
        label = "HTS221";
        status = "okay";
    };
    
    bme280@76 {
        compatible = "bosch,bme280";
        reg = <0x76>;
        label = "BME280";
        status = "okay";
    };
};

/* 修改I2C配置以支持传感器 */
&i2c0 {
    clock-frequency = <I2C_BITRATE_STANDARD>;
    status = "okay";
};

十、常见问题与解决方案

10.1 设备树语法错误

问题Error parsing device tree

解决

bash 复制代码
# 验证设备树语法
dtc -I dts -O dtb -o /dev/null app.dts

# 检查绑定文件
ls dts/bindings/gpio/

10.2 节点未找到

问题DT_NODELABEL: node 'uart0' not found

解决

dts 复制代码
/* 确保节点已定义 */
uart0: uart@40002000 {
    compatible = "nordic,nrf-uart";
    reg = <0x40002000 0x1000>;
    status = "okay";
};

10.3 属性未定义

问题DT_PROP: property 'current_speed' not found

解决

dts 复制代码
/* 在节点中添加属性 */
&uart0 {
    current-speed = <115200>;
};

10.4 设备未就绪

问题device_is_ready() returns false

解决

dts 复制代码
/* 确保设备状态为okay */
&uart0 {
    status = "okay";
};

10.5 中断配置错误

问题Interrupt not working

解决

dts 复制代码
/* 检查中断配置 */
my_device: device@1000 {
    compatible = "vendor,device";
    reg = <0x1000 0x100>;
    interrupts = <5 0>;  /* 中断号和优先级 */
    status = "okay";
};

十一、最佳实践

11.1 设备树组织建议

#mermaid-svg-qXTNBhQPSTIzvQU9{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-qXTNBhQPSTIzvQU9 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-qXTNBhQPSTIzvQU9 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-qXTNBhQPSTIzvQU9 .error-icon{fill:#552222;}#mermaid-svg-qXTNBhQPSTIzvQU9 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-qXTNBhQPSTIzvQU9 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-qXTNBhQPSTIzvQU9 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-qXTNBhQPSTIzvQU9 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-qXTNBhQPSTIzvQU9 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-qXTNBhQPSTIzvQU9 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-qXTNBhQPSTIzvQU9 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-qXTNBhQPSTIzvQU9 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-qXTNBhQPSTIzvQU9 .marker.cross{stroke:#333333;}#mermaid-svg-qXTNBhQPSTIzvQU9 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-qXTNBhQPSTIzvQU9 p{margin:0;}#mermaid-svg-qXTNBhQPSTIzvQU9 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-qXTNBhQPSTIzvQU9 .cluster-label text{fill:#333;}#mermaid-svg-qXTNBhQPSTIzvQU9 .cluster-label span{color:#333;}#mermaid-svg-qXTNBhQPSTIzvQU9 .cluster-label span p{background-color:transparent;}#mermaid-svg-qXTNBhQPSTIzvQU9 .label text,#mermaid-svg-qXTNBhQPSTIzvQU9 span{fill:#333;color:#333;}#mermaid-svg-qXTNBhQPSTIzvQU9 .node rect,#mermaid-svg-qXTNBhQPSTIzvQU9 .node circle,#mermaid-svg-qXTNBhQPSTIzvQU9 .node ellipse,#mermaid-svg-qXTNBhQPSTIzvQU9 .node polygon,#mermaid-svg-qXTNBhQPSTIzvQU9 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-qXTNBhQPSTIzvQU9 .rough-node .label text,#mermaid-svg-qXTNBhQPSTIzvQU9 .node .label text,#mermaid-svg-qXTNBhQPSTIzvQU9 .image-shape .label,#mermaid-svg-qXTNBhQPSTIzvQU9 .icon-shape .label{text-anchor:middle;}#mermaid-svg-qXTNBhQPSTIzvQU9 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-qXTNBhQPSTIzvQU9 .rough-node .label,#mermaid-svg-qXTNBhQPSTIzvQU9 .node .label,#mermaid-svg-qXTNBhQPSTIzvQU9 .image-shape .label,#mermaid-svg-qXTNBhQPSTIzvQU9 .icon-shape .label{text-align:center;}#mermaid-svg-qXTNBhQPSTIzvQU9 .node.clickable{cursor:pointer;}#mermaid-svg-qXTNBhQPSTIzvQU9 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-qXTNBhQPSTIzvQU9 .arrowheadPath{fill:#333333;}#mermaid-svg-qXTNBhQPSTIzvQU9 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-qXTNBhQPSTIzvQU9 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-qXTNBhQPSTIzvQU9 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-qXTNBhQPSTIzvQU9 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-qXTNBhQPSTIzvQU9 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-qXTNBhQPSTIzvQU9 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-qXTNBhQPSTIzvQU9 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-qXTNBhQPSTIzvQU9 .cluster text{fill:#333;}#mermaid-svg-qXTNBhQPSTIzvQU9 .cluster span{color:#333;}#mermaid-svg-qXTNBhQPSTIzvQU9 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-qXTNBhQPSTIzvQU9 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-qXTNBhQPSTIzvQU9 rect.text{fill:none;stroke-width:0;}#mermaid-svg-qXTNBhQPSTIzvQU9 .icon-shape,#mermaid-svg-qXTNBhQPSTIzvQU9 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-qXTNBhQPSTIzvQU9 .icon-shape p,#mermaid-svg-qXTNBhQPSTIzvQU9 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-qXTNBhQPSTIzvQU9 .icon-shape .label rect,#mermaid-svg-qXTNBhQPSTIzvQU9 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-qXTNBhQPSTIzvQU9 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-qXTNBhQPSTIzvQU9 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-qXTNBhQPSTIzvQU9 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 设备树组织
层次化设计
模块化拆分
注释规范
SoC层
板级层
应用层
按功能分组
复用.dtsi
节点说明
属性说明

11.2 实践建议

建议 说明
使用别名 通过aliases节点定义设备别名
复用dtsi 将通用配置放入.dtsi文件
使用覆盖 使用.overlay修改配置而非修改原文件
添加注释 为节点和属性添加说明
验证语法 使用dtc工具验证设备树语法

11.3 设备树风格指南

dts 复制代码
/* 良好的设备树风格 */

/ {
    /* 使用4空格缩进 */
    model = "My Board";
    compatible = "vendor,myboard";
    
    /* 节点按功能分组 */
    leds {
        compatible = "gpio-leds";
        
        /* 使用一致的命名 */
        led0: led_red {
            gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
            label = "LED_RED";
        };
    };
};

结束语

通过本文的详细介绍,相信您已经全面理解了Zephyr中设备树的概念和使用方法:

知识点 内容
设备树作用 硬件抽象、平台适配、配置灵活
文件类型 .dtsi(包含)、.dts(完整)、.overlay(覆盖)
基本语法 节点、属性、标签、引用
代码使用 DT_NODELABELDT_PROPDEVICE_DT_GET
覆盖文件 修改配置无需修改原设备树

掌握设备树可以帮助您:

  1. 硬件解耦:代码与硬件配置分离
  2. 平台适配:一套代码支持多硬件
  3. 配置灵活:通过配置文件修改硬件参数
  4. 代码复用:通用配置可以复用

建议在实际项目中:

  1. 从现有设备树模板开始
  2. 使用覆盖文件进行定制
  3. 遵循绑定文件规范
  4. 添加详细注释

参考资料

相关推荐
dozenyaoyida7 小时前
Zephyr BLE 上行链路源码拆解:一个空中报文怎么从 radio 跑到应用回调(NCS v3.2.1)
controller·嵌入式开发·ble·host·zephyr·协议栈·软链路层
dozenyaoyida2 天前
Zephyr BLE GATT Server 注册到收发调用链源码解析(NCS v3.2.1)
ble·zephyr·gatt·ble协议栈
iini1 个月前
nRF Connect SDK 开发新体验:VS Code + Claude Code + DeepSeek + Nordic MCP 全流程(蓝牙开发实例)
agent·ai编程·nrf connect sdk·zephyr·蓝牙开发·deepseek·mcp·claude code·nordic mcp
fitpolo1 个月前
详解Zephyr设备树与设备驱动模型
zephyr
乐鑫科技 Espressif1 个月前
用 AI 开发 Zephyr-IoT 应用
人工智能·物联网·esp32·乐鑫科技·zephyr
固执的你2 个月前
串口中断接收协议数据并用状态机解析_printk()打印内容
zephyr
fitpolo2 个月前
Zephyr的SPI
zephyr
toradexsh2 个月前
基于 NXP i.MX8M Plus 测试 Zephyr RTOS
arm·rtos·nxp·imx8mp·zephyr
ScilogyHunter3 个月前
Zephyr串口驱动开发及构建完全指南
驱动开发·uart·zephyr
ScilogyHunter3 个月前
Zephyr Hello World应用开发构建完全指南
zephyr·hello world