设备树及其操作
设备树驱动
设备树
设备树将是设备文件,后缀.dts。其用于描述板级设备,开发板的设备信息。(CPU数量,内存基地址,IIC控制器,SPI控制器)。设备树文件在linux内核文件中。
设备树文件格式
设备树源文件扩展名后缀.dts。设备树二进制文件后缀为.dtb。将dts编译为dtb文件,使用的工具是dtc。
只编译设备树文件指令make dtbs。
设备树文件路径,一般放置在arch/arm/boot/dts/Makefile
dts源文件格式
设备树支持头文件,设备树头文件扩展名后缀.dtsi。具体格式:
图 2 设备树文件格式
设备节点
图 3 设备树文件节点
“/”是根节点,是设备树首节点。而节点是具有追加效果的(dtsi文件中也有“/”根节点)。
节点格式:
node-name@unit-address
node-name是设备节点的名字,一般是字符串表示。
unit-address是设备的地址信息,一般是设备地址或寄存器首地址。如果节点没有地址或寄存器,unit-address可以没有。gpio_keys:gpio_keys@0
使用:将gpio_keys:gpio_keys@0隔开。其中冒号前面的是别名(label)。
设备树源代码包含的数据格式:
字符串,32位无符号数,字符串数组
标准属性
Compatible属性:兼容属性,通过该属性将驱动与设备匹配。
Model属性值是字符串,一般描述设备模块信息。
Status:描述和设备状态有关。Status一般如下:“okay”,“disabled”,“fail”“fail-sss”。
#address-cells与#size-cells,属性值是32位整形。在任何子节点的设备包含在#address-cells与#size-cells。Address-cells属性值表示reg地址信息所占用的字长(32位)。Size-cells属性值表示reg属性长度信息所占字长(32位)。
格式:reg = <address1 length1 address2 length2 address3 length3……>
Reg属性:reg属性值一般是(address,length)。其属性一般用于描述设备地址空间资源与地址范围信息。
Ranges:这个属性值可以为空。也可以有内容:
(child-bus-address,parent-bus-address,length)
child-bus-address:子总线地址空间物理地址,其一般由父节点#address-cells
parent-bus-address: 父总线地址空间的物理地址,其一般由父节点#address-cells
length: 子地址空间的长度,由父节点的#size-cells 确定此地址长度所占用的字长。
根节点的compatible属性
使用该属性值完成Linux内核中的驱动程序匹配。
设备树在系统体现
在根文件系统/proc/device-tree目录下,可以查看到设备树对应的节点信息与内容。
设备树节点操作OF函数
节点查找
struct device_node *of_find_node_by_name(struct device_node *from,const char *name);
from:从哪个节点开始找,NULL表示从根节点开始。
Name:查找节点的名字。
struct device_node *of_find_node_by_type(struct device_node *from, const char *type)
type:要查找的节点对应的 type 字符串,也就是 device_type 属性值
struct device_node *of_find_compatible_node(struct device_node *from,const char *type,const char *compatible)
compatible: 要查找的节点所对应的 compatible 属性列表。(常用)
inline struct device_node *of_find_node_by_path(const char *path)
path:带有全路径的节点名,可以使用节点的别名,比如“/backlight”就是 backlight 这个节点的全路径。
父子节点
struct device_node *of_get_parent(const struct device_node *node)
node:要查找的父节点的节点。
struct device_node *of_get_next_child(const struct device_node *node,struct device_node *prev)
node:父节点。
prev:前一个子节点,也就是从哪一个子节点开始迭代的查找下一个子节点。可以设置为
NULL,表示从第一个子节点开始。
属性值获取
property *of_find_property(const struct device_node *np,const char *name,int *lenp)
np:设备节点。
name: 属性名字。
lenp:属性值的字节数
返回值: 找到的属性。
int of_n_addr_cells(struct device_node *np)
函数参数和返回值含义如下:
np:设备节点。
返回值: 获取到的#address-cells 属性值。
int of_n_size_cells(struct device_node *np)
函数参数和返回值含义如下:
np:设备节点。
返回值: 获取到的#size-cells 属性值