1.概念

设备树用于实现驱动代码与设备信息相分离。驱动代码只负责处理驱动的逻辑而关于设备的具体信息存放到设备树文件中。(dts文件,编译后为dtb文件)。一个dts文件对应一个ARM的machine,位置:/arch/arm/boot/dts

一般dtb文件的开头会#include<xxxx.dtsi>。(eg.#include "zynq-7000.dtsi")在同样的目录下能够找到该dtsi文件。这个文件是一个SOC公用的部分或者多个machine共同的部分。dts文件只需要改写差异部分即可。由于编译设备树的时候,相同节点的不同属性信息会被合并,相同节点的相同属性会被重写。所以,比如我要做的是iic的设备树,那么把dtsi里面的I2C的设备树整个节点copy出来到dts文件当中再进行改写即可(引用)。

2.设备数框架

设备树用树状结构描述设备信息,它有以下几种特性

  1. 每个设备树文件都有一个根节点,每个设备都是一个节点。
  2. 节点间可以嵌套,形成父子关系,这样就可以方便的描述设备间的关系。
  3. 每个设备的属性都用一组key-value对(键值对)来描述。
  4. 每个属性的描述用;结束

所以,一个设备树的基本框架可以写成下面这个样子,一般来说,/表示板子,它的子节点node1表示SoC上的某个控制器,控制器中的子节点node2表示挂接在这个控制器上的设备(们)

/{                                  //根节点
node1{ //node1是节点名,是/的子节点
key=value; //node1的属性
...
node2{ //node2是node1的子节点
key=value; //node2的属性
...
}
} //node1的描述到此为止
node3{
key=value;
...
}
}

  

节点名

格式:<name>[@<unit_address>]

axi_hdmi@70e00000 {
compatible = "adi,axi-hdmi-tx-1.00.a";
reg = <0x70e00000 0x10000>;
dmas = <&axi_vdma_0 0>;
dma-names = "video";
clocks = <&hdmi_clock>; port {
axi_hdmi_out: endpoint {
remote-endpoint = <&adv7511_in>;
};
};

  比如这个,节点名是hdmi,设备地址为70e00000。这个设备地址一般是在处理器的用户手册,或者hdf文件里面有的。一些可更改的设备地址同样可以在block designd的address editor里面配置(VIVADO)。reg<address offset>中的地址要和节点名那里的地址对应上哦~~

KEY

在设备树中,键值对是描述属性的方式,比如,Linux驱动中可以通过设备节点中的"compatible"这个属性查找设备节点。
Linux设备树语法中定义了一些具有规范意义的属性,包括:compatibleaddressinterrupt等,这些信息能够在内核初始化找到节点的时候,自动解析生成相应的设备信息。此外,还有一些Linux内核定义好的,一类设备通用的有默认意义的属性,这些属性一般不能被内核自动解析生成相应的设备信息,但是内核已经编写的相应的解析提取函数,常见的有 "mac_addr""gpio""clock""power""regulator" 等等。

compatible

设备节点中对应的节点信息已经被内核构造成struct platform_device。驱动可以通过相应的函数从中提取信息。compatible属性是用来查找节点的方法之一,另外还可以通过节点名或节点路径查找指定节点。dm9000驱动中就是使用下面这个函数通过设备节点中的"compatible"属性提取相应的信息,所以二者的字符串需要严格匹配。
在下面的这个dm9000的例子中,我们在相应的板级dts中找到了这样的代码块:

然后我们取内核源码中找到dm9000的网卡驱动,从中可以发现这个驱动是使用的设备树描述的设备信息(这不废话么,显然用设备树好处多多)。我们可以找到它用来描述设备信息的结构体,可以看出,驱动中用于匹配的结构使用的compatible和设备树中一模一样,否则就可能无法匹配,这里另外的一点是struct of_device_id数组的最后一个成员一定是空,因为相关的操作API会读取这个数组直到遇到一个

address

  • #address-cells,用来描述子节点"reg"属性的地址表中用来描述首地址的cell的数量,
  • #size-cells,用来描述子节点"reg"属性的地址表中用来描述地址长度的cell的数量。

有了这两个属性,子节点中的"reg"就可以描述一块连续的地址区域。下例中,父节点中指定了#address-cells = <2>;#size-cells = <1>,则子节点dev-bootscs0中的reg中的前两个数表示一个地址,即MBUS_ID(0xf0, 0x01)0x1045C,最后一个数的表示地址跨度,即是0x4

interrupts

  • interrupt-controller 一个空属性用来声明这个node接收中断信号,即这个node是一个中断控制器。
  • #interrupt-cells,是中断控制器节点的属性,用来标识这个控制器需要几个单位做中断描述符,用来描述子节点中"interrupts"属性使用了父节点中的interrupts属性的具体的哪个值。一般,如果父节点的该属性的值是3,则子节点的interrupts一个cell的三个32bits整数值分别为:<中断域 中断 触发方式>,如果父节点的该属性是2,则是<中断 触发方式>
  • interrupt-parent,标识此设备节点属于哪一个中断控制器,如果没有设置这个属性,会自动依附父节点的
  • interrupts,一个中断标识符列表,表示每一个中断输出信号

Linux设备树学习的更多相关文章

  1. Linux设备驱动程序学习之分配内存

    内核为设备驱动提供了一个统一的内存管理接口,所以模块无需涉及分段和分页等问题. 我已经在第一个scull模块中使用了 kmalloc 和 kfree 来分配和释放内存空间. kmalloc 函数内幕 ...

  2. Linux设备驱动程序学习----3.模块的编译和装载

    模块的编译和装载 更多内容请参考Linux设备驱动程序学习----目录 1. 设置测试系统 第1步,要先从kernel.org的镜像网站上获取一个主线内核,并安装到自己的系统中,因为学习驱动程序的编写 ...

  3. Linux设备树语法详解

    概念 Linux内核从3.x开始引入设备树的概念,用于实现驱动代码与设备信息相分离.在设备树出现以前,所有关于设备的具体信息都要写在驱动里,一旦外围设备变化,驱动代码就要重写.引入了设备树之后,驱动代 ...

  4. Linux设备树语法详解【转】

    转自:http://www.cnblogs.com/xiaojiang1025/p/6131381.html 概念 Linux内核从3.x开始引入设备树的概念,用于实现驱动代码与设备信息相分离.在设备 ...

  5. 宋牧春: Linux设备树文件结构与解析深度分析(2) 【转】

    转自:https://mp.weixin.qq.com/s/WPZSElF3OQPMGqdoldm07A 作者简介 宋牧春,linux内核爱好者,喜欢阅读各种开源代码(uboot.linux.ucos ...

  6. linux 设备树【转】

    转自:http://blog.csdn.net/chenqianleo/article/details/77779439 [-] linux 设备树 为什么要使用设备树Device Tree 设备树的 ...

  7. linux设备树语法

    设备树语法及绑定 概述 Device Tree是一种用来描述硬件的数据结构,类似板级描述语言,起源于OpenFirmware(OF). 就ARM平台来说,设备树文件存放在arch/arm/boot/d ...

  8. Linux设备驱动程序学习----1.设备驱动程序简介

    设备驱动程序简介 更多内容请参考Linux设备驱动程序学习----目录 1. 简介   Linux系统的优点是,系统内部实现细节对所有人都是公开的.Linux内核由大量复杂的代码组成,设备驱动程序可以 ...

  9. Linux设备驱动程序学习----2.内核模块与应用程序的对比

    内核模块与应用程序的对比 更多内容请参考Linux设备驱动程序学习----目录 1. 内核模块与应用程序的对比 内核模块和应用程序之间的不同之处: 大多数中小规模的应用程序是从头到尾执行单个任务,而模 ...

随机推荐

  1. 彻底解决Spring mvc中时间的转换和序列化等问题

    痛点 在使用Spring mvc 进行开发时我们经常遇到前端传来的某种格式的时间字符串无法用java8的新特性java.time包下的具体类型参数来直接接收. 我们使用含有java.time封装类型的 ...

  2. 探讨 Git 代码托管平台的若干问题

    关于 Git 版本控制软件种类繁多,维基百科收录的最早的版本控制系统是 1972 年贝尔实验室开发的 Source Code Control System.1986 年 Concurrent Vers ...

  3. C - Water The Garden

    It is winter now, and Max decided it's about time he watered the garden. The garden can be represent ...

  4. P2774 方格取数(网络流)

    https://www.luogu.com.cn/problem/P2774 在一个有 m×n 个方格的棋盘中,每个方格中有一个正整数. 现要从方格中取数,使任意2个数所在方格没有公共边,且取出的数的 ...

  5. 各大厂商发力5G新机,未来全球手机市场或将呈现新格局

    随着5G商用将正式于今年开启落地,运营商和手机厂商都在为新一代网络制式积极做好准备.对于运营商来说,它们在不断增加5G基站的建设,让5G信号覆盖更广泛的范围.而对于手机厂商来说,它们在努力推出旗下的5 ...

  6. Windows平台VC++ 6.0 下的网络编程学习 - 简单的测试winsock.h头文件

    最近学习数据结构和算法学得有点累了(貌似也没那么累...)...找了本网络编程翻了翻当做打一个小基础吧,打算一边继续学习数据结构一边也看看网络编程相关的... 简单的第一次尝试,就大致梳理一下看书+自 ...

  7. 01背包第k最优解

    附题目链接:Bone Collector II Input The first line contain a integer T , the number of cases.Followed by T ...

  8. OpenTSDB 写入数据

    1. 关于 Metrics, value, tag name, tag value opentsdb的每个时间序列必须有一个metric和一个或多个tag对,每个时间序列每小时的数据保存一行.open ...

  9. linux mysql 查看数据库大小

    SELECT CONCAT(TRUNCATE(SUM(data_length)//,),'MB') AS data_size, CONCAT(TRUNCATE(SUM(max_data_length) ...

  10. python去除字符串中的特殊字符(爬虫存储数据时会遇到不能作为文件名的字符串)

    问题描述 今天在写爬虫爬取影评时,本来的思路把影评的标题作为文件名,将每个影评的详情内容写入到"标题.txt"文件中,直到我遇到了这个问题: 这时我突然意识到,文件名中有些字符是不 ...