活动地址:CSDN21天学习挑战赛

【Linux驱动开发】设备树详解(一)设备树基础介绍
【Linux驱动开发】设备树详解(二)设备树语法详解
【Linux驱动开发】设备树详解(三)设备树Kernel解析

个人主页:董哥聊技术 我是董哥,嵌入式领域新星创作者 创作理念:专注分享高质量嵌入式文章,让大家读有所得!

文章目录

  • 4、设备树语法
    • 4.1 数据格式
    • 4.2 数据结构
    • 4.3 属性介绍
      • 4.3.1 基本属性之compatible、name、unit-address
      • 4.3.2 寻址属性之address-cells、size-cells、reg、range
      • 4.3.3 中断属性之interrupt-controller、interrupt-cells、interrupt-parent、interrupts
      • 4.3.4 其他属性之aliases、chosen

4、设备树语法

dts文件是一种ASCII文本格式的设备树描述,它有以下几种特性:

  • 每个设备树文件都有一个根节点,每个设备都是一个节点。

  • 节点间可以嵌套,形成父子关系,这样就可以方便的描述设备间的关系。

  • 每个设备的属性都用一组key-value对(键值对)来描述。

  • 每个属性的描述用;结束

记住上面的几个核心特性,往下看!

4.1 数据格式

/dts-v1/;/ {node1 {a-string-property = "A string";a-string-list-property = "first string", "second string";// hex is implied in byte arrays. no '0x' prefix is requireda-byte-data-property = [01 23 34 56];child-node1 {first-child-property;second-child-property = <1>;a-string-property = "Hello, world";};child-node2 {};};node2 {an-empty-property;a-cell-property = <1 2 3 4>; /* each number (cell) is a uint32 */child-node1 {};};
};
  • /:表示根节点
  • node1node2:表示根节点下的两个子节点
  • child-node1child-node2:表示子节点node1下的两个子节点
  • a-string-property = "A string";:字符串属性,用双引号表示
  • cell-property = <0xbeef 123 0xabcd1234>;:32bit的无符号整数,用尖括号表示
  • binary-property = [0x01 0x23 0x45 0x67];:二进制数据用方括号表示
  • a-string-list-property = "first string", "second string";:用逗号表示字符串列表

4.2 数据结构

DeviceTree的结构非常简单,由两种元素组成:Node(节点)和Property(属性)。

[label:] node-name[@unit-address] {[properties definitions][child nodes]
}

想象一下,一棵大树,每一个树干都认为是一个节点,每一片树叶,想作一个属性!

  • label:节点的一个标签,可以作为别名
  • node-name:节点的名称
  • unit-address:单元地址,也就是控制器的地址
  • properties:属性名称
  • definitions:属性的值

4.3 属性介绍

/dts-v1/;/ {compatible = "acme,coyotes-revenge";#address-cells = <1>;#size-cells = <0>;cpus {cpu@0 {compatible = "arm,cortex-a9";reg = <0>;};cpu@1 {compatible = "arm,cortex-a9";reg = <1>;};};serial@101f0000 {#address-cells = <1>;#size-cells = <1>;compatible = "arm,pl011";reg = <0x101f0000 0x1000 >;};};

4.3.1 基本属性之compatible、name、unit-address

下面几个属性是基本属性

  • /dts-v1/;:表示一个dts设备树文件
  • /:表示根节点
  • compatible = "acme,coyotes-revenge";
    • compatible: “兼容性” 属性,这是非常重要的一个属性兼容属性,由该属性值来匹配对应的驱动代码。
    • "acme,coyotes-revenge":该值遵循"manufacturer,model"格式manufacturer表示芯片厂商,model表示驱动名称

compatible是一个字符串列表。列表中的第一个字符串指定节点在表单中表示的确切设备"<manufacturer>,<model>"

例如,飞思卡尔 MPC8349 片上系统 (SoC) 有一个串行设备,可实现 National Semiconductor ns16550 寄存器接口。因此,MPC8349 串行设备的 compatible 属性应为:compatible = "fsl,mpc8349-uart", "ns16550". 在这种情况下,fsl,mpc8349-uart指定确切的设备,并ns16550声明它与 National Semiconductor 16550 UART 的寄存器级兼容。

  • cpus:表示一个子节点,该子节点下又有两个子节点,分别为cpu0cpu1
  • cpu@0:遵循<name>[@<unit-address>]格式
    • <name>:ascii字符串,表示节点名称
    • <unit-address>:单元地址,设备的私有地址,在节点reg属性中描述。

4.3.2 寻址属性之address-cells、size-cells、reg、range

下面几个属性与寻址相关的

  • #address-cells :表示reg属性中表示地址字段的单元个数,每个单元32bit,即用多少个32bit单元表示地址信息。

  • #size-cells:表示reg属性中表示长度字段的单元个数,每个单元32bit,即用多少个32bit单元表示长度信息。

  • reg:该属性一般用于描述设备地址空间资源信息,一般都是某个外设的寄存器地址范围信息。其式为reg = <address1 length1 [address2 length2] [address3 length3] ... >。每个地址值都是一个或多个 32 位整数的列表,称为单元格。同样,长度值可以是单元格列表,也可以是空的。

cpu节点为例

    cpu@0 {compatible = "arm,cortex-a9";reg = <0>;};

#address-cells=1表示reg属性中描述地址字段,所需32bit的单元个数为1,#size-cells=0表示reg属性中没有表示长度的单元,即reg=<0>

再以serial节点为例

    serial@101f0000 {#address-cells = <1>;#size-cells = <1>;compatible = "arm,pl011";reg = <0x101f0000 0x1000 >;};

该设备都被分配一个基址,以及被分配区域的大小

#address-cells=1表示reg属性中描述地址字段需要1个32bit单元,#size-cells=1表示reg属性中描述长度字段需要2个单元,即reg=<0x101f0000 0x1000>

  • 0x101f0000:表示serial的控制器起始地址
  • 0x1000:表示serial控制器所占用的大小

地址映射部分还要了解一个属性<range>,为什么要引入这个属性呢

根节点与根节点的直接子节点,都使用了CPU的地址分配空间,但是根节点的非直接子节点,并不会自动实用CPU的地址空间,因此需要手动用<range>属性分配。

如上述的serial节点,属于根节点下的直接子节点,无需手动再次分配地址空间,而下面所述的 external-bus节点,其内部的子节点就需要再次分配!

/dts-v1/;/ {compatible = "acme,coyotes-revenge";#address-cells = <1>;#size-cells = <1>;...external-bus {#address-cells = <2>;#size-cells = <1>;ranges = <0 0  0x10100000   0x10000     // Chipselect 1, Ethernet1 0  0x10160000   0x10000     // Chipselect 2, i2c controller2 0  0x30000000   0x1000000>; // Chipselect 3, NOR Flashethernet@0,0 {compatible = "smc,smc91c111";reg = <0 0 0x1000>;};i2c@1,0 {compatible = "acme,a1234-i2c-bus";#address-cells = <1>;#size-cells = <0>;reg = <1 0 0x1000>;rtc@58 {compatible = "maxim,ds1338";reg = <58>;};};flash@2,0 {compatible = "samsung,k8f1315ebm", "cfi-flash";reg = <2 0 0x4000000>;};};
};

该总线使用了不同的寻址方式,分析一下external-bus节点

  • #address-cells = <2>:用两个单元表示地址
  • #size-cells = <1>:用一个单元表示长度
  • reg = <0 0 0x1000>:第一个0表示片选号,第二个0表示基于片选的偏移,第三个表示偏移的大小

这种抽象的表示,如何映射到CPU地址区域呢?```属性来帮助!

   ranges = <0 0  0x10100000   0x10000     // Chipselect 1, Ethernet1 0  0x10160000   0x10000     // Chipselect 2, i2c controller2 0  0x30000000   0x1000000>; // Chipselect 3, NOR Flash

range:表示了不同设备的地址空间范围,表中的每一项都是一个元组,包含子地址、父地址以及子地址空间中区域的大小,这三个字段。

  • 子地址字段:由子节点的#address-cells决定,如前面的0 00 1
  • 父地址字段:由父节点的#address-cells决定,如0x101000000x10160000
  • 子地址空间字段:描述子节点的空间大小,由父节点的#size-cells决定,如0x100000x10000

经过映射后,总线的地址映射如下:

  • Offset 0 from chip select 0 is mapped to address range 0x10100000…0x1010ffff
  • Offset 0 from chip select 1 is mapped to address range 0x10160000…0x1016ffff
  • Offset 0 from chip select 2 is mapped to address range 0x30000000…0x30ffffff

4.3.3 中断属性之interrupt-controller、interrupt-cells、interrupt-parent、interrupts

/dts-v1/;/ {compatible = "acme,coyotes-revenge";#address-cells = <1>;#size-cells = <1>;interrupt-parent = <&intc>;cpus {#address-cells = <1>;#size-cells = <0>;cpu@0 {compatible = "arm,cortex-a9";reg = <0>;};cpu@1 {compatible = "arm,cortex-a9";reg = <1>;};};serial@101f0000 {compatible = "arm,pl011";reg = <0x101f0000 0x1000 >;interrupts = < 1 0 >;};intc: interrupt-controller@10140000 {compatible = "arm,pl190";reg = <0x10140000 0x1000 >;interrupt-controller;#interrupt-cells = <2>;};
};

如上

  • interrupt-controller:声明一个节点是接收中断信号的设备,也就是中断控制器
  • #interrupt-cellsinterrupt-controller节点下的一个属性,表明中断标识符用多少个单元表示
  • interrupt-parent:设备节点中的一个属性,选择哪个中断控制器
  • interrupts:设备节点的一个属性,中断标识符列表,其单元个数取决于#interrupt-cells

根据设备树,我们了解到:

  • 该机器有一个中断控制器interrupt-controller@10140000
  • intc标签,为中断控制器的别名,方便引用
  • #interrupt-cells = <2>;:中断标识符用两个单元格表示
  • interrupt-parent = <&intc>;:选择中断控制器
  • interrupts = < 1 0 >;:表示一个中断,第一个值用于表明中断线编号,第二个值表明中断类型,如高电平,低电平,跳变沿等

4.3.4 其他属性之aliases、chosen

    aliases {ethernet0 = &eth0;serial0 = &serial0;};

aliases:正如其名,别名属性,使用方式:property = &label;

    chosen {bootargs = "root=/dev/nfs rw nfsroot=192.168.1.1 console=ttyS0,115200";};

chosen:该属性并不表示一个真实的设备,但是提供一个空间,用于传输固件和Linux之间的数据,像启动参数,

【Linux驱动开发】设备树详解(二)设备树语法详解相关推荐

  1. linux驱动开发篇(三)—— 总线设备驱动模型

    linux系列目录: linux基础篇(一)--GCC和Makefile编译过程 linux基础篇(二)--静态和动态链接 ARM裸机篇(一)--i.MX6ULL介绍 ARM裸机篇(二)--i.MX6 ...

  2. Linux 驱动开发 四十四:platform 设备驱动实验(二)

    驱动测试通过操作 led 完成. 一.原理图 二.无设备树源码实现 无设备树时候通过 platform_device.name 和 platform_driver.driver.name 进行匹配. ...

  3. Linux驱动开发(一):字符设备

    目的:实现最简单的点灯操作. Linux一切皆文件,应用程序访问某个物理设备(文件)时,首先通过open, read, write等库函数调用系统调用接口(System call interface) ...

  4. “手把手教你学linux驱动开发”OK6410系列之03---LED字符设备驱动

    上一篇文章我们介绍了字符设备驱动程序的框架,本篇文章我们将操作真实的硬件---LED. 作者:沧海猎人   出处:http://blog.csdn.net/embedded_hunter  转载请注明 ...

  5. linux驱动开发篇(四)—— platform平台设备驱动

    linux系列目录: linux基础篇(一)--GCC和Makefile编译过程 linux基础篇(二)--静态和动态链接 ARM裸机篇(一)--i.MX6ULL介绍 ARM裸机篇(二)--i.MX6 ...

  6. 【正点原子MP157连载】第二十章 字符设备驱动开发-摘自【正点原子】STM32MP1嵌入式Linux驱动开发指南V1.7

    1)实验平台:正点原子STM32MP157开发板 2)购买链接:https://item.taobao.com/item.htm?&id=629270721801 3)全套实验源码+手册+视频 ...

  7. Linux驱动开发(十八)---网络(网卡)驱动学习

    前文回顾 <Linux驱动开发(一)-环境搭建与hello world> <Linux驱动开发(二)-驱动与设备的分离设计> <Linux驱动开发(三)-设备树> ...

  8. Linux驱动开发(外传)---驱动开发调试方法

    前文回顾 <Linux驱动开发(一)-环境搭建与hello world> <Linux驱动开发(二)-驱动与设备的分离设计> <Linux驱动开发(三)-设备树> ...

  9. Linux驱动开发(十五)---如何使用内核现有驱动(显示屏)

    前文回顾 <Linux驱动开发(一)-环境搭建与hello world> <Linux驱动开发(二)-驱动与设备的分离设计> <Linux驱动开发(三)-设备树> ...

  10. Linux驱动开发(十)---树莓派输入子系统学习(红外接收)

    前文回顾 <Linux驱动开发(一)-环境搭建与hello world> <Linux驱动开发(二)-驱动与设备的分离设计> <Linux驱动开发(三)-设备树> ...

最新文章

  1. novaclient的api调用流程与开发
  2. 磁盘占用百分百?Windows 10必做各项优化
  3. Chapter 1 First Sight——17
  4. mysql报错01427_ORA-01427问题的分析和解决
  5. 【java笔记】模拟B/S服务器
  6. mysql并行复制功能
  7. new对象后的代码块(匿名类)
  8. sql盲注 解决_sql盲注解决方案.docx
  9. excel合并工作簿怎么做?
  10. 运动蓝牙耳机挑选要注意什么?蓝牙耳机知识科普
  11. 官方正版授权Apowersoft 傲软抠图AI智能换背景工具软件
  12. 怎么在电脑端下载和编辑哔哩哔哩的视频
  13. 传感器模组:手机摄像头模组-1亿像素是如何实现的?
  14. 升级打怪小游戏(面向对象)
  15. 【Python入门基础】Web前端
  16. 电子计算机的元器件发展过程,电子元器件及发展历程及未来趋势.doc
  17. Cilantro 点云处理库
  18. HTML+CSS大作业——仿团购商城(1页) 简单个人网页设计作业 静态HTML旅行主题网页作业 DW个人网站模板下载 大学生简单个人网页作品代码 个人网页制作 学生个人网页Dreamwe
  19. ASO优化之新应用该如何推广
  20. 浅谈一类积性函数的前缀和(转载)

热门文章

  1. 怎么看守望先锋服务器位置,守望先锋手机怎么查战绩_守望先锋国服战绩在哪看_玩游戏网...
  2. mysql流式计算,Stream流式计算
  3. C语言运算符优先级 之 快速记忆6,[快速记忆]C语言/php的运算符优先级(结合性)...
  4. javaweb 三大组件之Severlet
  5. 限时福利!技术大牛给你送书了
  6. 3C数字钥匙技术规范解读
  7. 又一款知名云盘服务翻车:“免费不限量”变收费,用户被骗5年
  8. JAVA代码学习之芋道源码
  9. markdown 合并单元格
  10. maven依赖本地jar包