【linux】设备树dts文件中节点的属性compatible #address-cells 和#size-cells reg属性

节点是由一堆属性组成的,节点都是具体的设备,不同的设备需要的属性不同,用户可以自定义属性。除了用户自定义属性,有很多属性都是标准属性

 

1. compatible属性

compatible属性也叫做“兼容性”属性,是一个字符串列表,compatible属性用于将设备和驱动绑定起来。字符串列表用于选择设备所要使用的驱动程序,格式如下所示

                                                  “manufacturer,model”

其中manufacturrer表示厂商,model一般是模块对应的驱动名字。比如像下面这个sound节点

    sound {
                           compatible = "fsl,imx6ul-evk-wm8960","fsl,imx-audio-wm8960";

                    . . . . . .

               }

属性有两个,分别是“fsl,imx6ul-evk-wm8960”和“fsl,imx-audio-wm8960”,其中“fsl” 表示厂商是飞思卡尔,“imx6ul-evk-wm8960”和“imx-audio-wm8960”表示驱动模块名字,这个设备首先使用第一个兼容值在 Linux 内核里面查找,看看能不能找到与之匹配的驱动文件,如果没有找到的话就使用第二个兼容值查。

那么怎么找?去哪里找?

一般驱动程序文件都会有一个OF匹配表,此OF匹配表保存着一些compatible值,如果设备节点的compatible属性值和OF匹配表中的任何一个值相等,那么就表示设备可以使用这个驱动。

比如在文件imx-wm8960.c中有如下内容

static const struct of_device_id imx_wm8960_dt_ids[] = {
	{ .compatible = "fsl,imx-audio-wm8960", },
	{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, imx_wm8960_dt_ids);

static struct platform_driver imx_wm8960_driver = {
	.driver = {
		.name = "imx-wm8960",
		.pm = &snd_soc_pm_ops,
		.of_match_table = imx_wm8960_dt_ids,
	},
	.probe = imx_wm8960_probe,
	.remove = imx_wm8960_remove,
};

imx_wm8960_dt_ids 就是 imx-wm8960.c 这个驱动文件的匹配表,此匹配表只有一个匹配值“fsl,imx-audio-wm8960”。如果在设备树中有哪个节点的 compatible 属性值与此相等,那么这个节点就会使用此驱动文件

 

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

这两个属性的值都是无符号32位整型,用于描述子节点的地址信息。#address-cells属性值决定了子节点reg属性中地址信息所占用的字长(32位),#size-cells属性值决定了子节点reg属性中长度信息所占的字长(32 位)(reg属性见下面)

spi4 {
    compatible = "spi-gpio";
    #address-cells = <1>;
    #size-cells = <0>;
    gpio_spi: gpio_spi@0 {
    compatible = "fairchild,74hc595";
    reg = <0>;
    };
}

节点 spi4 的#address-cells = <1>, #size-cells = <0>,说明 spi4 的子节点 reg 属性中起始地址所占用的字长为 1,地址长度所占用的字长为 0。


       因为父节点设置了#address cells = <1>, #size-cells = <0>,因此 addres=0,没有 length 的值,相当于设置了起始地址而没有设置地址长度。

3. reg属性

      #address-cells 和#size-cells 表明了子节点应该如何编写 reg 属性值,一般 reg 属性都是和地址有关的内容,和地址相关的信息有两种:起始地址和地址长度, reg 属性的格式一为:

reg = <address1 length1 address2 length2 address3 length3……>

 reg 属性一般用于描述设备地址空间资源信息,一般都是某个外设的寄存器地址范围信息,比如在 imx6ull.dtsi 中有如下内容:

uart1: serial@02020000 {
    compatible = "fsl,imx6ul-uart",
    "fsl,imx6q-uart", "fsl,imx21-uart";
    reg = <0x02020000 0x4000>;
    interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
    clocks = <&clks IMX6UL_CLK_UART1_IPG>,
    <&clks IMX6UL_CLK_UART1_SERIAL>;
    clock-names = "ipg", "per";
    status = "disabled";
};

上述代码是节点 uart1, uart1 节点描述了 I.MX6ULL 的 UART1 相关信息,重点是第 326 行的 reg 属性。其中 uart1 的父节点 aips1: aips-bus@02000000 设置了#address-cells = <1>、 #sizecells = <1>,因此 reg 属性中 address=0x02020000, length=0x4000。查阅《I.MX6ULL 参考手册》可知, I.MX6ULL 的 UART1 寄存器首地址为 0x02020000,但是 UART1 的地址长度(范围)并没有 0x4000 这么多,这里我们重点是获取 UART1 寄存器首地址。
 

### DTS 文件中 `reg` 属性使用两个 cell 表示地址空间长度的解析 在设备树文件DTS)中,`reg` 属性用于描述硬件资源的内存映射区域。其具体格式由父节点中的 `#address-cells` `#size-cells` 属性决定。当 `reg` 属性使用两个 cell 来表示地址空间长度时,通常意味着: #### 1. **`#address-cells` `#size-cells` 的作用** - `#address-cells=<n>` 定义了子节点的 `reg` 属性中地址部分所需的单元数(cell),即地址字段占据 n 个 cell。 - `#size-cells=<m>` 定义了子节点的 `reg` 属性中大小部分所需的单元数(cell),即长度字段占据 m 个 cell。 因此,当 `#address-cells=<1>` 且 `#size-cells=<1>` 时,`reg` 属性会使用两个 cell 来分别表示起始地址地址范围的大小[^1]。 #### 2. **`reg` 属性的具体格式** 对于上述情况,`reg` 属性的格式如下: ```plaintext reg = <address length>; ``` 其中: - `<address>` 是一个 cell,表示该资源的起始物理地址。 - `<length>` 是另一个 cell,表示该资源的地址范围大小。 例如,在 SPI 控制器的情况下: ```dts spi4: spi@f800 { compatible = "example,spi-controller"; reg = <0xf800 0x100>; /* 起始地址为 f800h,长度为 100h */ }; ``` 在此例子中: - `#address-cells=<1>` 表明地址部分只占用了 1 个 cell。 - `#size-cells=<1>` 表明长度部分也只占用了 1 个 cell。 - 因此,`reg = <0xf800 0x100>;` 中的第一个值 `0xf800` 表示起始地址,第二个值 `0x100` 表示地址范围的大小[^5]。 #### 3. **实际应用案例** 假设有一个 GPIO 控制器节点定义如下: ```dts gpio_controller: gpio@7e200000 { compatible = "brcm,bcm2835-gpio"; reg = <0x7e200000 0x100>; }; ``` 在这个例子中: -节点可能已经设置了 `#address-cells=<1>` `#size-cells=<1>`。 -节点 `gpio@7e200000` 的 `reg` 属性表明它位于物理地址 `0x7e200000` 处,并占据了 `0x100` 字节的空间。 这种设置方式使得操作系统能够通过这些信息正确识别并访问对应的硬件资源[^2]。 #### 4. **特殊情况处理** 如果某个子节点需要特殊的地址或大小配置,则可以在子节点中重新定义 `#address-cells` 或 `#size-cells`,从而覆盖父节点的影响。例如: ```dts parent_node { #address-cells = <1>; #size-cells = <1>; child_node_with_custom_cells { #address-cells = <2>; /* 自定义地址单元数量 */ #size-cells = <2>; /* 自定义大小单元数量 */ reg = <0x0000f800 0x00000100 0x000000ff 0x0000ffff>; }; }; ``` 在这种情况下,`child_node_with_custom_cells` 的 `reg` 属性将按照新的规则解释:前两组数据表示地址,后两组数据表示大小。 --- ### 示例代码 以下是完整的 DTS 配置片段,展示如何使用两个 cell 描述地址空间长度: ```dts / { cpus { #address-cells = <1>; #size-cells = <0>; cpu@0 { reg = <0>; }; /* CPU 0 */ cpu@1 { reg = <1>; }; /* CPU 1 */ }; memory@80000000 { device_type = "memory"; reg = <0x80000000 0x40000000>; /* 物理地址从 0x80000000 开始,总大小为 0x40000000 (1GB) */ }; spi4: spi@f800 { compatible = "example,spi-controller"; reg = <0xf800 0x100>; /* 起始地址为 f800h,长度为 100h */ }; }; ``` ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值