Linux 设备树dts介绍

一  概述

    在写驱动的过程中,有很大一部分工作是在对设备信息进行管理,随着芯片种类的增加,这种管理工作变得越来越复杂。目前写驱动主要有三种方式:

1、跟写单片机裸机驱动一样,直接把驱动和硬件信息写在一起。这种方式的优点是程序简单,缺点很明显,就是每当硬件信息改动的时候,比如简单的更换一下IO引脚,都需要去修改源文件的大部分内容,因此扩展性不强。

2、使用总线-设备-驱动模型。这种模式使用上下分层,左右分离的思想,把设备和驱动分离,然后挂在一根总线上,使用一定的机制进行匹配。这种方式相对与第一种,扩展性更强,当需要改动硬件信息时,只需要改动device相关代码就好,而driver相关代码则是纯软件概念,不需要动,但是他仍然不够好,想象一下每个设备对应一个device文件,当有成千上万个设备时,岂不是会产生大量的冗余代码,而且每次改动硬件信息都需要重新编译驱动,导致效率不高,于是有了第三种方式。

3、使用设备树管理。这种方式沿用总线-设备-驱动模型,与第二种方式不同的是,我们把硬件信息单独抽出来,使用一定的格式组织起来,这就是设备树文件(dts),使用时它会被编译成dtb文件,被内核解析。这样的方式减少了代码的冗余度,提高了效率,下面一步一步地了解dts文件是怎样使用起来的。

二  dts文件格式

    既然是一棵树,就要有根和节点,下面通过一个实际的例子来看下这些东西是怎么定义的。一个完整的设备树文件摘选部分如下:

/dts-v1/;

/* First 4KB has pen for secondary cores. */
/memreserve/ 0x00000000 0x0001000;

/ {
	model = "Calxeda Highbank";
	compatible = "calxeda,highbank";
	#address-cells = <1>
	#size-cells = <1>

	cpus {
		#address-cells = <1>
		#size-cells = <0>

		cpu@0 {
			compatible = "arm,cortex-a9";
			reg = <0>
			next-level-cache = <&L2>
		};

		cpu@1 {
			compatible = "arm,cortex-a9";
			reg = <1>
			next-level-cache = <&L2>
		};
	};

	memory {
		name = "memory";
		device_type = "memory";
		reg = <0x00000000 0xff900000>
	};

	chosen {
		bootargs = "console=ttyAMA0";
	};

	soc {
		#address-cells = <1>
		#size-cells = <1>
		compatible = "simple-bus";
		interrupt-parent = <&intc>
		ranges;

		timer@fff10600 {
			compatible = "arm,cortex-a9-twd-timer";
			reg = <0xfff10600 0x20>
			interrupts = <1 13 0xf01>
		};

		watchdog@fff10620 {
			compatible = "arm,cortex-a9-twd-wdt";
			reg = <0xfff10620 0x20>
			interrupts = <1 14 0xf01>
		};

		intc: interrupt-controller@fff11000 {
			compatible = "arm,cortex-a9-gic";
			#interrupt-cells = <3>
			#size-cells = <0>
			#address-cells = <1>
			interrupt-controller;
			reg = <0xfff11000 0x1000>,
			      <0xfff10100 0x100>
		};

		gpioe: gpio@fff30000 {
			#gpio-cells = <2>
			compatible = "arm,pl061", "arm,primecell";
			gpio-controller;
			reg = <0xfff30000 0x1000>
			interrupts = <0 14 4>
		};
		......
	};
};

从上面可以看出,dts文件的布局是这样的:

/dts-v1/;  // 表示设备树文件的版本号
[memory reservations] //表示保留的内存大小,就是说我想保留多少内存给自己用,不给内核使用
格式为: /memreserve/ <address> <length>
/ {                   // "/" 表示根  
    [property definitions]   // 属性定义
    [child nodes]            // 子节点定义
};

子节点的格式为:

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

首先[label:],如上面的这个节点:

gpioe: gpio@fff30000 {
			#gpio-cells = <2>
			compatible = "arm,pl061", "arm,primecell";
			gpio-controller;
			reg = <0xfff30000 0x1000>
			interrupts = <0 14 4>
		};
  • 4
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值