1. 设备树节点与属性操作基础
在嵌入式Linux开发中,设备树(Device Tree)已经成为描述硬件配置信息的标准方式。通过设备树,我们可以清晰地定义系统中的各种硬件设备及其相互关系,而无需在内核中硬编码这些信息。设备树由节点(node)和属性(property)组成,每个节点代表一个设备或总线,属性则用于描述该设备的特征。
设备树源文件通常以.dts或.dtsi为扩展名,经过DTC(Device Tree Compiler)编译后生成二进制的.dtb文件,由bootloader加载到内存并传递给内核。内核在启动过程中会解析设备树,根据其中的信息创建设备。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 设备树节点的基本结构
设备树采用树状结构组织硬件信息,根节点为"/",所有其他节点都是它的子节点。每个节点都有名称和可选的地址,格式为:
code复制node-name@unit-address
例如:
dts复制uart@101f1000 {
compatible = "ns16550";
reg = <0x101f1000 0x1000>;
interrupts = <0 12 4>;
};
这个例子定义了一个名为"uart"的节点,位于地址0x101f1000处。节点包含三个属性:
- compatible:指定驱动匹配的字符串
- reg:设备的寄存器地址范围
- interrupts:设备使用的中断信息
3. 获取设备树节点的常用方法
3.1 通过路径获取节点
在内核代码中,我们可以使用以下API获取设备树节点:
c复制struct device_node *of_find_node_by_path(const char *path);
例如,要获取上面定义的UART节点:
c复制struct device_node *uart_node = of_find_node_by_path("/uart@101f1000");
3.2 通过兼容性字符串获取节点
更常用的方法是根据compatible属性查找节点:
c复制struct device_node *of_find_compatible_node(struct device_node *from,
const char *type,
const char *compatible);
例如:
c复制struct device_node *uart_node = of_find_compatible_node(NULL, NULL, "ns16550");
这个函数会遍历设备树,查找compatible属性包含"ns16550"的节点。
3.3 通过父节点和名称获取子节点
如果已知父节点,可以获取特定名称的子节点:
c复制struct device_node *of_get_child_by_name(const struct device_node *node,
const char *name);
例如:
c复制struct device_node *child = of_get_child_by_name(parent_node, "ethernet");
4. 读取节点属性的常用方法
获取到设备树节点后,我们可以读取其中的属性值。内核提供了丰富的API来处理不同类型的属性。
4.1 读取整型属性
对于32位整型属性,可以使用:
c复制int of_property_read_u32(const struct device_node *np,
