当前位置:首页 > 嵌入式 > 嵌入式分享
[导读]很多刚接触嵌入式Linux的工程师看到arch/arm64/boot/dts/下成片的.dts、.dtsi文件就头大。其实设备树(Device Tree)本质就是一份"硬件简历"——用树形结构告诉内核:板子上有啥外设、挂在哪个地址、用哪根中断线、连到哪个GPIO。内核据此匹配驱动,不再把硬件信息写死在代码里。


很多刚接触嵌入式Linux的工程师看到arch/arm64/boot/dts/下成片的.dts、.dtsi文件就头大。其实设备树(Device Tree)本质就是一份"硬件简历"——用树形结构告诉内核:板子上有啥外设、挂在哪个地址、用哪根中断线、连到哪个GPIO。内核据此匹配驱动,不再把硬件信息写死在代码里。

设备树的"语法三件套"

一个典型的设备节点长这样:

/ {

   mydev: uart@40000000 {

       compatible = "mycorp,my-uart";

       reg = <0x40000000 0x1000>;

       interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;

       clocks = <&clk 12>;

       status = "disabled";

   };

};

抓住几个核心属性就够了:

compatible:驱动匹配的"身份证",字符串须与驱动中的of_device_id完全一致

reg:设备寄存器基地址和长度,<基地址 大小>

interrupts:中断号和触发方式

status:"okay"启用,"disabled"禁用——SoC级.dtsi通常默认全disabled,板级.dts按需开启

.dtsi是芯片级通用描述(SoC内置IP),.dts是板级描述,通过#include引用dtsi,并用&标签语法覆写节点属性。

实战:给板子加一颗LED

假设要在GPIO0_A0上加一颗状态LED,步骤如下:

1. 在根节点下添加LED节点

/ {

   my_led: led@0 {

       compatible = "gpio-leds";

       label = "sys:status";

       gpios = <&gpio0 0 GPIO_ACTIVE_HIGH>;

       default-state = "on";

       pinctrl-names = "default";

       pinctrl-0 = <&led_pin>;

       status = "okay";

   };

};

2. 配置引脚复用

&pinctrl {

   led_pin: led-grp {

       rockchip,pins = <0 0 0 &pcfg_pull_none>;

   };

};

3. 编译并部署

# 内核源码树内编译

make dtbs -j8


# 或单文件编译

dtc -I dts -O dtb -o myboard.dtb myboard.dts

生成的.dtb放到U-Boot加载路径,重启即可。

上板验证四件套

改完设备树最怕"编译过了但外设不干活",按下面顺序排查:

# 1. 看内核是否解析到节点

dmesg | grep -i "device tree"

# 2. 查看运行时设备树

ls /proc/device-tree/

cat /proc/device-tree/my_led/status

# 3. 反编译当前dtb,确认烧录无误

dtc -I dtb -O dts -o check.dts myboard.dtb

# 4. 确认LED设备是否出现

ls /sys/class/leds/

排查口诀:设备没生效先看status是不是okay;驱动没加载先查compatible字符串是否精确匹配;中断不触发检查interrupt-parent是否指向正确的中断控制器。

新手常踩的三个坑

第一,节点加错位置。必须放在根节点/ { ... };的大括号内,加在外面编译不报错,但节点不会被解析。

第二,引脚复用冲突。同一个物理引脚被两个外设同时声明,SoC会静默使用最后配置的那个,导致前一个外设莫名失效。改DTS前务必核对芯片手册的引脚分配表。

第三,只改.dts忘记重编.dtb。代码改了但烧的还是旧dtb,现象就是"我明明改了啊"——此时用dtc -I dtb -O dts反编译烧录后的dtb一看便知。

写在最后

设备树的学习曲线并不陡,关键是建立"分层修改"的思维:.dtsi不动,只在板级.dts里用&标签覆写;外设默认disabled,用哪个开哪个;所有配置必须对照芯片手册和原理图。掌握这一套,无论是加CAN、调I2C传感器、配SPI屏,还是使能RS485,套路都是一样的——这也是嵌入式Linux硬件适配最硬核的通用能力。



本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除( 邮箱:macysun@21ic.com )。
关闭