Rk3568驱动开发_设备树_9_rk3568 uart
什么是设备树?
以我目前的理解,设备树更像日常生活中用的地图,用户能根据地图去寻找到相应位置
设备树也是如此它描述了硬件设备的连接关系和配置信息,供 CPU(或者更准确地说,是操作系统内核)在启动时读取和解析,从而正确地识别和初始化硬件设备
设备树代码编写与代码解析:
根节点
/ { compatible = \"rockchip,rk3568-evb1-ddr4-v10\", \"rockchip,rk3568\"; };
/ { 为根节点,代表设备树的起点,compatible:这是设备树中非常重要的属性,用于标识设备的兼容性,“rockchip,rk3568-evb1-ddr4-v10”:这是第一个兼容性字符串,表示该设备树描述的是 Rockchip RK3568 的开发板 EVB1 DDR4 V10 版本。这是一个非常具体的描述,用于匹配特定的硬件平台。“rockchip,rk3568”:这是第二个兼容性字符串,表示该设备树也兼容 Rockchip RK3568 芯片。这是一个更通用的描述,用于匹配所有基于 RK3568 芯片的硬件平台。
内核在启动时会读取 compatible 属性,根据这些字符串来选择合适的初始化代码和驱动程序。
如果内核中有一个驱动程序支持 rockchip,rk3568-evb1-ddr4-v10,那么它会被优先加载。如果没有,内核会尝试加载支持 rockchip,rk3568 的驱动程序。
用设备树描述下面信息
设备树里面描述的内容如下:① 、这个芯片是由四个 Cortex-A55 架构的 64 位 CPU 组成。② 、RK3568 内部 uart2,起始地址为 0xfe660000,大小为 256B(0x100)。③ 、RK3568 内部 spi0,起始地址为 0xfe610000,大小为 4KB(0x1000)。④ 、RK3568 内部 i2c5,起始地址为 0xfe5e0000,大小为 4KB(0x1000)。
1、添加 cpus 节点
/ { compatible = \"rockchip,rk3568-evb1-ddr4-v10\", \"rockchip,rk3568\"; cpus { #address-cells = ; #size-cells = ; /* CPU0 节点 */ cpu0: cpu@0 { device_type = \"cpu\"; compatible = \"arm,cortex-a55\"; reg = <0x0 0x0>; }; /* CPU1 节点 */ cpu1: cpu@1 { device_type = \"cpu\"; compatible = \"arm,cortex-a55\"; reg = <0x0 0x100>; }; /* CPU2 节点 */ cpu2: cpu@2 { device_type = \"cpu\"; compatible = \"arm,cortex-a55\"; reg = <0x0 0x200>; }; /* CPU3 节点 */ cpu3: cpu@3 { device_type = \"cpu\"; compatible = \"arm,cortex-a55\"; reg = <0x0 0x300>; }; };};
cpus 表示cpu集合的节点,#address-cells = ;:表示每个 CPU 节点的地址由 2 个单元(64 位)表示,#size-cells = ;:表示 CPU 节点没有大小信息(size 属性)。cpu0: cpu@0:定义了一个名为 cpu0 的 CPU 节点,地址为 0x0。device_type = “cpu”;:表示这是一个 CPU 设备。compatible = “arm,cortex-a55”;:表示该 CPU 是 ARM Cortex-A55 架构,reg = ;:定义了 CPU 的地址,这里是一个 64 位的地址 0x0
reg 属性是一个 64 位的地址,表示设备的地址范围。具体解释如下:
:这是一个由两个单元组成的地址值,每个单元是 32 位(4 字节)。
0x0:表示设备的起始地址的高位部分。
0x100:表示设备的起始地址的低位部分。
因此,reg = ; 表示设备的起始地址是 0x0000000000000100(即 16 进制的 0x100)。
完整代码:
/ { compatible = \"rockchip,rk3568-evb1-ddr4-v10\", \"rockchip,rk3568\"; cpus { #address-cells = ; #size-cells = ; /* CPU0 节点 */ cpu0: cpu@0 { device_type = \"cpu\"; compatible = \"arm,cortex-a55\"; reg = <0x0 0x0>; }; /* CPU1 节点 */ cpu1: cpu@100 { device_type = \"cpu\"; compatible = \"arm,cortex-a55\"; reg = <0x0 0x100>; }; /* CPU2 节点 */ cpu2: cpu@200 { device_type = \"cpu\"; compatible = \"arm,cortex-a55\"; reg = <0x0 0x200>; }; /* CPU3 节点 */ cpu3: cpu@300 { device_type = \"cpu\"; compatible = \"arm,cortex-a55\"; reg = <0x0 0x300>; }; }; /* uart2 节点 */ uart2: serial@fe660000 { compatible = \"rockchip,rk3568-uart\", \"snps,dw-apb-uart\"; reg = <0x0 0xfe660000 0x0 0x100>; }; /* spi0 节点 */ spi0: spi@fe610000 { compatible = \"rockchip,rk3568-spi\", \"rockchip,rk3066-spi\"; reg = <0x0 0xfe610000 0x0 0x1000>; }; /* i2c5 节点 */ i2c5: i2c@fe5e0000 { compatible = \"rockchip,rk3568-i2c\", \"rockchip,rk3399-i2c\"; reg = <0x0 0xfe5e0000 0x0 0x1000>; };};
reg = ; :表示设备的地址,:表示设备的大小
对于外设设备(如 UART、SPI、I2C 等),reg 属性通常包含两个部分:
地址(Address):设备的寄存器基地址。
大小(Size):设备的寄存器区域大小。
对于 CPU 核心,reg 属性通常只包含地址部分,而没有大小部分。这是因为 CPU 核心的寄存器地址通常不需要定义一个固定的大小范围。CPU 核心的寄存器地址通常是固定的,并且由硬件设计决定。
外设设备:reg 属性包含地址和大小部分,因为外设设备的寄存器区域需要定义一个地址范围,以便内核能够正确地访问这些寄存器