设备树的概念
设备树,顾名思义,就是设备组成的树。树这个玩意吧,数据结构里也有,只不过数据结构里的树的叶子是数据,设备树的叶子则是设备,并且没有数据结构那么复杂。是否想起了曾经被各种树支配的恐惧。
Device Tree由一系列被命名的结点(node)和属性(property)组成,而结点本身可包含子节点。属性就是成对出现的键值对name和value。在DTS中,可描述的信息包括:CPU的数量和类别、内存基地址和大小、总线和桥、外设链接、中断控制器和中断使用情况、GPIO控制器和GPIO使用情况、clock控制器和clock使用情况。
/ {
node1 {
a-string-property = "A string";
a-string-list-property = "first string","second string";
a-byte-data-property = [0x01 0x23 0x34 0x56];
child-node1 {
first-child-property;
second-child-property = <1>;
};
child-node2 {
};
}
node2 {
an-empty-property;
a-cell-property = <1 2 3 4>;
child-node1 {
};
}
}
- 1./:根节点,也可以叫root节点,root节点下面含一系列子节点。
2.node:子节点。
3.child-node:根节点的子节点的子节点。
节点属性
1.compatible:
“<manufacturer>,<model>”,可通过根节点的compatible判断属于哪个平台。在根节点的子节点中可判断设备的兼容性。
举个栗子:
/ {
...
compatible = "mediatek,M78XY";
...
fingerprint@0 {
...
compatible = "mediatek,fingerx1","fxx,fingerx2";
...
}
}
说明一下,根节点地下的那个compatible属性里说明了这个项目用的是联发科的M78XY平台。然后根节点下面那个子节点中的compatible属性说明这个指纹(fingerprint)不仅支持联发科的fingerx1还兼容fxx的fingerx2。当然,其实这个compatible和驱动那边有关系,为了匹配上这么写的。
2.name@unit-address:
<name>[@<unit-address>](<>为必须,[]为可选)。name为一个ASCII字符串,用于描述节点对应的设备类型。如果一个节点描述的设备有地址,则应该给出@unit-address。多个相同类型的设备节点的name可以一样,只要unit-address不同即可。设备的unit-address地址也经常在其对应节点的reg属性中给出。
举个栗子:
/ {
...
compatible = "mediatek,M78XY";
...
cpus {
...
cpu@000 {
...
compatible = "mediatek,cortex-M78";
...
}
cpu@001 {
...
compatible = "mediatek,cortex-M78";
...
}
}
spi@11010000{
fingerprint@0 {
...
compatible = "mediatek,fingerx1","fxx,fingerx2";
...
}
}
}
说明一下,emmmmm…感觉没啥好说的…就像这样,cpu相同类型设备,但其地址不同。
3.reg:
<address1 length1[address2 length2][address3 length3]>。父类的address-cells和size-cells决定了子类的相关属性,要包含多少个cell。如果子节点有特殊需求,可自己再定义,这样就可以摆脱父节点的控制。address-cells:决定了address1、2、3包含了几个cell。size-cells:决定了length1、2、3包含了几个cell。子节点中对address-cells与size-cells重赋值可称为重写…吧?…
举个栗子:
/ {
...
#address-cells = <2>;
#size-cells = <2>;
compatible = "mediatek,M78XY";
...
cpus {
...
#address-cells = <1>;
#size-cells = <0>;
cpu@000 {
...
reg = <0x000>;
compatible = "mediatek,cortex-M78";
...
}
cpu@001 {
...
reg = <0x001>;
compatible = "mediatek,cortex-M78";
...
}
}
spi@11010000{
...
reg = <0 0x11010000 0 0x1000>;
fingerprint@0 {
...
#address-cells = <1>;
#size-cells = <0>;
reg = <0>;
compatible = "mediatek,fingerx1","fxx,fingerx2";
...
}
}
}
说明一下,根节点两个address-cells和两个size-cells,spi继承了它,所以reg的前两个值是指address,后两个值则指size。但是呢,指纹没有继承spi,spi中也么有重定义address-cells和size-cells,而是自己重新定义了那两,只有一个address没有size,所以reg里只有一个值,就是他自己本身重新定义的address-cells。
4.ranges:
描述一个从设备地址空间到CPU地址空间的映射关系,为一个地址转换表。表中的每一行都包括了子地址、父地址、在子地址空间内的区域大小。他们的大小(包含的cell)分别由子节点的address-cells的值、父节点的address-cells的值和子节点的size-cells来决定。
这个就不举栗子了吧,太重了。
5.interrupt:
(1).interrupt-controller:一个空属性用来声明这个node接收中断信号。
(2).#interrupt-cells:这是个中断控制器节点的属性,用来标识这个控制器。必须要几个单位做中断描述符。
(3).interrupt-parent:标识此设备节点属于哪一个中断控制器,如果没有设置这个属性,会自动依附父节点的。
(4).interrupts:一个中断标识列表,标识每一个中断输出信号。
举个栗子:
/ {
...
#address-cells = <2>;
#size-cells = <2>;
compatible = "mediatek,M78XY";
interrupt-parents = <&sysirq>;//(3)
cpus {
#address-cells = <1>;
#size-cells = <0>;
cpu@000 {
device_type = "cpu";//类似于name,就是个名字。
reg = <0x000>;
compatible = "mediatek,cortex-M78";
enable-method = "pisc";//使能方法。
clock-frequency = 168000000;//时钟频率。
}
cpu@001 {
device_type = "cpu";
reg = <0x001>;
compatible = "mediatek,cortex-M78";
enable-method = "pisc";
clock-frequency = 168000000;
}
}
spi@11010000{
compatible = "mediatek,M78XY-spi";
reg = <0 0x11010000 0 0x1000>;
inperrupts = <GIC_SPI 122 IRQ_TYPE_LEVEL_LOW>;
fingerprint@0 {
#address-cells = <1>;
#size-cells = <0>;
reg = <0>;
spi-max-frequency = <8000000>;
interrupt-parent = <&pio>;
int-gpio = <&pio 5 0>;
interrupts = <GIC_SPI 5 IRQ_TYPE_EDGE_FALLING>;
compatible = "mediatek,fingerx1","fxx,fingerx2";
pinctrl = ...
...
status = "okey";
}
}
}
说明一下昂,这…根节点的中断属于系统中断控制器,而spi未标明interrupt-parent属性,则说明spi依附于根节点中断控制器,而fingerprint中标明其interrupt-parent是pio,所以fingerprint将使用gpio的中断控制器,int-gpio声明一下将要被用作中断的pinctrl,接下来就是为这个pin标明中断方式。
interrupts第一个属性,GIC_SPI,表示共享中断(SPI),这个值实际上是0,在include\dt-bindings\Interrupt-controller\arm-gic.h被定义,还有GIC_PPI代表每个处理器有独立的中断,第二个属性,就是上面所声明的pin引脚,第三个属性就是中断方式,FALLING下降沿触发。
DTS配置
-
配置文件路径:
32位芯片:kernel/arch/arm/boot/dts/
64位芯片:kernel/arch/arm64/boot/dts/
ps:这是arm-dts的位置,mips、powerpc请自行替换arm… -
使能总线上的控制器:
默认的status值为disable,改为okey为使能的意思,会覆盖默认值(平台dts)。 -
添加设备dto节点,在dts中添加(项目dts)。
device@x,@后是设备地址,平台方案控制器通过片选而来,不需要指定的设备地址,@x也可以没有。
compatible的值与驱动代码中定义的相匹配:与match内.compatible属性值相同。 -
GPIO配置
参考GPIO配置表。
(目前就这样吧,等有啥改动了,回头再改…)
转载请注明出处,谢谢...0.0