第 08 课:Devicetree(设备树)— Zephyr 最重要的知识之一摘要:本课系统讲解 Zephyr 的 Devicetree(设备树)机制。你将理解 Zephyr 为何用 Devicetree 解耦应用与硬件、掌握.dts/.dtsi/.overlay文件的作用与关系,学会通过app.overlay修改板级配置(如 LED、UART),并掌握compatible、status、aliases、chosen等核心概念。最后通过 4 个 ESP32-S3 实验,学会用DT_ALIAS()、DEVICE_DT_GET()、GPIO_DT_SPEC_GET()等宏在 C 代码中读取设备树信息,实现应用代码与具体开发板解耦。目标:掌握 Zephyr 的 Devicetree,学会修改板级硬件配置,并能够在应用程序中读取 Devicetree 信息。为什么要学习 Devicetree?在 STM32Cube 或 ESP-IDF 中,我们通常这样写:#defineLED_GPIOGPIOA#defineLED_PIN5如果换一块板子,就要修改源码。Zephyr 不希望这样。它希望:程序完全不知道 LED 接在哪里。程序只知道LED0,真正接在哪里,由 Devicetree 决定。因此:Application │ ▼ Devicetree │ ▼ Board Hardware这也是 Zephyr 能支持数百块开发板的重要原因。Devicetree 的作用它主要描述两件事情:MCU 上有哪些硬件;每个硬件如何连接、配置和初始化。例如:UART1 SPI2 GPIOA LED Button I2C Flash全部放进 DTS。程序不用再写GPIO_NUM_5,而是写led0。Devicetree 文件有哪些?对于 ESP32-S3:boards/ espressif/ esp32s3_devkitc/里面通常有:esp32s3_devkitc.dts esp32s3_devkitc_defconfig Kconfig.board应用程序可以增加:app.overlay通常目录如下:my_app │ ├── src │ main.c │ ├── prj.conf │ ├── CMakeLists.txt │ └── app.overlay以后99% 的修改都放在 overlay,不要直接修改官方 .dts。为了帮助你快速区分三种文件的使用场景,下面用一张表格对比.dts、.dtsi、.overlay:文件类型作用修改场景注意事项.dts描述某块具体开发板的完整设备树,是最终编译的入口一般不要修改,它由板级厂商维护修改后升级 SDK 会被覆盖;改动应尽量放到 overlay.dtsi存放可复用的公共设备树片段(如 SoC 定义、通用外设),被.dts通过#include引入通常不需要修改,除非要定制 SoC 级默认配置改动会影响所有引用它的板子,风险较大.overlay应用级覆盖文件,在编译时叠加到板级 DTS 之上99% 的应用修改都放这里:新增/修改/禁用节点、改 GPIO、改 UART 等只影响当前应用,不污染官方文件;是 Zephyr 推荐的扩展方式简单记忆:.dts是板子的“底图”,.dtsi是公共“零件库”,.overlay是应用自己的“贴纸”。Overlay 是什么?Zephyr 会先读取:官方 Board DTS然后读取:app.overlayOverlay 可以:新增节点 修改节点 禁用节点 修改 GPIO 修改 UART例如:官方:UART0 ↓ Overlay:UART0 波特率改成 115200一个 LED 节点例如:/{leds{compatible="gpio-leds";led0:led_0{gpios=lt;gpio02GPIO_ACTIVE_HIGHgt;;label="LED0";};};};这里可以看到:led0就是一个 Node Label。程序以后就是找:led0Button例如:buttons{compatible="gpio-keys";button0:button_0{gpios=lt;gpio09GPIO_ACTIVE_LOWgt;;label="SW0";};};Button 和 LED 都只是:NodeDevicetree 的树结构例如:所以叫:Device TreeNode例如:uart0{};就是一个 Node。里面有很多 Property。例如:uart0{current-speed=lt