设备树的概念

1.问:设备树是什么东东?
答:它是一个文件,这个文件描述的是设备的信息

2.问:为什么要引入设备树?
答:因为设备的信息是针对于特定平台的,如果我们在Linux内核中包含太多设备信息,
则Linux内核移植性就会变差。引入设备树之后,设备的信息的描述不在是以代码的形式存在于
Linux内核源代码中,这种做法实际上是将设备的信息,从Linux 内核中独立出来,
单独描述(用设备树语法规则来描述设备的信息)。

3.问:设备的信息是以设备树的形式呈现,那么Linux操作系统是如何识别设备的呢?
答:Linux内核在启动的时候,要求把设备树文件传递给它。它拿到设备树之后,会解析设备树文件,
从而识别设备信息。


3.x Linux 内核platform总线上设备与驱动的匹配规则
<1>设备树中的compatible属性与驱动中指定的of_match_table中的compatible进行匹配
如果没有匹配成功:
<2>如果驱动中有id_table,则拿id_table中记录的名字与设备的名字匹配
如果驱动中没有id_table,则拿驱动的名字与设备的名字匹配

节点名称@reg属性的第一个地址值{
#address-cells = <1>;
#size-cells = <1>; //规定它的子节点reg属性写法
compatible = “名字”;//和驱动匹配 (必须)
reg = <寄存器的起始地址 地址的长度>;
---------------------------------------------------------------------------------------------------
设备名-gpios = <&gpio控制器的标签名 管脚编号 标志>; //gpio信息 (驱动需要操作GPIO输出高低电平)
---------------------------------------------------------------------------------------------------
interrupt-parent = <&中断控制器的标签名>;//gpio gic combiner(exynos4412)
interrupts = <1个或多个uint32的数字描述中断的信息>;// #interrupt-cells
interrupt-names = “名称”;
----------------------------------------------------------------------------------------------------
clocks = <&clock 时钟信号的ID>; clk_get , clk_enable ,clk_disable
clock-names = “名字”;
----------------------------------------------------------------------------------------------------
pinctrl-0 = <&描述gpio管脚功能的标签 &描述gpio管脚功能的标签>;//系统自动帮助我们设定为指定的功能模式
pinctrl-1 = <&描述gpio管脚功能的标签 &描述gpio管脚功能的标签>;
pinctrl-names = “default”,“other(随便)”;(第一个名字对应pinctrl-0,第二个对应pinctrl-1)

	struct pinctrl * devm_pinctrl_get_select(struct device *dev, const char *name);
	-----------------------------------------------------------------------------------------------------
	自己定义的属性    = "值";
	-----------------------------------------------------------------------------------------------------
	status            = "状态";//okay , disabled

};

*--------------------------------------------------------------------------------------------------------------
*属性(描述设备的信息)是最简单的键-值对,它的值可以为空或者是一个有效的数据,基本的数据类型如下
*(1)属性后面的值可以是一个字符串,如:

  • a string-propery = “a string”

*(2)属性后面的值可以是多个32位的无符号整数,用尖括号限定

  • cell-propery = <0xbeef 123 0xabcd1234>

*(3)属性后面的值可以多个二进制数据,用方括号限定

  • binary-propery = [0x01 0x23 0x45 0x67]
  • 注意:写的时候用十六进制来表示二进制

*(4)属性后面的值可以是多个不同形式的数据组合在一起,他们之间用逗号隔开

  • mixed-propery = “a string”,[0x01 0x23 0x45 0x67],<0x12345678>

*(5)属性后面的值可以多个字符传,他们之间用逗号隔开

  • string-list = “red fish”,“blue fish”;
    *---------------------------------------------------------------------------------------------------------------

注意:
属性名可以任意,但是赋值的时候需要遵从设备树的语法原则,
通用的属性内核是自动解析的,自己的属性需要使用内核提供的设备树函数接口(linux/of.h)自己解析

必须知道的知识:
<1>这个节点Linux内核最终会对它进行解析,解析完成之后是一个结构体:
struct device_node 这个结构体中包含的就是这个节点的所有信息
(struct platform_device 它有记录)

<2>Linux内核在解析这个节点的时候,会根据节点的状态,判定是否添加到platform bus总线上。
如果是添加到platform bus总线上,就会构建一个platform_device结构体,并且会去匹配驱动
此时reg属性就会解析成IORESOURCE_MEM platform_get_resource
此时interrupts属性就会解析成IORESOURCE_IRQ

练习:
(1)描述LED2这个设备
led2@11000C40{
compatible = “fs4412-led”;
reg = <0x11000C40 8>;
------------------------------------------------
pin = <7>;
level = <1>;
mode = <1>;
------------------------------------------------
status = “okay”;
};

如果一个模块包括多个.c文件(如file1.c,file2.c),则应该以如下方式编写Makefile:
obj-m = modulename.o
modulename-objs := file1.o file2.o

(2)描述KEY2这个设备(描述中断信息)
key2{
compatible = “fs4412-key”;
interrupt-parent = <&gpx1>;
interrupts = <1 8>;
intrrupt-names = “key-interrupt”;
};

(3)描述ADC这个设备 (reg ,interrupt , clock)
adc@126C0000{
compatible = “exynos4412-adc”;
reg = <0x126C0000 0x20>;
interrupt-parent = <&combiner>;
interrupts = <10 3>;
intrrupt-names = “adc-interrupt”;
clocks = <&clock 326>;
clock-names = “adc-clock”;
status = “okay”
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值