[DTS]设备树语法

2024-06-22 09:08
文章标签 语法 设备 dts

本文主要是介绍[DTS]设备树语法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、设备树语法

(1)设备树节点语法

[label:] node-name[@unit-address] {[properties definitions];[child nodes];
};

解释:
  label: 可选项,节点别名
  node-name: 节点名
  unit-address: 设备地址
  properties definitions:属性定义
  child nodes:子节点

(2) 属性定义语法

[label:] property-name = value;
[label:] property-name;

属性分为有属性值和无属性值

属性值有三种取值

  • arrays of cells(1个或多个32位数据, 64位数据使用2个32位数据表示),用尖括号表示(< >)
  • string(字符串), 用双引号表示(" ")
  • bytestring(1个或多个字节),用方括号表示([ ])

举例:

//Arrays of cells : cell就是一个32位的数据
interrupts = <17 0xc>;//64bit数据使用2个cell来表示:
clock-frequency = <0x00000001 0x00000000>;//A null-terminated string (有结束符的字符串):
compatible = "simple-bus";//A bytestring(字节序列) :
local-mac-address = [00 00 12 34 56 78];  // 每个byte使用2个16进制数来表示
local-mac-address = [000012345678];       // 每个byte使用2个16进制数来表示//可以是各种值的组合, 用逗号隔开:
compatible = "ns16550", "ns8250";
example = <0xf00f0000 19>, "a strange property format";

二、特殊属性

(1)根节点

#address-cells   // 在它的子节点的reg属性中, 使用多少个u32整数来描述地址(address)
#size-cells      // 在它的子节点的reg属性中, 使用多少个u32整数来描述大小(size)
compatible       // 定义一系列的字符串, 用来指定内核中哪个machine_desc可以支持本设备// 即这个板子兼容哪些平台 // uImage : smdk2410 smdk2440 mini2440     ==> machine_desc         model            // 比如有2款板子配置基本一致, 它们的compatible是一样的// 那么就通过model来分辨这2款板子

cell: 一个u32整数

(2) /memory

所有设备树文件的必需节点,它定义了系统物理内存的 layout

device_type = "memory";
reg             // 用来指定内存的地址、大小

(3) /chosen

传递runtime parameter

bootargs        // 内核command line参数, 跟u-boot中设置的bootargs作用一样

(4) /cpus

/cpus节点下有1个或多个cpu子节点, cpu子节点中用reg属性用来标明自己是哪一个cpu
所以 /cpus 中有以下2个属性:

#address-cells   // 在它的子节点的reg属性中, 使用多少个u32整数来描述地址(address)
#size-cells      // 在它的子节点的reg属性中, 使用多少个u32整数来描述大小(size)// 必须设置为0

(5) /cpus/cpu*

device_type = "cpu";
reg             // 表明自己是哪一个cpu

(6) aliases

用来定义别名

	aliases {ethernet0 = &gmac;i2c0 = &i2c0;i2c1 = &i2c1;i2c2 = &i2c2;mshc0 = &emmc;mshc1 = &sdmmc;mshc2 = &sdio0;mshc3 = &sdio1;serial0 = &uart0;serial1 = &uart1;spi0 = &spi0;spi1 = &spi1;};

三、 引用其他节点

(1) phandle属性引用

节点中的phandle属性, 它的取值必须是唯一的(不要跟其他的phandle值一样)

pic@10000000 {phandle = <1>;interrupt-controller;
};another-device-node {interrupt-parent = <1>;   // 使用phandle值为1来引用上述节点
};

(2)使用别名(本质还是phandle)

PIC: pic@10000000 {interrupt-controller;
};another-device-node {interrupt-parent = <&PIC>;   // 使用label来引用上述节点, // 使用lable时实际上也是使用phandle来引用, // 在编译dts文件为dtb文件时, 编译器dtc会在dtb中插入phandle属性
};

四、包含dtsi文件

#include "rk3288-firefly.dtsi"

  在每个.dsti和.dts中都会存在一个“/”根节点,那么如果在一个设备树文件中include一个.dtsi文件,那么岂不是存在多个“/”根节点了么。其实不然,编译器DTC在对.dts进行编译生成dtb时,会对node进行合并操作,最终生成的dtb只有一个root node。

五、使用宏定义

#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/pinctrl/rockchip.h>
#include <dt-bindings/clock/rk3288-cru.h>
#include <dt-bindings/power/rk3288-power.h>
#include <dt-bindings/thermal/thermal.h>
#include <dt-bindings/power/rk3288-power.h>
#include <dt-bindings/soc/rockchip,boot-mode.h>arm-pmu {compatible = "arm,cortex-a12-pmu";interrupts = <GIC_SPI 151 IRQ_TYPE_LEVEL_HIGH>,<GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>,<GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>,<GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>;};

上面的GIC_SPI和IRQ_TYPE_LEVEL_HIGH都是宏定义,定义在头文件中。

六、属性重写

//rk3288.dtsi
hdmi: hdmi@ff980000 {compatible = "rockchip,rk3288-dw-hdmi";reg = <0x0 0xff980000 0x0 0x20000>;reg-io-width = <4>;#sound-dai-cells = <0>;rockchip,grf = <&grf>;interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;clocks = <&cru  PCLK_HDMI_CTRL>, <&cru SCLK_HDMI_HDCP>, <&cru SCLK_HDMI_CEC>;clock-names = "iahb", "isfr", "cec";power-domains = <&power RK3288_PD_VIO>;status = "disabled";
};//rk3288-firefly.dtsi
&hdmi {ddc-i2c-bus = <&i2c5>;status = "okay";
};

上面的rk3288-firefly.dtsi包含rk3288.dtsi, 然后使用&hdmi引用rk3288.dtsi中的hdmi节点。并在原有的基础上添加ddc-i2c-bus属性,然后将status属性进行重写覆盖
这就体现了dtsi文件的价值,dtsi定义公共的部分,板级差异再进行添加或重写

七、实例解析

/ {compatible = "acme,coyotes-revenge";#address-cells = <1>; //子结点需要一个 cell 描述地址#size-cells = <1>; //子结点需要一个 cell 描述长度interrupt-parent = <&intc>;cpus {#address-cells = <1>;#size-cells = <0>;cpu@0 {compatible = "arm,cortex-a9";reg = <0>;};cpu@1 {compatible = "arm,cortex-a9";reg = <1>;};};serial@101f1000 { //串口compatible = "arm,pl011";reg = <0x101f1000 0x1000 >;interrupts = < 1 0 >;};serial@101f2000 { //串口compatible = "arm,pl011";reg = <0x101f2000 0x1000 >;interrupts = < 2 0 >;};intc: interrupt-controller@10140000 { //中断控制器compatible = "arm,pl190";reg = <0x10140000 0x1000 >;interrupt-controller;#interrupt-cells = <2>;};spi@10115000 { //spi 控制器compatible = "arm,pl022";reg = <0x10115000 0x1000 >; 起始地址为 0x10115000,长度为 0x1000interrupts = < 4 0 >;};external-bus { //external bus 桥#address-cells = <2> //子结点需要两个 cell 描述地址,片选#size-cells = <1>; //子结点需要一个 cell 描述长度ranges = <0 0 0x10100000 0x10000 // Chipselect 1, Ethernet 片选 0 0,地址 0x10100000 ,长度 0x100001 0 0x10160000 0x10000 // Chipselect 2, i2c controller2 0 0x30000000 0x1000000>; // Chipselect 3, NOR Flashethernet@0,0 {compatible = "smc,smc91c111";reg = <0 0 0x1000>;interrupts = < 5 2 >;};i2c@1,0 {compatible = "acme,a1234-i2c-bus";#address-cells = <1>; //rtc 需要一个 cell 描述地址#size-cells = <0>; //rtc 不需要 0 描述长度reg = <1 0 0x1000>;rtc@58 {compatible = "maxim,ds1338";reg = <58>;interrupts = < 7 3 >;};};flash@2,0 {compatible = "samsung,k8f1315ebm", "cfi-flash";reg = <2 0 0x4000000>;};};
};

解析:
(1) 根节点
  compatible: 内核通过root节点"/"的compatible属性来判断它启动的是哪个machine。
  #address-cells : 子结点(reg属性)需要多少个cell描述地址。
  #size-cells : 子结点(reg属性)需要多少个cell描述长度。
  interrupt-parent : 标示该节点属于哪个中断控制器,如果没有该属性,则依附于父节点。

(2) cpus节点
  #address-cells : 同上
  #size-cells : 同上

(3) cpu节点
  @unit-address: 可选项,设备地址,节点名相同时可以通过这个来区分不同节点。unit-address地址也经常在其对应的reg属性中给出。
  reg : region,描述设备地址
格式: reg = <address1 length1 [address2 length2] [address3 length3]>

(4) serial节点
  compatible: 外设节点上的compatible属性用于驱动和设备的绑定(匹配)
  reg: 外设基地址和偏移量 ,比如:reg = <0x101f1000 0x1000 >
  interrupts: 中断号和标识(上升沿,下降沿等), 里面多少个值要根据中断控制器的#interrupt-cells属性来决定。而#interrupt-cells属性值要由中断控制器的类型决定。

中断控制器类型:
GIC: Generic Interrupt Controller(通用中断控制器)
中断类型,中断号,标识(上升沿,下降沿等)
VIC : Vectored Interrupt Controller(向量中断控制器)
中断号
NVIC:Nested Vectored Interrupt Controller(内嵌向量中断控制器)
中断号,中断优先级

参考: Documentation\devicetree\bindings\interrupt-controller

(5) interrupt-controller节点
  compatible: 中断控制器类型,查看上面路径下的文件来获知。
  reg:同上
  interrupt-controller:空属性,用来声明这个节点接收中断信号。
  #interrupt-cells:标识该控制器需要几个cell来描述中断,其实就是决定了interrupts属性需要几个cell

(6) external-bus节点
  ranges: 地址转换表,每一行都包含子地址、父地址、在子地址空间内的区域大小。
ranges属性值为空的话,表示1:1映射。

ranges属性值的格式 <local地址, parent地址, size>
  local地址的个数取决于当前含有ranges属性的节点的#address-cells属性的值。
  parent地址的个数取决于父节点的#address-cells的值。
  size取决于当前含有ranges属性的节点的#size-cells属性的值。

(7) rtc节点
  reg: i2c设备地址

欢迎大家关注我的微信公众号!!

这篇关于[DTS]设备树语法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1083854

相关文章

如何编写Linux PCIe设备驱动器 之二

如何编写Linux PCIe设备驱动器 之二 功能(capability)集功能(capability)APIs通过pci_bus_read_config完成功能存取功能APIs参数pos常量值PCI功能结构 PCI功能IDMSI功能电源功率管理功能 功能(capability)集 功能(capability)APIs int pcie_capability_read_wo

音视频入门基础:WAV专题(10)——FFmpeg源码中计算WAV音频文件每个packet的pts、dts的实现

一、引言 从文章《音视频入门基础:WAV专题(6)——通过FFprobe显示WAV音频文件每个数据包的信息》中我们可以知道,通过FFprobe命令可以打印WAV音频文件每个packet(也称为数据包或多媒体包)的信息,这些信息包含该packet的pts、dts: 打印出来的“pts”实际是AVPacket结构体中的成员变量pts,是以AVStream->time_base为单位的显

C++语法知识点合集:11.模板

文章目录 一、非类型模板参数1.非类型模板参数的基本形式2.指针作为非类型模板参数3.引用作为非类型模板参数4.非类型模板参数的限制和陷阱:5.几个问题 二、模板的特化1.概念2.函数模板特化3.类模板特化(1)全特化(2)偏特化(3)类模板特化应用示例 三、模板分离编译1.概念2.模板的分离编译 模版总结 一、非类型模板参数 模板参数分类类型形参与非类型形参 非类型模板

Java基础回顾系列-第一天-基本语法

基本语法 Java基础回顾系列-第一天-基本语法基础常识人机交互方式常用的DOS命令什么是计算机语言(编程语言) Java语言简介Java程序运行机制Java虚拟机(Java Virtual Machine)垃圾收集机制(Garbage Collection) Java语言的特点面向对象健壮性跨平台性 编写第一个Java程序什么是JDK, JRE下载及安装 JDK配置环境变量 pathHe

Hibernate框架中,使用JDBC语法

/*** 调用存储过程* * @param PRONAME* @return*/public CallableStatement citePro(final String PRONAME){Session session = getCurrentSession();CallableStatement pro = session.doReturningWork(new ReturningWork<C

ORACLE语法-包(package)、存储过程(procedure)、游标(cursor)以及java对Result结果集的处理

陈科肇 示例: 包规范 CREATE OR REPLACE PACKAGE PACK_WMS_YX IS-- Author : CKZ-- Created : 2015/8/28 9:52:29-- Purpose : 同步数据-- Public type declarations,游标 退休订单TYPE retCursor IS REF CURSOR;-- RETURN vi_co_co

文章解读与仿真程序复现思路——电力自动化设备EI\CSCD\北大核心《考虑燃料电池和电解槽虚拟惯量支撑的电力系统优化调度方法》

本专栏栏目提供文章与程序复现思路,具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源程序擅长文章解读,论文与完整源程序,等方面的知识,电网论文源程序关注python

全英文地图/天地图和谷歌瓦片地图杂交/设备分布和轨迹回放/无需翻墙离线使用

一、前言说明 随着风云局势的剧烈变化,对我们搞软件开发的人员来说,影响也是越发明显,比如之前对美对欧的软件居多,现在慢慢的变成了对大鹅和中东以及非洲的居多,这两年明显问有没有俄语或者阿拉伯语的输入法的增多,这要是放在2019年以前,一年也遇不到一个人问这种需求场景的。 地图应用这块也是,之前的应用主要在国内,现在慢慢的多了一些外国的应用场景,这就遇到一个大问题,我们平时主要开发用的都是国内的地

ElasticSearch的DSL查询⑤(ES数据聚合、DSL语法数据聚合、RestClient数据聚合)

目录 一、数据聚合 1.1 DSL实现聚合 1.1.1 Bucket聚合  1.1.2 带条件聚合 1.1.3 Metric聚合 1.1.4 总结 2.1 RestClient实现聚合 2.1.1 Bucket聚合 2.1.2 带条件聚合 2.2.3 Metric聚合 一、数据聚合 聚合(aggregations)可以让我们极其方便的实现对数据的统计、分析、运算。例如:

驱动(RK3588S)第七课时:单节点设备树

目录 需求一、设备树的概念1、设备树的后缀名:2、设备树的语法格式3、设备树的属性(重要)4、设备树格式举例 二、设备树所用函数1、如何在内核层种获取设备树节点:2、从设备树上获取 gpio 口的属性3、获取节点上的属性只针对于字符串属性的4、函数读取 np 结点中的 propname 属性的值,并将读取到的 u32 类型的值保存在 out_value 指向的内存中,函数的返回值表示读取到的