瑞芯微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主板
第59章 实例分析:CPU
59.1 cpus节点
设备树的 cpus 节点是用于描述系统中的处理器的一个重要节点。它是处理器拓扑结构的顶层节点,包含了所有处理器相关的信息。下面将详细介绍设备树的 cpus 节点的各个方面。
节点结构:
cpus 节点是一个容器节点,其下包含了系统中每个处理器的子节点。每个子节点的名称通常为 cpu@X,其中 X 是处理器的索引号。每个子节点都包含了与处理器相关的属性,例如时钟频率、缓存大小等。
处理器属性:
cpu@X 子节点中的属性可以包括以下信息:
(1)device_type:指示设备类型为处理器("cpu")。
(2)reg:指定处理器的地址范围,通常是物理地址或寄存器地址。
(3)compatible:指定处理器的兼容性信息,用于匹配相应的设备驱动程序。
(4)clock-frequency:指定处理器的时钟频率。
(5)cache-size:指定处理器的缓存大小。
处理器拓扑关系:
除了处理器的基本属性,cpus 节点还可以包含其他用于描述处理器拓扑关系的节点,以提供更详细的处理器拓扑信息。这些节点可以帮助操作系统和软件了解处理器之间的连接关系、组织结构和特性。
cpu-map 节点:描述处理器的映射关系,通常在多核处理器系统中使用。
socket 节点:描述多处理器系统中的物理插槽或芯片组。
cluster 节点:描述处理器集群,即将多个处理器组织在一起形成的逻辑组。
core 节点:描述处理器核心,即一个物理处理器内的独立执行单元。
thread 节点:描述处理器线程,即一个物理处理器核心内的线程。
这些节点的嵌套关系可以在 cpus 节点下形成一个层次结构,反映了处理器的拓扑结构。上述这些节点会在后面的小节进行介绍。一个单核CPU设备树和一个四核CPU设备树示例如下所示:
单核CPU示例:
cpus {
#address-cells = <1>;
#size-cells = <0>;
cpu0: cpu@0 {
compatible = "arm,cortex-a7";
device_type = "cpu";
// 其他属性...
};
}
多核CPU示例:
cpus {
#address-cells = <1>;
#size-cells = <0>;
cpu0: cpu@0 {
device_type = "cpu";
compatible = "arm,cortex-a9";
};
cpu1: cpu@1 {
device_type = "cpu";
compatible = "arm,cortex-a9";
};
cpu2: cpu@2 {
device_type = "cpu";
compatible = "arm,cortex-a9";
};
cpu3: cpu@3 {
device_type = "cpu";
compatible = "arm,cortex-a9";
};
}
cpus 节点是一个容器节点,包含了 cpu0 子节点。该节点使用了 #address-cells 和 #size-cells 属性来指定地址和大小的单元数量。
cpu0 子节点代表第一个处理器,具有以下属性:
compatible 属性指定了处理器的兼容性信息
device_type 属性指示设备类型为处理器。
你可以在此基础上继续添加其他属性来描述处理器的特性,如时钟频率、缓存大小等。
59.2 cpu-map、socket、cluster节点
cpu-map 节点是设备树中用于描述大小核架构处理器的映射关系的节点之一。它的父节点必须是 cpus 节点,而子节点可以是一个或多个 cluster 和 socket 节点。通过 cpu-map 节点,可以定义不同核心和集群之间的连接和组织结构。
socket 节点用于描述处理器插槽(socket)之间的映射关系。每个 socket 子节点表示一个处理器插槽,可以使用 cpu-map-mask 属性来指定该插槽使用的核心。通过为每个 socket 子节点指定适当的 cpu-map-mask,可以定义不同插槽中使用的核心。这样,操作系统和软件可以了解到不同插槽之间的核心分配情况。
cluster 节点用于描述核心(cluster)之间的映射关系。每个 cluster 子节点表示一个核心集群,可以使用 cpu-map-mask 属性来指定该集群使用的核心。通过为每个 cluster 子节点指定适当的 cpu-map-mask,可以定义每个集群中使用的核心。这样,操作系统和软件可以了解到不同集群之间的核心分配情况。
通过在 cpu-map 节点中定义 socket 和 cluster 子节点,并为它们指定适当的 cpu-map-mask,可以提供处理器的拓扑结构信息。这对于操作系统和软件来说非常有用,因为它们可以根据这些信息进行任务调度和资源分配的优化,以充分利用大小核架构处理器的性能和能效特性。
一个大小核架构的具体示例如下所示:
cpus {
#address-cells = <2>;
#size-cells = <0>;
cpu-map {
cluster0 {
core0 {
cpu = <&cpu_l0>;
};
core1 {
cpu = <&cpu_l1>;
};
core2 {
cpu = <&cpu_l2>;
};
core3 {
cpu = <&cpu_l3>;
};
};
cluster1 {
core0 {
cpu = <&cpu_b0>;
};
core1 {
cpu = <&cpu_b1>;
};
};
};
cpu_l0: cpu@0 {
device_type = "cpu";
compatible = "arm,cortex-a53", "arm,armv8";
};
cpu_l1: cpu@1 {
device_type = "cpu";
compatible = "arm,cortex-a53", "arm,armv8";
};
cpu_l2: cpu@2 {
device_type = "cpu";
compatible = "arm,cortex-a53", "arm,armv8";
};
cpu_l3: cpu@3 {
device_type = "cpu";
compatible = "arm,cortex-a53", "arm,armv8";
};
cpu_b0: cpu@100 {
device_type = "cpu";
compatible = "arm,cortex-a72", "arm,armv8";
};
cpu_b1: cpu@101 {
device_type = "cpu";
compatible = "arm,cortex-a72", "arm,armv8";
};
};
这个设备树描述了一个具有多个 CPU 核心的系统,包括四个 Cortex-A53 核心和两个 Cortex-A72 核心。下面是对设备树中各个部分的简要介绍:
#address-cells = <2>; 和 #size-cells = <0>;:这些属性指定了设备树中地址和大小的编码方式。
cpu-map:这个节点定义了 CPU 的映射关系。它包含了两个簇(clusters):cluster0 和 cluster1。cluster0 包含了四个核心:core0、core1、core2 和 core3,分别对应 cpu_l0、cpu_l1、cpu_l2 和 cpu_l3。cluster1 包含了两个核心:core0 和 core1,分别对应 cpu_b0 和 cpu_b1。
cpu_l0、cpu_l1、cpu_l2 和 cpu_l3:这些节点描述了 Cortex-A53 核心。它们具有相同的设备类型 cpu 和兼容性属性 "arm,cortex-a53", "arm,armv8"。
cpu_b0 和 cpu_b1:这些节点描述了 Cortex-A72 核心。它们具有相同的设备类型 cpu 和兼容性属性 "arm,cortex-a72", "arm,armv8"。
59.3 core、thread节点
"core" 和 "thread" 节点通常用于描述处理器核心和线程的配置。下面是对这两个节点的详细介绍:
Core 节点用于描述处理器的核心。一个处理器通常由多个核心组成,每个核心可以独立执行指令和任务。
Thread 节点用于描述处理器的线程。线程是在处理器核心上执行的基本执行单元,每个核心可以支持多个线程。
通过使用 Core 和 Thread 节点,设备树可以准确描述处理器的核心和线程的配置,例如可以使用设备树来描述一个具有16个核心的CPU,一个物理插槽,每个集群中有两个核心,每个核心有两个线程的设备树示例,具体设备树如下所示:
cpus {
#address-cells = <2>;
cpu-map {
socket0 {
cluster0 {
core0 {
thread0 {
cpu = <&CPU0>;
};
thread1 {
cpu = <&CPU1>;
};
};
core1 {
thread0 {
cpu = <&CPU2>;
};
thread1 {
cpu = <&CPU3>;
};
};
};
cluster1 {
core0 {
thread0 {
cpu = <&CPU4>;
};
thread1 {
cpu = <&CPU5>;
};
};
core1 {
thread0 {
cpu = <&CPU6>;
};
thread1 {
cpu = <&CPU7>;
};
};
};
};
socket1 {
cluster0 {
core0 {
thread0 {
cpu = <&CPU8>;
};
thread1 {
cpu = <&CPU9>;
};
};
core1 {
thread0 {
cpu = <&CPU10>;
};
thread1 {
cpu = <&CPU11>;
};
};
};
cluster1 {
core0 {
thread0 {
cpu = <&CPU12>;
};
thread1 {
cpu = <&CPU13>;
};
};
core1 {
thread0 {
cpu = <&CPU14>;
};
thread1 {
cpu = <&CPU15>;
};
};
};
};
};
};