首页 > 编程知识 正文

设备树描述的是设备,excel自动生成树状图

时间:2023-05-03 09:16:48 阅读:27515 作者:62

另一方面,设备树来源Linux是世界上最大的开源项目之一,由全球内核开发者维护,所有Linux爱好者都可以提交自己的代码进行审核。

Linux内核包含描述设备的文件。 在早期的Linux内核下,每个平台/计算机的硬件设备描述都是使用. c文件(结构)编写的。 充斥着arch/arm/plat-xxx和arch/arm/mach-xxx目录。

但是,每个平台的硬件设备都不同,因此必须为每个平台编写. c文件。 随着arm平台的增加,描述板级设备的文件也越来越多。

但是,这对于linux内核来说是一个麻烦的代码,如果提交的代码(都是冗馀的硬件描述代码)旨在更新和优化内核,这些板级描述信息将变得毫无意义。

因此,为了便于管理,将各平台的硬件描述信息配置在/arch/arm/boot/dts/目录中,用树构造记述的. dts的文件记述硬件信息。 dts文件是设备树。

二、dis与dtc和dtb的关系dts是设备源树(设备树源)是人可读文件(字符文本文件),内核无法识别,因此dtc ) devicetreecompiler (设备树源)和

dts和dtb文件都位于/arch/arm/boot/dts/目录中。

dtc反汇编:

DTC-IDT B- odts-oxxxx.dts xxxx.dtb

三、dts语法dts用于描述硬件平台信息,在一个设备上有它们的外围设备,并告知内核它们的地址、使用哪个IO等。

设备树的结构类似于树,由几个节点组成。

顶层节点是根节点“/”,节点包含属性(属性类似变量,包含一些信息)和子节点。 这样有几个节点。

位于/dts-v1/;文件开头的这是设备树的版本。

注释:dts文件中的注释方法与c相同,为“/**/”或“//”。

支持头文件:

. dtsi头文件和支持. h的头文件

值得注意的是,dts文件也支持头文件。 扩展名为. dtsi,用于描述soc的一般信息,如cpu、soc和中断控制。 如果使用,请直接浏览此. dtsi文件。 此头文件由soc制造商提供。

例如,如果希望使用正阿尔法开发板下的I2C外围设备与其他模块进行通信,驱动程序需要获取该I2C外围设备的信息(时钟频率、设备地址、IO控制等)。 设备树用于描述这些信息。

我们知道阿尔法开发板使用的是类似I.MX6ULL的soc。 I.MX6ULL的参考手册记载了I2C1为soc/AIPS-2/I2C1。 这些是芯片制造商自己规定的。 与I.MX6ULL对应的头文件包含此类信息。 关于正点原子用,引用头文件,添加具体属性用的“”符号。

前面SOC的外设控制器信息没必要重复描述,放头文件,所有使用该soc的板子都引用这个头文件,具体信息的独立描述,这也就是一个板子一个dts文件。

在节点上,主要为一些属性赋值。对于头文件中已经赋值过的节点,在dts文件中可以重新赋值。

设备树中的节点设备树由多个节点组成。

节点用于描述设备的硬件信息。 用属性值描述。

设备树中只有一个根节点。 引用头文件时,头文件中的根节点与dts文件中的根节点是同一节点。 (节点中的内容)子节点或属性)是两个文件的总和。例如,memory节点有两个。 头文件和dts文件具有根据最后一个赋值重复赋值的属性。 )可以将内容添加到头文件中的节点中的dts文件。

节点命名节点名称格式: node-name@unit-address; 没有reg属性的后面没有单元地址。

例如,I.MX6ULL的I2C4节点是I2C4@021F8000。 http://www.Sina.com/http://www.Sina.com /可在I2C4 I2C4是节点名上的I.MX6ULL参考手册中找到。

单元地址——一般是外围设备寄存器的起始地址(不是绝对的),并且取决于具体节点。

021F8000是单元地址

节点名称前面可能有标签。 用“:”分隔。 标记的含义是为了使节点更容易找到。寄存器的首地址(例如,在dts文件中使用了' I2C4' )。 以这种方式添加时,头文件中的节点前面有I2C4:标记。 标签不属于节日点名。

设备树在系统中的表示形式标签

时候会将设备树在内存中的地址作为参数传递给内核,所以内核能找到这些信息。内核会解析设备树(dtb文件),在/proc/device-tree目录下呈现。

根节点

系统启动后可以在根文件系统里面看到设备树的节点信息。在 /proc/device-tree目录下存放着根节点的属性和子节点 (节点属性以文件的形式存在/proc/device-tree目录下,子节点以文件夹的形式存在)。

soc节点

soc子节点下一般是一些外设控制的子节点,多与寄存器相关。

I2C控制器节点

如图I2C节点下是对I2C外设控制器的描述,如:#address-cells ,status,clock等等属性描述,还有在他下面的子节点

i2c1: i2c@021a0000 {#address-cells = <1>;#size-cells = <0>;compatible = "fsl,imx6ul-i2c", "fsl,imx21-i2c";reg = <0x021a0000 0x4000>;interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;clocks = <&clks IMX6UL_CLK_I2C1>;status = "disabled";}; 具体实例节点,如rtc

下图是对I2C外设的追加,status = “okay”,修改该status属性,使能I2C。rtc@32节点是对I2C外设使用的实例,用于rtc(实时时钟,因为RTC要与cpu通信)。rtc@32,这个32是rtc的器件地址。

注意:追加的是写在根节点外面的,通过“&标签名”追加。

特殊节点

aliases(别名)节点 和chosen 节点。

aliases节点

aliases一般是给节点定义别名用的(为了更好的找到节点),但是我们一般不用别名来访问,一般用标签的形式。内核会使用。

chosen节点

chosen 节点:主要目的是将uboot里面bootargs环境变量值,传递给内核作为命令行参数,cmd line。

在uboot中可以查看环境变量bootarges的值,同时在Linux启动时,会打印一行cmdline它的值和bootarges是一样的。

uboot是如何向内核传递bootarges的呢?
经过查看发现节点chosen中包含bootarges属性(我们并没有去写这个属性),它的值和uboot的bootarges是一致的。
那么chosen节点中bootarges是谁添加的呢?最有可能是uboot添加(拥有属性值(bootarges环境变量),而且对dtb操作过)。

uboot中有一个fdt_chosen函数会对chosen节点做一些修改,其中就有给bootarges属性赋值。

特殊属性

属性是节点中用来描述硬件信息,具体的属性由各个节点来决定(因为每个外设,硬件什么的特性都不一样)。
然而也会有一些约定熟成的属性:compatible(兼容的)属性、

compatible(兼容的)属性

设备节点下的compatible属性用于查找可用的驱动程序,根节点下的compatible属性用于匹配某个版本内核是否支持一个平台/机器。

设备节点下的compatible属性

compatible(兼容的)属性也叫 兼容性属性,值是字符串。它是用来描述兼容性的,在驱动程序中也会维护一个兼容性列表(数组结构体),在这个表里会列出它所支持的设备。通过设备树的compatible属性值,与驱动程序里的列表相匹配(字符串是不是一样),可以确定是否兼容。

compatible 属性值的格式:
自己随意赋值,只要是字符串,它的值可以有多个,也就是可以兼容多种驱动

根节点下的compatible属性

用于查看某个版本linux内核是否支持一个平台。
在没有设备树之前uboot会向内核传递一个machline_id值,内核查看是否支持此机器。

在使用设备树的时候,不使用机器ID而是使用根节点下的compatible属性。内核会维护一段空间来保存compatible属性(所有支持的机器)的值。

根节点下compatible值的格式:
“厂商,设备名” 值可以有多个(兼容多个平台的时候)

modle

它的值也是一个字符串,用来描述设备模块的信息,比如名字什么的,应该是平台名字。

modle = “wm8960-audio”; status属性(相当于使能)

disabled表示不使用,okay表示可用。

#address-cells属性和#size-cells属性

它们的值是32位无符号整型数,可以用到任何一个子节点中,用于描述地址相关的信息。

#address-cells属性: 用于表示子节点reg属性中地址信息的单元数。
#size-cells属性: 用于表示子节点reg属性中长度(地址长度)信息的单元数。
地址信息和地址长度就表示了一段内存。

reg = <寄存器首地址 地址长度>
一个节点的reg属性里的数据会由它的父节点里的#address-cells属性和#size-cells属性决定。

#address-cells = <1>;//表示地址信息占一个单元#size-cells = <1>;//地址长度也占一个单元 reg属性

前面提到了reg属性,**在大部分情况下reg属性是用来描述一段内存的。(I2C设备节点中reg是表示对方的器件地址,不是I2C控制器)**例如:
** reg = <寄存器首地址 地址长度> ** ,其中它里面的单元个数是由它的父节点的#address-cells属性和#size-cells属性决定的。

比如:

father{#address-cells = <1>;//表示地址信息占一个单元#size-cells = <1>;//地址长度也占一个单元 ……son@起始地址{……reg = <起始地址1 长度1>};};father{#address-cells = <2>;//表示地址信息占两个单元#size-cells = <1>;//地址长度也占一个单元 ……son@起始地址{reg = <起始地址1 起始地址2 长度1>};father{#address-cells = <2>;//表示地址信息占两个单元#size-cells = <2>;//地址长度也占两个单元 ……son@起始地址{reg = <起始地址1 起始地址2 长度1 长度2>//这样来表示};};

之前说在大部分情况下用于描述一段内存,I2C最后与器件的描述就例外,它的reg用于描述与之通信的器件地址。

ranges属性

用于地址映射相关的,arm很少用到,在I.MX6ULL 中虽然有这个属性,但是值都是空的,表示不存在地址映射。

name属性和device_type属性

name属性:它的值是一个字符串,用来表示节点的名字。已经被淘汰,在老的平台上可能会看到。

device_type属性:也被淘汰,一般会用到cpu的属性和memory属性描述中。

绑定信息文档(相当于是设备树一些常见设备描述的参考文档)

描述一个设备的信息是用属性的,属性可以自定义,但是一些设备的属性大多类似(磁力计、陀螺仪传感器这一类属性大多通用),所以对于描述这样的设备都会遵循一个规则,这个规则在内核设备树的文档里面有写,叫绑定信息文档。

在 Documentation/devicetree/bindings/ 目录下有许多设备的绑定信息文档。
进入I2C外设这个文件夹,可以看到这些不同命名的.txt的文件,这其实是不同厂家芯片对与I2C这个外设的描述。

打开i2c-imx.txt 就可以看到恩智浦官方对I2C外设的描述:

* Freescale Inter IC (I2C) and High Speed Inter IC (HS-I2C) for i.MXRequired properties://要求的属性- compatible ://支持的驱动 - "fsl,imx1-i2c" for I2C compatible with the one integrated on i.MX1 SoC - "fsl,imx21-i2c" for I2C compatible with the one integrated on i.MX21 SoC - "fsl,vf610-i2c" for I2C compatible with the one integrated on Vybrid vf610 SoC- reg : Should contain I2C/HS-I2C registers location and length//寄存器空间的描述- interrupts : Should contain I2C/HS-I2C interrupt//中断的描述- clocks : Should contain the I2C/HS-I2C clock specifierOptional properties://可选属性- clock-frequency : Constains desired I2C/HS-I2C bus clock frequency in Hz.//时钟频率 The absence of the property indicates the default frequency 100 kHz.- dmas: A list of two dma specifiers, one for each entry in dma-names.- dma-names: should contain "tx" and "rx".- scl-gpios: specify the gpio related to SCL pin- sda-gpios: specify the gpio related to SDA pin- pinctrl: add extra pinctrl to configure i2c pins to gpio function for i2c bus recovery, call it "gpio" stateExamples:i2c@83fc4000 { /* I2C2 on i.MX51 */****//示例**** compatible = "fsl,imx51-i2c", "fsl,imx21-i2c"; reg = <0x83fc4000 0x4000>; interrupts = <63>;};i2c@70038000 { /* HS-I2C on i.MX51 */ compatible = "fsl,imx51-i2c", "fsl,imx21-i2c"; reg = <0x70038000 0x4000>; interrupts = <64>; clock-frequency = <400000>;};i2c0: i2c@40066000 { /* i2c0 on vf610 */ compatible = "fsl,vf610-i2c"; reg = <0x40066000 0x1000>; interrupts =<0 71 0x04>; dmas = <&edma0 0 50>, <&edma0 0 51>; dma-names = "rx","tx"; pinctrl-names = "default", "gpio"; pinctrl-0 = <&pinctrl_i2c1>; pinctrl-1 = <&pinctrl_i2c1_gpio>; scl-gpios = <&gpio5 26 GPIO_ACTIVE_HIGH>; sda-gpios = <&gpio5 27 GPIO_ACTIVE_HIGH>;};~

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。