设备树文件位置:
Linux内核/arch/arm/boot/dts/XXX.dts
编译设备树:
在 “Linux内核” 此目录下 make dtbs
内核启动后在如下位置生成同名的节点文件夹
/proc/device-tree/XXX@0x12345678
————————————————————————————————————
设备树编写的内核帮助文档:Linux内核/Documentation/devicetree/bindings
————————————————————————————————————
节点被内核解析后会创建一个对应的device_node结构体
struct device_node {
const char *name; //节点名称
const char *type; //节点类型
phandle phandle; //节点句柄,用于节点引用
const char *full_name; //节点全名
struct fwnode_handle fwnode;
struct property *properties; //一个结构体记录本节点的一个属性,链表存储
struct property *deadprops;
struct device_node *parent; //父节点
struct device_node *child; //第一个子节点
struct device_node *sibling; //第一个兄弟节点
struct kobject kobj; //节点kobj对象
unsigned long _flags; //节点标识
void *data; //节点特殊数据
#if defined(CONFIG_SPARC)
const char *path_component_name;
unsigned int unique_id;
struct of_irq_controller *irq_trans;
#endif
};
其中struct property结构体记录着本节点的属性,一个结构体记录一个属性
struct property {
char *name; //键
int length; //值的长度
void *value; //值
struct property *next; //指向下一个键值对
unsigned long _flags;
unsigned int unique_id;
struct bin_attribute attr;
};
驱动中获得节点结构体device_node的函数
1.通过路径获得节点结构体
struct device_node *of_find_node_by_path(const char *path)
path:在设备树中节点的绝对路径
返回值:成功=节点结构体首地址,失败=NULL
2.通过节点名获得节点结构体
struct device_node *of_find_node_by_name(struct device_node *from,const char *name)
from:开始查找节点的起始位置,NULL=从根节点开始
name:节点名
返回值:成功=节点结构体首地址,失败=NULL
3.通过compatible属性获得节点结构体
struct device_node *of_find_compatible_node(struct device_node *from, const char *type, const char *compatible)
from:开始查找节点的起始位置,NULL=从根节点开始
type:节点的type属性对应的值,NULL=忽略
compatible:节点compatible属性对应的值
返回值:成功=节点结构体首地址,失败=NULL
4.通过父节点获得子节点结构体
struct device_node *of_get_child_by_name(const struct device_node *node,const char *name)
node:父节点的结构体指针
name:子节点名字
返回值:成功=节点结构体首地址,失败=NULL
驱动中从节点结构体中获取键值的函数
1.通过键的名字找到对应的struct propetry结构体从而获得值
struct property *of_find_property(const struct device_node *np,const char *name,int *lenp)
np:节点的指针
name:键(属性)的名字
lenp:键值的字节数
返回值:成功=struct property结构体指针,失败=NULL
2.通过键的名字在节点结构体中获得值(忽略)
实则调用了of_find_property,只是省了一步,到property结构体中赋值而已
const void *of_get_property(const struct device_node *np, const char *name,int *lenp)
np:节点的指针
name:键(属性)的名字
lenp:键值的字节数
返回值:成功=键值,失败=NULL
3.获取一个u32类型的数 <>括号里的
int of_property_read_u32_index(const struct device_node *np,const char *propname,u32 index, u32 *out_value)
np:节点的指针
propname:键的名字
index:索引号,当属性=多个<>时,0=第一个,1=第二个
out_value:获取到的结果
返回值:成功=0,失败=错误码
4.获取一个u8类型的数组 [ ]括号里的
int of_property_read_variable_u8_array(const struct device_node *np,const char *propname, u8 *out_values,size_t sz_min, size_t sz_max)
np:节点的指针
propname:键的名字
out_values:获取到的结果
sz_min:最小下标
sz_max:最大下标
返回值:成功=0,失败=错误码
5.获取字符串
int of_property_read_string_index(const struct device_node *np,const char *propname,int index, const char **output)
np:节点的指针
propname:键的名字
index:索引号,当属性=多个值时,0=第一个,1=第二个
output:获取到的结果
返回值:成功=0,失败=错误码