LinuxDown

LinuxDown.com
Linux系统下载网——精选每一篇高品质的技术干货
  1. 首页
  2. 开源快讯
  3. 正文

正点原子左老师画的图很形象-正点设备树

2023年7月11日 112点热度

目录

说明:此博客为我自己对正点原子提供的资料学习的记录,内容大部份来始于正点原子资料,你们也可以去下载正点原子的官方资料学习,内容丰富。侵权删。1.哪些是设备树

设备树(DeviceTree),将这个词分开就是“设备”和“树”,描述设备树的文件称作DTS(DeviceTreeSource),这个DTS文件采用树状结构描述板级设备linux移植时需要编译设备树文件吗,也就是开发板上的设备信息,例如CPU数目、内存基地址、IIC插口上接了什么设备、SPI插口上接了什么设备等等。

这是正点原子左老师画的图很形象。树的主干就是系统总线,IIC控制器、GPIO控制器、SPI控制器等都是接到系统主线上的分支。IIC控制器有分为IIC1和IIC2两种,其中IIC1上接了FT5206和AT2424CC0202这两个IIC设备,IIC2上只接了MPU6050这个设备。DTS文件的主要功能就是依照图示的结构来描述板子上的设备信息。

2.DTS、DTB和DTC

设备树源文件扩充名为.dts,而且我们移植Linux的时侯应使用.dtb文件。

DTS是设备树源码文件。

DTB是将DTS编译之后得到的二补码文件。

DTC就是将DTS编译成DTB的工具。

3.DTS句型3.1dtsi头文件

和C语言一样,设备树也支持头文件,设备树的头文件扩充名为.dtsi。

#include "imx6ull.dtsi"

在.dts设备树文件中,可以通过“#include”来引用.h、.dtsi和.dts文件。只是,我们在编撰设备枝杈文件的时侯最好选择.dtsi后缀。

通常.dtsi文件用于描述SOC的内部外设信息,例如CPU构架、主频、外设寄存器地址范围,例如UART、IIC等等。

3.2设备节点

设备树是采用树状结构来描述板子上的设备信息的文件,每位设备都是一个节点,称作设备节点,每位节点都通过一些属性信息来描述节点信息,属性就是键—值对。

“/”是根节点,每位设备树文件只有一个根节点。在设备树中节点命名格式如下:node-name@unit-address

其中“node-name”是节点名字,为ASCII字符串,节点名字应当才能清晰的描述出节点的功能,例如“uart1”就表示这个节点是UART1外设。“unit-address”一般表示设备的地址或寄存器首地址,假如某个节点没有地址或则寄存器的话“unit-address”可以不要,例如“cpu@0”、“interrupt-controller@00a01000”。

编译程序的移植_编译设备树文件命令_linux移植时需要编译设备树文件吗

而且我们也会见到:cpu0:cpu@0这样的方式。上述命令并不是“node-name@unit-address”这样的格式,而是用“:”隔开成了两部份,“:”前面的是节点标签(label),“:”后面的才是节点名字,格式如下所示:

label:node-name@unit-address

引入label的目的就是为了便捷访问节点,可以直接通过&label来访问这个节点,例如通过&cpu0就可以访问“cpu@0”这个节点,而不须要输入完整的节点名字。

3.3标准属性

每位节点都有不同属性,不同的属性又有不同的内容,属性都是通配符对,值可以为空或任意的字节流。设备树源码中常用的几种数据方式如下所示:

①、字符串

compatible="arm,cortex-a7";

上述代码设置compatible属性的值为字符串“arm,cortex-a7”。

②、32位无符号整数

reg=;

上述代码设置reg属性的值为0,reg的值也可以设置为一组值,例如:

reg=;

③、字符串列表

属性值也可以为字符串列表,字符串和字符串之间采用“,”隔开,如下所示:

compatible="fsl,imx6ull-gpmi-nand","fsl,imx6ul-gpmi-nand";

上述代码设置属性compatible的值为“fsl,imx6ull-gpmi-nand”和“fsl,imx6ul-gpmi-nand”

3.3.1compatibe属性

compatible属性也称作“兼容性”属性,这是十分重要的一个属性!compatible属性的值是一个字符串列表,compatible属性用于将设备和驱动绑定上去。字符串列表用于选择设备所要使用的驱动程序,compatible属性的值格式如下所示:

"manufacturer,model"

编译程序的移植_编译设备树文件命令_linux移植时需要编译设备树文件吗

其中manufacturer表示厂商,model通常是模块对应的驱动名子。例如音频设备节点上linux移植时需要编译设备树文件吗,I.MX6U-ALPHA开发板上的音频芯片采用的欧胜(WOLFSON)出品的WM8960,sound节点的compatible属性值如下:

compatible="fsl,imx6ul-evk-wm8960","fsl,imx-audio-wm8960";

属性值有两个,分别为“fsl,imx6ul-evk-wm8960”和“fsl,imx-audio-wm8960”,其中“fsl”表示厂商是飞思卡尔linux手机软件,“imx6ul-evk-wm8960”和“imx-audio-wm8960”表示驱动模块名子。

这个设备首先使用第一个兼容值在Linux内核上面查找,瞧瞧能不能找到与之匹配的驱动文件,假如没有找到的话就使用第二个兼容值查。

3.3.2model属性

model属性值也是一个字符串,通常model属性描述设备模块信息,例如名子哪些的,例如:

model="wm8960-audio";

3.3.3status属性

status属性看名子就晓得是和设备状态有关的,status属性值也是字符串,字符串是设备的状态信息,可选的状态如表所示:

3.3.4#address-cells和#size-cells属性

这两个属性的值都是无符号32位整形,#address-cells和#size-cells这两个属性可以用在任何拥有子节点的设备中,用于描述子节点的地址信息。#address-cells属性值决定了子节点reg属性中地址信息所占用的字长(32位),#size-cells属性值决定了子节点reg属性中宽度信息所占的字长(32位)。#address-cells和#size-cells表明了子节点应当怎样编撰reg属性值,通常reg属性都是和地址有关的内容,和地址相关的信息有两种:起始地址和地址宽度,reg属性的格式一为:

reg=

每位“addresslength”组合表示一个地址范围,其中address是起始地址,length是地址宽度,#address-cells表明address这个数据所占用的字长,#size-cells表明length这个数据所占用的字长,例如:

spi4 { 
	compatible = "spi-gpio"; 
	#address-cells = <1>;
	#size-cells = <0>;
	gpio_spi: gpio_spi@0 { 
	compatible = "fairchild,74hc595"; 
	reg = <0>;
	};
};
	/*因为#address-cells和#size-cells都是描述reg属性的,所以根据reg的值来看,
	其address为0,无length,所以#address-cells值为1,#size-cells为0*/
aips3: aips-bus@02200000 {
	compatible = "fsl,aips-bus", "simple-bus";
	#address-cells = <1>;
	#size-cells = <1>;
	dcp: dcp@02280000 {
		compatible = "fsl,imx6sl-dcp";
		reg = <0x02280000 0x4000>;
	};
};
/*因为#address-cells和#size-cells都是描述reg属性的,所以根据reg的值来看,
其address为0x02280000,length为0x4000,所以#address-cells值为1,#size-cells为1*/

3.3.5reg属性

reg属性上面早已提及过了,reg属性的值通常是(address,length)对。reg属性通常用于描述设备地址空间资源信息,通常都是某个外设的寄存器地址范围信息,例如在imx6ull.dtsi中有如下内容:

aips3: aips-bus@02200000 {
	compatible = "fsl,aips-bus", "simple-bus";
	#address-cells = <1>;
	#size-cells = <1>;
	dcp: dcp@02280000 {
		compatible = "fsl,imx6sl-dcp";
		reg = <0x02280000 0x4000>;
	};
};

每位“addresslength”组合表示一个地址范围,其中address是起始地址,length是地址宽度,所以dcp寄存器的范围是0x2280000到0x2284000。

3.3.6ranges属性

ranges属性值可以为空或则根据(child-bus-address,parent-bus-address,length)格式编撰的数字矩阵,ranges是一个地址映射/转换表,ranges属性每位项目由子地址、父地址和地址空间厚度这三部份组成:

child-bus-address:子总线地址空间的数学地址,由父节点的#address-cells确定此化学地址所占用的字长。

parent-bus-address:父总线地址空间的数学地址,同样由父节点的#address-cells确定此化学地址所占用的字长。

length:子地址空间的宽度,由父节点的#size-cells确定此地址宽度所占用的字长。

假如ranges属性值为空值,说明子地址空间和父地址空间完全相同,不须要进行地址转换,

对于我们所使用的I.MX6ULL来说,子地址空间和父地址空间完全相同,因而会在imx6ull.dtsi中找到大量的值为空的ranges属性。

3.3.7name属性

name属性值为字符串,name属性用于记录节点名字linux 软件,name属性早已被弃用,不推荐使用name属性,一些老的设备树文件可能会使用此属性。

3.3.8device_type属性

device_type属性值为字符串,IEEE1275会用到此属性,用于描述设备的FCode,而且设备树没有FCode,所以此属性也被抛弃了。此属性只能用于cpu节点或则memory节点。

3.4根节点compatible属性

可以看出,compatible有两个值:“fsl,imx6ull-14x14-evk”和“fsl,imx6ull”。上面我们说了,设备节点的compatible属性值是为了匹配Linux内核中的驱动程序,这么根节点中的compatible属性是为了做哪些工作的?通过根节点的compatible属性可以晓得我们所使用的设备,通常第一个值描述了所使用的硬件设备名子,例如这儿使用的是“imx6ull-14x14-evk”这个设备,第二个值描述了设备所使用的SOC,例如这儿使用的是“imx6ull”这颗SOC。Linux内核会通过根节点的compoatible属性查看是否支持此设备,假如支持的话设备都会启动Linux内核。接出来我们就来学习一下Linux内核在使用设备树前后是怎样判定是否支持某款设备的。

3.4.1没使用设备树设备匹配方式

在没有使用设备树曾经,uboot会向Linux内核传递一个称作machineid的值,machineid也就是设备ID,告诉Linux内核自己是个哪些设备,瞧瞧Linux内核是否支持。Linux内核是支持好多设备的,针对每一个设备(板子),Linux内核都用MACHINE_START和MACHINE_END来定义一个machine_desc结构体来描述这个设备。

3.4.1使用设备树设备匹配方式

当Linux内核引入设备树以后就不再使用MACHINE_START了,而是换为了DT_MACHINE_START。DT_MACHINE_START和MACHINE_START基本相同,只是.nr的设置不同,在DT_MACHINE_START上面直接将.nr设置为~0。说明引入设备树之后不会再按照machineid来检测Linux内核是否支持某个设备了。

machine_desc结构体中有个.dt_compat成员变量,此成员变量保存着本设备兼容属性,示例代码43.3.4.5中设置.dt_compat=imx6ul_dt_compat,imx6ul_dt_compat表上面有"fsl,imx6ul"和"fsl,imx6ull"这两个兼容值。只要某个设备(板子)根节点“/”的compatible属性值与imx6ul_dt_compat表中的任何一个值相等,这么就表示Linux内核支持此设备。在3.4中说到,imx6ull-alientek-emmc.dts中根节点的compatible属性值有“fsl,imx6ull”。

4.设备树在系统中的彰显

Linux内核启动的时侯会解析设备树中各个节点的信息,而且在根文件系统的/proc/device-tree目录下按照节点名字创建不同文件夹。

5.设备树常用的OF操作函数5.1查找节点的OF函数(1)of_find_node_by_name函数

of_find_node_by_name函数通过节点名字查找指定的节点,函数原型下:

struct device_node *of_find_node_by_name(struct device_node *from,
										const char *name);

函数参数和返回值涵义如下:

from:开始查找的节点,倘若为NULL表示从根节点开始查找整个设备树。

name:要查找的节点名字。

返回值:找到的节点,倘若为NULL表示查找失败。

(2)of_find_node_by_type函数

of_find_node_by_type函数通过device_type属性查找指定的节点,函数原型如下:

struct device_node *of_find_node_by_type(struct device_node *from, const char *type)

函数参数和返回值涵义如下:

from:开始查找的节点,倘若为NULL表示从根节点开始查找整个设备树。

type:要查找的节点对应的type字符串,也就是device_type属性值。

返回值:找到的节点,倘若为NULL表示查找失败。

(3)of_find_compatible_node函数

of_find_compatible_node函数依据device_type和compatible这两个属性查找指定的节点,函数原型如下:

struct device_node *of_find_compatible_node(struct device_node *from,
										const char *type, 
										const char *compatible)

函数参数和返回值涵义如下:

from:开始查找的节点,倘若为NULL表示从根节点开始查找整个设备树。

type:要查找的节点对应的type字符串,也就是device_type属性值,可以为NULL,表示忽视掉device_type属性。

compatible:要查找的节点所对应的compatible属性列表。

返回值:找到的节点,倘若为NULL表示查找失败

(4)of_find_matching_node_and_match函数

of_find_matching_node_and_match函数通过of_device_id匹配表来查找指定的节点,函数原型如下:

struct device_node *of_find_matching_node_and_match(struct device_node *from,
 												const struct of_device_id *matches,
 												const struct of_device_id **match)

函数参数和返回值涵义如下:

from:开始查找的节点,倘若为NULL表示从根节点开始查找整个设备树。

matches:of_device_id匹配表,也就是在此匹配表上面查找节点。

match:找到的匹配的of_device_id。

返回值:找到的节点,倘若为NULL表示查找失败

(5)of_find_node_by_path函数

of_find_node_by_path函数通过路径来查找指定的节点,函数原型如下:

inline struct device_node *of_find_node_by_path(const char *path)

函数参数和返回值涵义如下:

path:带有全路径的节点名,可以使用节点的别称,例如“/backlight”就是backlight这个节点的全路径。

返回值:找到的节点,倘若为NULL表示查找失败

其实:学习过stm32以后,我认为配置设备树如同是在cubeMx上面配置一样,都是配置一些须要用到的外设,gpio、串口等,配置她们的电气属性;不同的是cubeMx是图形化界面,一些寄存器值可以依据选择的芯片和配置的电气属性手动生成,便捷许多;并且在设备树中就得自己查看芯片指南,而且似乎有一个专门配置的工具,还没去了解。

本作品采用 知识共享署名 4.0 国际许可协议 进行许可
标签: 字符 属性 查找 节点 设备
最后更新:2023年7月11日

Linux系统下载网

每日更新,欢迎收藏♥ 不积跬步无以至千里,加油,共勉。

点赞
< 上一篇
下一篇 >

Linux系统下载网

每日更新,欢迎收藏♥
不积跬步无以至千里,加油,共勉。

最新 热点 随机
最新 热点 随机
Linux系统助你轻松查看sh文件内容 熠熠生辉的C语言Linux开发者的好书和技术参考资料 fedora win7 双系统 Fedora与Win7双系统完美融合 Windows10版本1803和更高版本重置密码18031803 yum安装PHP5.4的亲身体验系统管理员 编译流程(12、GCC、hello.s)预处理 不同操作系统中比较常见的文件系统定义是什么 快速掌握fedora终端打开技巧 Ubuntu下软件安装的几种方式,及apt工具的使用 Red Hat Linux AS下载对比 深度解析Linux网络带宽测试,揭秘速度与激情 文件路径例子及应用软件下载工具 Fedora安装Steam,一键搞定 修改root用户的密码需要注意哪些问题? Linux僵死:解决与预防 开始开发小程序的第一步,你的小程序之旅 Linux移植:地址划分与分配解析 应用软件工程师的隐形之道:驱使硬件设备行动 Linux命令与Shell脚本实践:九个重点指南 phpWeChat微信+网站开发框架功能亮点解析!安装方法
完成远程连接以后就可以安装图形化界面,配置低了会比较卡Linux系统助你轻松查看sh文件内容快速了解Linux内核版本,查看命令揭秘!SUSELinux12SP5的安装步骤及安装方法Linux部署Tomcat项目对比评测基于精简指令集计算原理建立的CPU体系结构有不同的特点和应用场景Linux操作系统:端口查进程用做ASIC芯片的EDA仿真工具来做FPGA的仿真调试ghost linux系统 备受瞩目的Ghost Linux:稳定性与性能共赢Centos7无人值守安装系统架构及工作原理启动畅行编程世界,掌握Linux Java环境LinuxCentOS7中如何安装字体库以及中文字体?Linux Find命令:简单使用正则统计次数本地Windows远程桌面连接阿里云Ubuntu16.04服务器:1linux 解压zip文件 (Linux基础知识)Linux常用的压缩命令和常见用法打造高效稳定的Linux网络应用(Linux基础知识)linuxuserdel命令是系统管理员命令解决Linux命令行中文乱码问题Linux内核下载地址,Linux之旅加速!《Linux命令大全Linuxscp命令》命令
快速入门Linux程序开发的过程及操作步骤详解!! 《Linux应用大全服务器架设》内容涉及Linux系统级解决方案 PDFelement6Promac版(万能编辑器编辑器)中文编辑工具 Linux下的Web服务器开发:八个必知技巧 掌握Linux内核信息,从uname命令开始 掌握Linux配额管理,轻松设置与启用 linux ping大包 Linux网络传输优化:掌握Ping大包技巧 Linux用户如何获得管理员权限?8种方法解析 ghost linux系统 备受瞩目的Ghost Linux:稳定性与性能共赢 安装KaliLinux虚拟机的大小选项中的配置信息介绍 Linux命令用于显示内存使用情况的free(-bkmotV) 简洁实用:Linux用户命令经验分享! lastb列出登入系统失败的用户相关信息补充说明命令 玩转Linux C索引:3.1版本安装指南 suse linux常用版本 SUSE Linux版本大揭秘! (Linux基础知识)Linux系统安装ethtool固件版本的方法 高性能Linux服务器实战:监控、调优与集群应用 Linux稳定版本的选择经验分享 掌握 Linux 服务器监控,8个细节详解,不容错过! Linux系统如何精准查看MySQL版本?
标签聚合
内核 文件 linux服务器 操作 安装 linux系统 应用 电脑 软件 命令
书籍
课程
技术群
技术干货大合集↓
  • 2023年9月 / 118篇
  • 2023年8月 / 122篇
  • 2023年7月 / 122篇
  • 2023年6月 / 119篇
  • 2023年5月 / 123篇
  • 2023年4月 / 113篇
  • 2023年3月 / 265篇
友情链接:

Linux书籍 | Linux命令 | Linux系统 | RHCE红帽认证 | Linux软件 | Linux教程 | CentOS系统 | Linux内核 | Linux服务器 | Linux大神 | IT资源

COPYRIGHT © 2023 LinuxDown.com ALL RIGHTS RESERVED.

京ICP备14023444号-2