瑞芯微RK3568芯片是一款定位中高端的通用型SOC,采用22nm制程工艺,搭载一颗四核Cortex-A55处理器和Mali G52 2EE 图形处理器。RK3568 支持4K 解码和 1080P 编码,支持SATA/PCIE/USB3.0 外围接口。RK3568内置独立NPU,可用于轻量级人工智能应用。RK3568 支持安卓 11 和 linux 系统,主要面向物联网网关、NVR 存储、工控平板、工业检测、工控盒、卡拉 OK、云终端、车载中控等行业。
【公众号】迅为电子
【粉丝群】824412014(加群获取驱动文档+例程)
【视频观看】嵌入式学习之Linux驱动(第七期_设备树_全新升级)_基于RK3568
【购买链接】迅为RK3568开发板瑞芯微Linux安卓鸿蒙ARM核心板人工智能AI主板
设备树使用一种层次结构,其中的根节点(Root Node)是整个设备树的起始点和顶层节点。根节点由一个以/开头的标识符来表示,然后使用{}来包含根节点所在的内容,一个最简单的根节点示例如下所示:
- /dts-v1/; // 设备树版本信息
-
- / {
- // 根节点开始
-
- /*
- 在这里可以添加注释,描述根节点的属性和配置
- */
-
- };
其中第一行的设备树中的版本信息行 dts-v1 是可选的,可以根据需要选择是否保留。这行注释通常用于指定设备树的语法版本。如果您不需要在设备树中指定版本信息,可以将其删除。
设备树中的子节点是根节点的直接子项,用于描述具体的硬件设备或设备集合。子节点采用以下特定的格式来表示:
- [label:] node-name@[unit-address] {
- [properties definitions]
- [child nodes]
- };
以下是对这些部分的详细介绍:
(1)节点标签(Label)(可选):节点标签是一个可选的标识符,用于在设备树中引用该节点。标签允许其他节点直接引用此节点,以便在设备树中建立引用关系。
(2)节点名称(Node Name):节点名称是一个字符串,用于唯一标识该节点在设备树中的位置。节点名称通常是硬件设备的名称,但必须在设备树中是唯一的。
(3)单元地址(Unit Address)(可选):单元地址用于标识设备的实例。它可以是一个整数、一个十六进制值或一个字符串,具体取决于设备的要求。单元地址的目的是区分相同类型的设备的不同实例,例如在下图(55-6)中名为 cpu 的节点通过它们的单元地址值 0 和 1 来区分,名称为 ethernet 的节点通过其单元地址值 fe002000 和 fe003000 来区分。
图 56-1
(4)属性定义(Properties Definitions):属性定义是一组键值对,用于描述设备的配置和特性。属性可以根据设备的需求进行定义,例如寄存器地址、中断号、时钟频率等,关于这些属性会在后面的小节中进行讲解
(5)子节点(Child Nodes):子节点是当前节点的子项,用于进一步描述硬件设备的子组件或配置。子节点可以包含自己的属性定义和更深层次的子节点,形成设备树的层次结构。
reg 属性用于在设备树中指定设备的寄存器地址和大小,提供了与设备树中的物理设备之间的寄存器映射关系。
reg 属性可以在设备节点中有单个值格式和列表值格式这两种常见格式,接下来将对这两种格式进行介绍:
(1)单个值格式如下所示:
reg = ;
这种格式适用于描述单个寄存器的情况。其中,address 是设备的起始寄存器地址,可以是一个整数或十六进制值。size 表示寄存器的大小,即占用的字节数。
例如,假设有一个设备节点 my_device,使用单个值格式的 reg 属性来描述一个 4 字节寄存器的地址和大小,可以这样定义:
- my_device {
- compatible = "vendor,device";
- reg = <0x1000 0x4>;
- // 其他属性和子节点的定义
- }
在这个示例中,`my_device` 设备节点的 `reg` 属性值为 `<0x1000 0x4>`,表示从地址 `0x1000` 开始的 4 字节寄存器区域。
列表值格式如下所示:
reg = ;
当设备具有多个寄存器区域时,可以使用列表值格式的 reg 属性来描述每个寄存器区域的地址和大小。通过这种方式,可以指定多个寄存器的位置和大小,以描述设备的完整寄存器映射。
例如,考虑一个设备节点 my_device,它具有两个寄存器区域,分别是 8 字节和 4 字节大小的寄存器。可以使用列表值格式的 reg 属性来描述这种情况:
- my_device {
- compatible = "vendor,device";
- reg = <0x1000 0x8 0x2000 0x4>;
- // 其他属性和子节点的定义
- };
在这个示例中,my_device 设备节点的 reg 属性值为 <0x1000 0x8 0x2000 0x4>,表示设备有两个寄存器区域。第一个寄存器区域从地址 0x1000 开始,大小为 8 字节;第二个寄存器区域从地址 0x2000 开始,大小为 4 字节。
通过使用 reg 属性,设备树可以提供有关设备寄存器布局和寄存器访问方式的信息。这对于操作系统的设备驱动程序很重要,因为它们需要了解设备的寄存器映射以正确地与设备进行交互和配置。
#address-cells 和 #size-cells 属性用于指定在上个小节中要设置的设备树中地址单元和大小单元的位数。它们提供了设备树解析所需的元数据,以正确解释设备的地址和大小信息。下面对两个属性分别进行介绍:
(1)#address-cells属性:
#address-cells 属性是一个位于设备树根节点的特殊属性,它指定了设备树中地址单元的位数。地址单元是设备树中用于表示设备地址的单个单位。它通常是一个整数,可以是十进制或十六进制值。
#address-cells 属性的值告诉解析设备树的软件在解释设备地址时应该使用多少位来表示一个地址单元。
默认情况下,#address-cells 的值为 2,表示使用两个单元来表示一个设备地址。这意味着设备的地址将由两个整数(每个整数使用指定位数的位)组成。
例如,对于一个使用两个 32 位(4字节)整数表示地址的设备,可以在设备树的根节点中设置 #address-cells 属性为 <2>。
(2)#size-cells 属性:
#size-cells 属性也是一个位于设备树根节点的特殊属性,它指定了设备树中大小单元的位数。大小单元是设备树中用于表示设备大小的单个单位。它通常是一个整数,可以是十进制或十六进制值。
#size-cells 属性的值告诉解析设备树的软件在解释设备大小时应该使用多少位来表示一个大小单元。
默认情况下,#size-cells 的值为 1,表示使用一个单元来表示一个设备的大小。这意味着设备的大小将由一个整数(使用指定位数的位)表示。
例如,对于一个使用一个 32 位(4 字节)整数表示大小的设备,可以在设备树的根节点中设置 #size-cells 属性为 <1>。
这两个属性的存在是为了使设备树能够灵活地描述各种设备的地址和大小表示方式。通过在设备树的根节点中设置适当的 #address-cells 和 #size-cells 值,设备树解析软件能够正确地解释设备节点中的地址和大小信息。
以下是两个个示例,展示了根节点中 #address-cells 和 #size-cells 属性的使用:
示例1:
- node1 {
- #address-cells = <1>;
- #size-cells = <1>;
- node1-child {
- reg = <0x02200000 0x4000>;
- // 其他属性和子节点的定义
- };
- };
在这个示例中,node1-child 节点的 reg 属性使用了 <0x02200000 0x4000> 表示地址和大小。由于 #address-cells 的值为 <1>,表示使用一个单元来表示地址。#size-cells 的值也为 <1>,表示使用一个单元来表示大小。
解释后的地址和大小值如下:
地址部分:0x02200000 被解释为一个地址单元,地址为 0x02200000。
大小部分:0x4000 被解释为一个大小单元,大小为 0x4000。
示例2:
- node1 {
- #address-cells = <2>;
- #size-cells = <0>;
- node1-child {
- reg = <0x0000 0x0001>;
- // 其他属性和子节点的定义
- };
- };
在这个示例中,node1-child 节点的 reg 属性使用了 <0x0000 0x0001> 表示地址。由于 #address-cells 的值为 <2>,表示使用两个单元来表示地址。#size-cells 的值为 <0>,表示不使用单元来表示大小。
解释后的地址值如下:
地址部分:0x0000 0x0001 被解释为两个地址单元,其中第一个地址单元为 0x0000,第二个地址单元为 0x0001。
这种使用 #address-cells 和 #size-cells 属性的方式使得设备树可以适应不同设备的寄存器映射和大小表示方式,并确保设备树解析软件能够正确解释设备的地址和大小信息。
在设备树中,model 属性用于描述设备的型号或者名称。它通常作为设备节点的一个属性,用来提供关于设备的标识信息。model 属性是可选的,但在实际应用中经常被使用。
model 属性的值是一个字符串,可以是设备的型号、名称、或者其他标识符,用来识别设备。该值通常由设备的厂商定义,并且在设备树中使用。
以下是一个示例,展示了如何在设备树中使用 model 属性:
- my_device {
- compatible = "vendor,device";
- model = "My Device XYZ";
- // 其他属性和子节点的定义
- };
在这个示例中,my_device 节点具有 model 属性,其值为 "My Device XYZ"。这个值描述了设备的型号或名称为 "My Device XYZ"。
model 属性通常用于标识和区分不同的设备,特别是当设备节点的 compatible 属性相同或相似时。通过使用不同的 model 属性值,可以更加准确地确定所使用的设备类型。
在设备树中,status 属性用于描述设备或节点的状态。它是设备树中常见的属性之一,用于表示设备或节点的可用性或操作状态。
status 属性的值可以是以下几种:
"okay":表示设备或节点正常工作,可用。
"disabled":表示设备或节点被禁用,不可用。
"reserved":表示设备或节点已被保留,暂时不可用。
"fail":表示设备或节点初始化或操作失败,不可用。
以下是一个示例,展示了如何在设备树中使用 status 属性:
- my_device {
- compatible = "vendor,device";
- status = "okay";
- // 其他属性和子节点的定义
- };
在这个示例中,my_device 节点具有 status 属性,其值为 "okay"。这表示设备处于正常工作状态,可用。
通过使用 status 属性,设备树可以动态地控制设备的启用和禁用状态。这对于在系统启动过程中选择性地启用或禁用设备,或者在运行时根据特定条件调整设备状态非常有用。
在设备树中,compatible 属性用于描述设备的兼容性信息。它是设备树中重要的属性之一,用于识别设备节点与驱动程序之间的匹配关系。
compatible 属性的值是一个字符串或字符串列表,用于指定设备节点与相应的驱动程序或设备描述符兼容的规则。通常,compatible 属性的值由设备的厂商定义,并且在设备树中使用。
以下是一些常见的 compatible 属性值的示例:
(1)单个字符串值:例如 "vendor,device",用于指定设备节点与特定厂商的特定设备兼容。
(2)字符串列表:例如 ["vendor,device1", "vendor,device2"],用于指定设备节点与多个设备兼容,通常用于设备节点具有多种变体或配置。
(3)通配符匹配:例如 "vendor,*",用于指定设备节点与特定厂商的所有设备兼容,不考虑具体的设备标识。
以下是一个示例,展示了如何在设备树中使用 compatible 属性:
- my_device {
- compatible = "vendor,device";
- // 其他属性和子节点的定义
- };
在这个示例中,my_device 节点具有 compatible 属性,其值为 "vendor,device"。这个值用于标识设备节点与特定厂商的特定设备兼容。
compatible 属性也可以具有多个匹配值,用于指定设备节点与多个设备或驱动程序的兼容性规则。这种情况下,compatible 属性的值是一个字符串列表,每个字符串表示一个匹配值。
以下是一个示例,展示了具有多个匹配值的 compatible 属性的用法:
- my_device {
- compatible = ["vendor,device1", "vendor,device2"];
- // 其他属性和子节点的定义
- };
在这个示例中,my_device 节点具有 compatible 属性,其值为 ["vendor,device1", "vendor,device2"]。这表示设备节点与厂商的 device1 和 device2 兼容。
通过使用 compatible 属性,设备树可以提供设备和驱动程序之间的匹配信息。当设备树被操作系统或设备管理软件解析时,会根据设备节点的 compatible 属性值来选择适合的驱动程序进行设备的初始化和配置。
aliases 节点是一个特殊的节点,用于定义设备别名。该节点位于设备树的根部,并具有节点路径 /aliases。
aliases 节点是一个容器节点,包含一组属性,每个属性都代表一个设备别名。每个属性的名称是别名的标识符,而属性的值是被引用设备节点的路径或设备树中其他节点的路径。
以下是一个示例,演示了如何在设备树中使用 aliases 节点:
- aliases {
- mmc0 = &sdmmc0;
- mmc1 = &sdmmc1;
- mmc2 = &sdhci;
- serial0 = "/simple@fe000000/seria1@11c500";
- };
在给定的例子中,有四个别名的定义:
(1)mmc0 别名与设备树中的 sdmmc0 节点相关联。通过使用别名 mmc0,其他设备节点或客户端程序可以更方便地引用 sdmmc0 节点,而不必直接使用其完整路径。
(2)mmc1 别名与设备树中的 sdmmc1 节点相关联。通过使用别名 mmc1,其他设备节点或客户端程序可以更方便地引用 sdmmc1 节点,而不必直接使用其完整路径。
(3)mmc2 别名与设备树中的 sdhci 节点相关联。通过使用别名 mmc2,其他设备节点或客户端程序可以更方便地引用 sdhci 节点,而不必直接使用其完整路径。
(4)serial0 别名与设备树中的路径 /simple@fe000000/seria1@11c500 相关联。通过使用别名 serial0,其他设备节点或客户端程序可以更方便地引用该路径,而不必记住整个路径字符串。
在别名的定义中,& 符号用于引用设备树中的节点。别名的目的是提供可读性更高的名称,使设备树更易于理解和维护。通过使用别名,可以简化设备节点之间的关联,并减少重复输入设备节点的路径。
客户端程序可以使用别名属性名称来引用完整的设备路径或部分路径。当客户端程序将别名字符串视为设备路径时,应检测并使用别名。这样,设备树的使用者可以更方便地引用设备节点,而不必记住复杂的路径结构。
需要注意的是,aliases 节点中定义的别名只在设备树内部可见,不能在设备树之外引用。它们主要用于设备树的内部组织和引用,以提高可读性和可维护性。
chosen节点是设备树中的一个特殊节点,用于传递和存储系统引导和配置的相关信息。它位于设备树的根部,并具有路径/chosen。
chosen节点通常包含以下子节点和属性:
(1)bootargs:用于存储引导内核时传递的命令行参数。它可以包含诸如内核参数、设备树参数等信息。在引导过程中,操作系统或引导加载程序可以读取该属性来获取启动参数。
(2)stdout-path:用于指定用于标准输出的设备路径。在引导过程中,操作系统可以使用该属性来确定将控制台输出发送到哪个设备,例如串口或显示屏。
(3)firmware-name:用于指定系统固件的名称。它可以用于标识所使用的引导加载程序或固件的类型和版本。
(4)linux,initrd-start和linux,initrd-end:这些属性用于指定Linux内核初始化RAM磁盘(initrd)的起始地址和结束地址。这些信息在引导过程中被引导加载程序使用,以将initrd加载到内存中供内核使用。
(5)其他自定义属性:chosen节点还可以包含其他自定义属性,用于存储特定于系统引导和配置的信息。这些属性的具体含义和用法取决于设备树的使用和上下文。
关于chosen节点的实际例子如下所示:
- chosen {
- bootargs = "root=/dev/nfs rw nfsroot=192.168.1.1 console=ttyS0,115200";
- };
在这个示例中,chosen 节点具有一个属性 bootargs,其值为"root=/dev/nfs rw nfsroot=192.168.1.1 console=ttyS0,115200"。
通过这些命令行参数,操作系统或引导加载程序可以配置内核在引导过程中正确地加载 NFS 根文件系统,并将控制台输出发送到指定的串口设备。
通过使用chosen节点,系统引导过程中的相关信息可以方便地传递给操作系统或引导加载程序。这样,系统引导和配置的各个组件可以共享和访问这些信息,从而实现更灵活和可配置的系统引导流程。chosen节点提供了一种通用的机制,使得不同的设备树和引导系统可以在传递信息方面保持一致性,并且可以根据具体需求扩展和自定义。
在设备树中,device_type 节点是用于描述设备类型的节点。它通常作为设备节点的一个属性存在。device_type 属性的值是一个字符串,用于标识设备的类型。
device_type 节点的存在有助于操作系统或其他软件识别和处理设备。它提供了设备的基本分类信息,使得驱动程序、设备树解析器或其他系统组件能够根据设备的类型执行相应的操作。
常见的设备类型包括但不限于:
(1)cpu:表示中央处理器。
(2)memory:表示内存设备。
(3)display:表示显示设备,如液晶显示屏。
(4)serial:表示串行通信设备,如串口。
(5)ethernet:表示以太网设备。
(6)usb:表示通用串行总线设备。
(7)i2c:表示使用 I2C (Inter-Integrated Circuit) 总线通信的设备。
(8)spi:表示使用 SPI (Serial Peripheral Interface) 总线通信的设备。
(9)gpio:表示通用输入/输出设备。
(10)pwm:表示脉宽调制设备。
这些只是一些常见的设备类型示例,实际上,设备类型可以根据具体的硬件和设备树的使用情况进行自定义和扩展。根据设备类型,操作系统或其他软件可以加载适当的驱动程序、配置设备资源、建立设备之间的连接等。
设备树中的自定义属性是用户根据特定需求添加的属性。这些属性可以用于提供额外的信息、配置参数或元数据,以满足设备或系统的特定要求。
在设备树中添加自定义属性时,可以在设备节点或其他适当的节点下定义新的属性。自定义属性可以是整数、字符串、布尔值或其他数据类型。它们的命名应遵循设备树的命名约定,并且应该与已有的属性名称避免冲突。
例如可以在设备树中自定义一个管脚标号的属性pinnum,添加好的设备树源码如下所示:
- my_device {
- compatible = "my_device";
- pinnum = <0 1 2 3 4>;
- };
在上述示例中,my_device 是一个自定义设备节点,并添加了一个自定义属性 pinnum。该属性的值 <0 1 2 3 4> 是一个整数数组,表示管脚的标号(PIN number)。
通过这样定义 pinnum 属性,您可以在设备树中为特定设备指定管教标号,以便操作系统、驱动程序或其他软件组件使用。这可以用于在设备初始化或配置过程中对特定管教进行操作或控制。