linux设备树学习笔记

文章目录

  • 一、什么是设备树
  • 二、设备树源码格式
  • 三、如何找到对应的驱动
  • 四、驱动和设备的关系
  • 五、追加说明

一、什么是设备树

1、dts:device tree source 设备树源码
硬件的相应信息都会写在.dts为后缀的文件中,每一款硬件可以单独写一xxxx.dts,一般在Linux源码中存在大量的dts文件,对于arm架构可以在arch/arm/boot/dts找到相应的dts,一个dts文件对应一个ARM的machie。
2、dtsi:类似于dts。是dts的头文件,dts中的配置会覆盖dtsi中的配置。非必要的我们一般不去改这个,这是一种板子的通用文件。dts就是细分一种板子的几个版本这种。
3、dtc是编译dts的工具,可以在Ubuntu系统上通过指令apt-get install device-tree-compiler安装dtc工具,不过在内核源码scripts/dtc路径下已经包含了dtc工具。直接用就可以。
4、dtb(Device Tree Blob),dts经过dtc编译之后会得到dtb文件,dtb通过Bootloader引导程序加载到内核。所以Bootloader需要支持设备树才行;Kernel也需要加入设备树的支持;

linux设备树学习笔记_第1张图片

二、设备树源码格式

dts一般放在,kernel/arh/arm*/boot/dts/xxxx/里面(xxx是你自己板子的牌子那种,比如瑞芯微就是rockchip),在这里面有很多的dts文件和dtsi文件。我们需要找到自己对应的板子的dts和dtsi文件。
找到过后我们就能看到很多源码。
我们打开一个看看

/*第一个pdm_mic_array,是他的别名,第二个pdm-mic-array是他的真名,有时真名比较长,所以会采用别名方便调用
 *比如:vcc_camera: vcc-camera-regulator {}
 */
pdm_mic_array: pdm-mic-array {
	/*状态,打开或者关闭*/
		status = "disabled";
	/*属性,可以理解设备注册的名字,需要和驱动注册的名字对应*/
		compatible = "simple-audio-card";
	/*也是他的属性,瑞芯微的,设备名字是pdm-mic-array*/
		simple-audio-card,name = "rockchip,pdm-mic-array";
		/*这两个都是声卡连接cpu的编解码器*/
		simple-audio-card,cpu {
			sound-dai = <&pdm>;
		};
		simple-audio-card,codec {
			sound-dai = <&pdmics>;
		};
	};

还有这样的

/*子节点名称*/
wd_tpl5010 {
		compatible = "wd-tpl5010";
		/*这个好像都是default,应该是pinctrl子系统里面的东西*/
		pinctrl-names = "default";
		/*用pinctrl子系统去控制这个gpiod的模式(类似于浮空、上拉、下拉这种)*/
		pinctrl-0 = <&gpio4_b6>;
		/*配置gpio的状态*/
		tpl-wake = <&gpio0 RK_PA5 GPIO_ACTIVE_LOW>;	
		tpl-done = <&gpio3 RK_PC5 GPIO_ACTIVE_HIGH>;	
	};

在dts文件的上端,一般会有一个这个代码,这不是注释,这是dts的版本那种

/dts-v1/;

/ 表示这是根节点,仔细看看源码,根结点都是顶行写的,而根节点的下面的节点会用一个TAB来表示,同样的下面的节点也会继续TAB,这样用tab就可以看出各个节点的关系了。

/{
	child1{
		child2{
			child3{
				.......
			};
		};
	};
};

三、如何找到对应的驱动

zwave_ctl {
		/* qls_cnt_zwave 这个就是你去匹配对应驱动代码的*/
		compatible = "Pine,qls_cnt_zwave";
		gpios = <&gpio3 RK_PB6 GPIO_ACTIVE_HIGH>;	
		pinctrl-names = "default";
		pinctrl-0 = <&gpio3_b6>;		
	};

用sourceinsight的可以直接搜索
我用的vim,因为ubuntu用sourceinsight很难受

drivers/misc/tab07_rk68_qls_cnt_zware.c:33:struct qls_cnt_zwave_drvdata {
drivers/misc/tab07_rk68_qls_cnt_zware.c:39:static const struct of_device_id qls_cnt_zwave_match[] = {
drivers/misc/tab07_rk68_qls_cnt_zware.c:40:	{ .compatible = "Pine,qls_cnt_zwave", .data = NULL},
drivers/misc/tab07_rk68_qls_cnt_zware.c:43:MODULE_DEVICE_TABLE(of, qls_cnt_zwave_match);
..........

我们马上就在驱动里面找到相关代码,打开他(你打开的不一定正确,所以有时需要多次打开)
果然我们就在里面找到了对应的代码


static struct platform_driver pine_qls_cnt_zwave_driver = {
		/*驱动的注册,注销、名字*/
        .probe          = qls_cnt_zwave_probe,
        .remove         = qls_cnt_zwave_remove,
        .driver         = {
                .name   = "qls_cnt_zwave",
                .owner  = THIS_MODULE,
                /*匹配函数,去匹配设备和驱动的代码*/
                .of_match_table = qls_cnt_zwave_match,
#ifdef CONFIG_PM
                .pm     = &qls_cnt_zwave_pm_ops,
#endif

同样的方法,我们可以找到相关的驱动和dts的关系。
阅读驱动的代码建议从下往上看,因为驱动的代码重要的东西都是放在下面的。

四、驱动和设备的关系

可以想象一条总线上有两个链表,一个是设备链表,一个是驱动链表。每一个节点就是自己的设备或者驱动的名字,match函数就是遍历链表,然后把两个链表的节点名字用来作比对,如果对上了,那么就证明我们的设备是有驱动的,如果没有对上,那么就证明我们的设备是没有驱动的,取要去写驱动。
每一个设备都有一个驱动,不然设备没法工作,但是不是每一驱动都有设备。设备可以少,但是驱动不能少。

五、追加说明

在dts里面我们会看到这样的一种代码

&dfi {
	status = "disabled";
	........
};

这种一个取地址符加上一个名字这种,这是追加说明,是因为dts不止用在一个开发板上,那么对应的驱动或者总线就会有不同的需求,有的要,有的不要,为了不去找之前是什么状态,我们直接追加一个我们需要的属性就好,可以追加状态开或者关,也可以追加子节点,类似下面的代码。

&i2c0 {
	status = "okay";

	vdd_cpu: tcs4525@1c {
		compatible = "tcs,tcs452x";
		reg = <0x1c>;
		vin-supply = <&vcc5v0_sys>;
		regulator-compatible = "fan53555-reg";
		regulator-name = "vdd_cpu";
		regulator-min-microvolt = <712500>;
		regulator-max-microvolt = <1390000>;
		regulator-init-microvolt = <900000>;
		regulator-ramp-delay = <2300>;
		fcs,suspend-voltage-selector = <1>;
		regulator-boot-on;
		regulator-always-on;
		regulator-state-mem {
			regulator-off-in-suspend;
		};
	};

	rk809: pmic@20 {
		compatible = "rockchip,rk809";
		reg = <0x20>;
		interrupt-parent = <&gpio0>;
		interrupts = <3 IRQ_TYPE_LEVEL_LOW>;
		....
		...
	};
};

你可能感兴趣的:(linux,linux驱动学习(兼容安卓),linux,运维,服务器)