完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
1. 什么是设备树
1.1 背景 嵌入式底层,一般是用汇编或者C语言进行编程,如内存访问、寄存器访问、外设控制等。在linux 3.x之前,linux内核与硬件抽象层相关采用的是C语言的方式描述板级设备信息,一般位于“kernel/arch/arm/mach-xxx”下,这样的方式有个严重弊端就是板级源码与内核耦合在一起,同一个CPU更改PCB或者调整底层设备时,就得修改板级C源码,然后重新编译内核,导致内核存在大量与内核无关的冗余代码。因此,从linux 3.x后引入独立于内核的设备树(Device Tree),来描述板级信息,存放于“/kernel/arch/arm(arm64)/boot/dts”目录下。 1.2 设备树 设备树,顾名思义,分为设备和树,以树的形式描述设备,所有设备都是“挂”在树上,,设备树不限于传统板级描述。设备树以ASCII字符的形式描述板级信息,类似XML、JSON的易读性格式,方便编写和阅读。
1.3 设备树组成 设备树包括DTC(device tree compiler)编译器,DTS(device tree source)源文件和DTB(device tree blob)目标文件。DTS与C语言一样,包括源文件DTS和头文件DTSI。DTB是二进制目标文件,DTS和DTSI通过编译后输出,在系统起来后加载使用。 DTS DTS是设备树源文件,文件为“.dts”后缀,对设备信息的描述。一个系统对应一个DTS,可能存在多个DTS,但最终通过编译都得出一个DTB文件。DTS可以“include”DTS和DTSI,甚至C语言头文件。 #include "rk3399-firefly-core.dtsi" #include DTSI DTS头文件,文件为“.dtsi”后缀。一个CPU可能用于多个产品上(板级信息),不同产品存在共同的设备信息,那么可以将这些共同的设备描述保存为一个DTSI文件,通过“include”方式实现复用,减少DTS冗余。类似的,DTSI支持include DTS、DTSI、C语言头文件。 DTC 设备树编译工具,将DTS和DTSI编译为目标DTB文件。 DTB 二进制文件,文件为“.dtb”后缀,存放于板级固定存储地址空间,bootloader在引导内核时,首先读取DTB到内存,由内核解析,执行板级相关操作。 1.4 设备树优点
2. 设备树语法 2.1 设备树节点 设备树采用树型结构来描述板级设备信号,每个设备都是一个节点,每个节点都有自己的属性来描述设备,节点和属性就是一对“键值”。因此设备树是由节点和节点属性组成,一个节点可以嵌套多字子节点,子节点还可以包含孙子节点。 【1】节点表示形式 #源自rk3399.dtsi / { compatible = "rockchip,rk3399"; interrupt-parent = <&gic>; #address-cells = <2>; #size-cells = <2>; aliases { dsi0 = &dsi; dsi1 = &dsi1; ethernet0 = &gmac; i2c0 = &i2c0; i2c1 = &i2c1; i2c2 = &i2c2; i2c3 = &i2c3; i2c4 = &i2c4; i2c5 = &i2c5; i2c6 = &i2c6; i2c7 = &i2c7; i2c8 = &i2c8; serial0 = &uart0; serial1 = &uart1; serial2 = &uart2; serial3 = &uart3; serial4 = &uart4; }; 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>; }; }; }; uart0: serial@ff180000 { compatible = "rockchip,rk3399-uart", "snps,dw-apb-uart"; reg = <0x0 0xff180000 0x0 0x100>; clocks = <&cru SCLK_UART0>, <&cru PCLK_UART0>; clock-names = "baudclk", "apb_pclk"; interrupts = reg-shift = <2>; reg-io-width = <4>; pinctrl-names = "default"; pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>; status = "disabled"; }; .......
node-label:node-name@node-address
2.2 节点属性 设备属性一般是以“属性名+属性值”的键值对存在,属性值的表示方式是多元的,可以为空、数字、字符、字符串等。 [tr]值类型举例[/tr]
【1】状态 status ,键值类型为 [tr]键值描述[/tr]
【2】兼容属性 compatible ,键值类型为 compatible = "invensense,mpu6500","mpu65xx"; #先匹配“invensense,mpu6500”,如失败则继续匹配“mpu65xx” 【3】设备信息 model,键值类型为 model= "invensense,mpu6500"; 【4】 地址
#源自rk3399.dtsi i2c4: i2c@ff3d0000 { compatible = "rockchip,rk3399-i2c"; reg = <0x0 0xff3d0000 0x0 0x1000>; clocks = <&pmucru SCLK_I2C4_PMU>, <&pmucru PCLK_I2C4_PMU>; clock-names = "i2c", "pclk"; interrupts = pinctrl-names = "default"; pinctrl-0 = <&i2c4_xfer>; #address-cells = <1>; #size-cells = <0>; status = "disabled"; }; #源自rk3399-firefly-port.dtsi mpu6500: mpu@68 { status = "disabled"; compatible = "invensense,mpu6500"; reg = <0x68>; #父节点是i2c4 ...... 【5】 地址映射 ranges,子、父地址映射表,键值类型为
rk3399设备树文件“range”属性基本为空,表示不需要子、父地址转换,我们单独举个例子说明。 Test: Test@0x0 { #address-cells = <1>; #size-cells = <1>; ranges=<0x0 0x10 0x100> #把字地址空间(0x0——(x0+0x100))映射到父地址空间(0x10——(0x10+0x100)) .... 【6】 GPIO
#源自rk3399.dtsi gpio0: gpio0@ff720000 { compatible = "rockchip,gpio-bank"; reg = <0x0 0xff720000 0x0 0x100>; clocks = <&pmucru PCLK_GPIO0_PMU>; interrupts = gpio-controller; #gpio-cells = <0x2>; #2 cell个描述 interrupt-controller; #interrupt-cells = <0x2>; }; #源自rk3399firefly-port.dtsi leds { compatible = "gpio-leds"; work { label = "firefly:blue:power"; linux,default-trigger = "ir-power-click"; gpios = <&gpio2 27 GPIO_ACTIVE_HIGH>;#与“#gpio-cells”对应,27为管脚序号,GPIO_ACTIVE_HIGH为工作模式 pinctrl-names = "default"; pinctrl-0 = <&led_power>; default-state = "on"; }; 【7】中断
###rk3399电源管理设备(rk808)设备节点,父节点为i2c0。### #源自rk3399-firefly-core.dtsi rk808: pmic@1b { compatible = "rockchip,rk808"; reg = <0x1b>; interrupt-parent = <&gpio1>; #继承GPIO1中断 interrupts = <21 IRQ_TYPE_LEVEL_LOW>;#2个单位中断描述,<中断 触发方式> ..... #源自rk3399.dtsi gpio1: gpio1@ff730000 { compatible = "rockchip,gpio-bank"; reg = <0x0 0xff730000 0x0 0x100>; clocks = <&pmucru PCLK_GPIO1_PMU>; interrupts = gpio-controller; #gpio-cells = <0x2>; interrupt-controller; #interrupt-cells = <0x2>; #子节点需2个单位中断描述 }; |
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
基于米尔瑞芯微RK3576核心板/开发板的人脸疲劳检测应用方案
1009 浏览 0 评论
1194 浏览 1 评论
956 浏览 1 评论
2212 浏览 1 评论
3533 浏览 1 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-28 10:16 , Processed in 0.757545 second(s), Total 72, Slave 54 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号