当前位置: 首页 > article >正文

设备树总结学习

1,设备树常用语法

(1)字符串:

compatible="rockchip,rk3568"

(2)字符串列表:

compatible = "rockchip,rk3568-evb ", "rockchip,rk3568";

(3)32位无符号数:

reg=<0> 

(4)数组值:

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

举例: 

reg = <0x3000 0x20 0xFE00 0x100>; 

(5) reg range 范围:

举例: 

 ranges = <0x0 0xe0000000 0x00100000>;

 ranges属性值可以为空或者按照 (child-bus-address,parent-bus-address,length) 格式编写的数字矩阵, ranges 是一个地址映射/转换表, ranges 属性每个项目由子地址、父地址和地址空间长度这三部分组成:
child-bus-address: 子总线地址空间的物理地址,由父节点的 #address-cells 确定此物理地址所占用的字长。
parent-bus-address: 父总线地址空间的物理地址,同样由父节点的 #address-cells 确定此物理地址所占用的字长。
length: 子地址空间的长度,由父节点的 #size-cells 确定此地址长度所占用的字长。

 (6)reg属性补充:

 #address-cells

#size-cells

#address-cells属性值决定了子节点 reg属性中地址信息所占用的字长 (32位 ),#size-cells属性值决定了子节点 reg属性中长度信息所占的字长 (32位 )。

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

举例说明:。

soc {
    #address-cells = <2>;
    #size-cells = <1>;
    serial {
        compatible = "xxx";
        reg = <0x4600 0x5000 0x100>;  /*地址信息是:0x00004600 00005000,长度信息是:0x100*/
        };
};

#address-cells属性值为 2#size-cells属性值为 1,

也就是说 子节点的 reg第一位和第二位是起始地址,第三位为长度。

(7)中断: 

#interrupt-cells = <3>;

interrupt-cells 的值是一个无符号32位整数,表示构成一个完整中断specifier所需的32位单元的数量。例如,如果 interrupt-cells 的值为1,则每个中断specifier由一个单元组成;如果值为2,则由两个单元组成,以此类推。

interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;

 第一个参数表示是IPI、PPI、SPI、SGI其中的一个。

参数说明:

IPI:inter-processer interrupt   中断号0~15
PPI:per processor interrupts    中断号16~31
SPI:shared processor interrupts  中断号 32 ~32+224
SGI:software generated interrupts (SGI).

第二个参数表示:是第一个参数里面的第几个,所以是SPI里面的一个。

第三个参数表示:中断触发的类型。(上升沿、下降沿等)

#define IRQ_TYPE_NONE        0
#define IRQ_TYPE_EDGE_RISING    1
#define IRQ_TYPE_EDGE_FALLING    2
#define IRQ_TYPE_EDGE_BOTH    (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)
#define IRQ_TYPE_LEVEL_HIGH    4
#define IRQ_TYPE_LEVEL_LOW    8

其他的interrupt类型举例,#interrupt-cells是中断控制器中的属性。

  1. interrupt-parent = <&gpio4>;

  2. interrupts = <34 0>;

参数说明:

中断控制器是GPIO4,然后使用它的34号中断。(这里的34号,就是指34号引脚),0是指触发的方式(上升沿、下降沿等) .

“interrupt-controller”属性用来声明当前node为中断控制器。

中断映射

interrupt-map = <
    /* physical address range */ /* interrupt specifier */
    0x0 0 0 0x1 0x2 /* example mapping */
    0x1 0 0 0x1 0x3 /* another mapping */
    /* ... more mappings ... */
>;

“interrupt-map”属性用来描述interrupt nexus设备对中断的路由。解析格式为5个元素序列:

  • child unit address:被映射的子节点的单元地址。该属性的cells长度由其所在的总线节点的#address-cells属性描述。
  • child interrupt specifier:被映射的子节点的中断说明符。该节点所需的单元数由#interrupt-cells属性(包含中断映射属性的关系节点)指定。
  • interrupt-parent:单个值指向子域要映射到的父中断。
  • parent unit address:父中断域中的单元地址。指定此地址所需的单元数由父中断域指向节点的#address-cells属性描述。
  • parent interrupt specifier:父域中的中断说明符。所需的单元数由父中断域指向节点的#interrupt-cells属性描述。

参数说明:

  • 0x0 0 0:这是第一个映射的物理地址范围。在应用了 interrupt-map-mask 后,这个地址范围对应于某个具体的设备或设备区域。
  • 0x1 0x2:这是与上述物理地址范围相关联的中断specifier。0x1 可能是中断域标识符,而 0x2 是中断号。
  • 0x1 0 0:这是第二个映射的物理地址范围。
  • 0x1 0x3:这是与第二个物理地址范围相关联的中断specifier。0x1 可能是相同的中断域标识符,而 0x3 是另一个中断号。

(8)时钟:

clocks = <&cru PCLK_GPIO2>, <&cru DBCLK_GPIO2>; 

2,gpio设备树分析

gpio-controller;

#gpio-cells = <2>;

gpio-ranges = <&pinctrl 0 0 32>;

interrupt-controller;

#gpio-cells = <2>; 

 #gpio-cells = <2>; 表示每个 GPIO 的定义需要两个 <cell>

  1. 第一个 <cell> 是 GPIO 的编号。
  2. 第二个 <cell> 是 GPIO 的配置信息。

gpio-ranges 属性包含四个值:

  • 第一个值是引用父节点的phandle(在这个例子中是 &princtrl)。
  • 第二个值是GPIO控制器内部的一个偏移量,表示GPIO引脚范围的起始点。
  • 第三个值是GPIO控制器在系统中的起始GPIO编号
  • 第四个值是GPIO控制器管理的GPIO引脚数量。

3,printctl设备树分析

(1)PinCtrl子系统的工作内容如下:

获取设备树中 pin信息。
根据获取到的 pin信息来设置 pin的复用功能
根据获取到的 pin信息来设置 pin的电气特性, 如驱动能力。

(2) 当前GPIO控制器的0号引脚, 对应pinctrlA中的32号引脚, 数量为32。

引脚复用设置的格式如下:

rockchip,pins = <PIN_BANK PIN_BANK_IDX MUX &phandle>

  • PIN_BANK:引脚所在的GPIO引脚编号。
  • PIN_BANK_IDX:引脚在GPIO引脚中的索引。
  • MUX:引脚的复用功能编号,用于指定引脚的功能。
  • &phandle:一个指向引脚配置节点的引用,通常这个节点定义了引脚的详细配置,如驱动能力、上下拉电阻、电压等级等。
&pinctrl {
    i2c0_pins: i2c0-pins {
        rockchip,pins = <1 9 2 &pcfg_pull_up>; /* I2C0 SDA */
        rockchip,pins = <1 10 2 &pcfg_pull_up>; /* I2C0 SCL */
    };

    spi0_pins: spi0-pins {
        rockchip,pins = <1 4 3 &pcfg_pull_none>; /* SPI0 CS */
        rockchip,pins = <1 5 3 &pcfg_pull_none>; /* SPI0 CLK */
        rockchip,pins = <1 6 3 &pcfg_pull_none>; /* SPI0 MISO */
        rockchip,pins = <1 7 3 &pcfg_pull_none>; /* SPI0 MOSI */
    };
};

 寄存器说明:

#ifndef __DT_BINDINGS_ROCKCHIP_PINCTRL_H__
#define __DT_BINDINGS_ROCKCHIP_PINCTRL_H__

#define RK_GPIO0	0
#define RK_GPIO1	1
#define RK_GPIO2	2
#define RK_GPIO3	3
#define RK_GPIO4	4
#define RK_GPIO6	6

#define RK_PA0		0
#define RK_PA1		1
#define RK_PA2		2
#define RK_PA3		3
#define RK_PA4		4
#define RK_PA5		5
#define RK_PA6		6
#define RK_PA7		7
#define RK_PB0		8
#define RK_PB1		9
#define RK_PB2		10
#define RK_PB3		11
#define RK_PB4		12
#define RK_PB5		13
#define RK_PB6		14
#define RK_PB7		15
#define RK_PC0		16
#define RK_PC1		17
#define RK_PC2		18
#define RK_PC3		19
#define RK_PC4		20
#define RK_PC5		21
#define RK_PC6		22
#define RK_PC7		23
#define RK_PD0		24
#define RK_PD1		25
#define RK_PD2		26
#define RK_PD3		27
#define RK_PD4		28
#define RK_PD5		29
#define RK_PD6		30
#define RK_PD7		31

#endif

功能函数说明,查看手册。 

#define RK_FUNC_GPIO	0
#define RK_FUNC_0	0
#define RK_FUNC_1	1
#define RK_FUNC_2	2
#define RK_FUNC_3	3
#define RK_FUNC_4	4
#define RK_FUNC_5	5
#define RK_FUNC_6	6
#define RK_FUNC_7	7
#define RK_FUNC_8	8
#define RK_FUNC_9	9
#define RK_FUNC_10	10
#define RK_FUNC_11	11
#define RK_FUNC_12	12
#define RK_FUNC_13	13
#define RK_FUNC_14	14
#define RK_FUNC_15	15

查看上面的表,对比 数据手册

PINPIN NameFunc1Func2Func3Func4Func5Func6Die Power Domain
AF24I2C0_SCL/GPIO0_B1_uGPIO0_B1_uI2C0_SCL
AB21I2C0_SDA/GPIO0_B2_uGPIO0_B2_uI2C0_SDA
AG24I2C1_SCL/CAN0_TX_M0/PCIE30X1_BUTTONRSTn/MCU_JTAG_TDO/GPIO0_B3_uGPIO0_B3_uI2C1_SCLCAN0_TX_M0PCIE30X1_BUTTONR STnMCU_JTAG_TDO
AB20I2C1_SDA/CAN0_RX_M0/PCIE20_BUTTONRSTn/MCU_JTAG_TCK/GPIO0_B4_uGPIO0_B4_uI2C1_SDACAN0_RX_M0PCIE20_BUTTONRST nMCU_JTAG_TCK
AC22I2C2_SCL_M0/SPI0_CLK_M0/PCIE20_WAKEn_M0/PWM1_M1/GPIO0_B5_uGPIO0_B5_uI2C2_SCL_M0SPI0_CLK_M0PCIE20_WAKEn_M0PWM1_M1
AA20I2C2_SDA_M0/SPI0_MOSI_M0/PCIE20_PERSTn_M0/PWM2_M1/GPIO0_B6_uGPIO0_B6_uI2C2_SDA_M0SPI0_MOSI_M0PCIE20_PERSTn_M0PWM2_M1
AH26PWM0_M0/CPUAVS/GPIO0_B7_dGPIO0_B7_d

iic0的时钟线和数据线使用的是GPIO0_B1和GPIO0_B2

GPIO0_B1:

#define RK_GPIO0    0

#define RK_PB1        9

#define RK_FUNC_2    2

GPIO0_B2:

#define RK_GPIO0    0

#define RK_PB2       10

#define RK_FUNC_2    2

4,设备树匹配

 设备树的比较的优先顺序:
a. 比较 platform_dev.driver_override 和 platform_driver.drv->name
b. 比较 platform_dev.dev.of_node的compatible属性 和 platform_driver.drv->of_match_table
c. 比较 platform_dev.name 和 platform_driver.id_table
d. 比较 platform_dev.name 和 platform_driver.drv->name
有一个成功, 即匹配成功。

static int platform_match(struct device *dev, struct device_driver *drv)
{
    struct platform_device *pdev = to_platform_device(dev);
    struct platform_driver *pdrv = to_platform_driver(drv);
  
    /* When driver_override is set, only bind to the matching driver */
    /* 针对特殊情况,dev中的driver_override被设置,则只匹配和driver_override名字相同的驱动程序 */
    if (pdev->driver_override)
        return !strcmp(pdev->driver_override, drv->name);
  
    /* Attempt an OF style match first,设备树方式匹配 */
    if (of_driver_match_device(dev, drv))
        return 1;
  
    /* Then try ACPI style match */
    /* 高级配置和电源管理之类的匹配,这里不是我们这次的重点 */
    if (acpi_driver_match_device(dev, drv))
        return 1;
  
    /* Then try to match against the id table */
    /* 有驱动中有id_table,则dev中的名字和任何一个id_table里面的值匹配就认为匹配 */
    if (pdrv->id_table)
        return platform_match_id(pdrv->id_table, pdev) != NULL;
  
    /* fall-back to driver name match */
    /* 驱动和设备的名字匹配 */
    return (strcmp(pdev->name, drv->name) == 0);
}

 


http://www.kler.cn/a/400686.html

相关文章:

  • 为何数据库推荐将IPv4地址存储为32位整数而非字符串?
  • 2. kafka 生产者
  • 掌握Golang中的数据竞争检测:runtime/race包全面教程
  • 【LeetCode 题】只出现一次的数字--其余数字都出现3次
  • Relaxcert SSL证书申请与自动续签之IIS
  • RabbitMQ-死信队列(golang)
  • Arcgis js 加载mvt服务
  • 驾驭未来:Spring Boot汽车资讯门户
  • 网络协议之Ethernet
  • 3、.Net UI库:CSharpSkin - 开源项目研究文章
  • 算法——反转链表(leetcode206)
  • 数据分析-48-时间序列变点检测之在线实时数据的CPD
  • Go语言24小时极速学习教程(三)常见标准库用法
  • 3-KSQL
  • 【C#设计模式(11)——外观模式(Facade Pattern)】
  • 大数据治理:构建数据价值链的关键环节
  • 安全见闻6-9
  • 机器学习day5-随机森林和线性代数1最小二乘法
  • SQL复杂数据类型处理
  • 解决虚拟机未被自动分配ip
  • 康威定律和数据中心网络
  • 【Python项目】基于深度学习的音乐推荐方法研究系统
  • transformers 操作篇
  • OpenHarmony-2.DeviceInfo适配
  • Docker compose部署elasticsearch(单机版)
  • 问题定位学习