diff --git a/Software/Development/OperatingSystem/Linux/Kernel/Modules/DeviceTree/DeviceTree.md b/Software/Development/OperatingSystem/Linux/Kernel/Modules/DeviceTree/DeviceTree.md new file mode 100644 index 0000000..8c2c525 --- /dev/null +++ b/Software/Development/OperatingSystem/Linux/Kernel/Modules/DeviceTree/DeviceTree.md @@ -0,0 +1,274 @@ +# Device Tree + +## DTS 语法 + +## Device Tree 的解析 + +### device_node 结构体 + +Linux 内核中使用 device_node 结构体来描述一个节点,此结构体定义在文件 include/linux/of.h 中,定义如下: + +```cpp +struct device_node { + const char *name; /* 节点名字 */ + const char *type; /* 设备类型 */ + phandle phandle; + const char *full_name; /* 节点全名 */ + struct fwnode_handle fnode; + + struct property *properties; /* 属性 */ + struct property *deadprops; /* removes 属性 */ + struct device_node *parend; /* 父节点 */ + struct device_node *child; /* 子节点 */ + struct device_node *sibling; + struct kobject kobj; + ... +} +``` + +### property 结构体 + +Linux 内核中使用 struct property 结构体来表示属性,定义如下: + +```cpp +struct property { + char *name; //属性名字 + int length; //属性长度 + void *value; //属性值 + struct property *next;//下一个属性 + unsigned long _flags; + unsigned int unique_id; + struct bin_attribute attr; +} +``` + +### 常用 OF 函数 + +#### of_find_node_by_name 函数 + +**函数原型:** + +```cpp +struct device_node *of_find_node_by_name(struct device_node *from, const char *name); +``` + +**说明:** + +通过节点名字查找指定的节点。 + +**参数:** + +from:开始查找的节点,如果为 NULL 表示从根节点开始查找整个设备树 + +name:要查找的节点名字 + +**返回值:** + +成功则返回找到的节点,失败返回 NULL。 + +#### of_find_node_by_type 函数 + +**函数原型:** + +```cpp +struct device_node *of_find_node_by_type(struct device_node *from, const char *type); +``` + +**说明:** + +通过 device_type 属性查找指定的节点。 + +**参数:** + +from:开始查找的节点,如果为 NULL 表示从根节点开始查找整个设备树 + +type:要查找的节点对应的字符串,也就是 device_type 属性值 + +**返回值:** + +成功则返回找到的节点,失败返回 NULL。 + +#### of_find_compatible_node 函数 + +**函数原型:** + +```cpp +struct device_node *of_find_compatible_node(struct device_node *from, const struct of_device_id *matches, const struct of_device_id **match); +``` + +**说明:** + +根据 device_type 和 compatible 这两个属性查找指定的节点。 + +**参数:** + +from:开始查找的节点,如果为 NULL 表示从根节点开始查找整个设备树 + +matches:of_device_id 匹配表,也就是在此匹配表里面查找节点 + +match:找到的匹配的 of_device_id + +**返回值:** + +成功则返回找到的节点,失败返回 NULL。 + +#### of_find_node_by_path 函数 + +**函数原型:** + +```cpp +inline struct device_node *of_find_node_by_path(const char *path); +``` + +**说明:** + +通过路径来查找指定的节点。 + +**参数:** + +path:带有全路径的节点名 + +**返回值:** + +成功则返回找到的节点,失败返回 NULL。 + +#### of_get_parent 函数 + +**函数原型:** + +```cpp +struct device_node *of_get_parent(const struct device_node *node); +``` + +**说明:** + +用于获取指定节点的父节点(如果有父节点的话)。 + +**参数:** + +node:子节点。 + +**返回值:** + +成功则返回找到的父节点,失败返回 NULL。 + +#### of_get_next_child 函数 + +**函数原型:** + +```cpp +struct device_node *of_get_next_child(const struct device_node *node, struct device_node *prev); +``` + +**说明:** + +查找谋节点的子节点。 + +**参数:** + +node:父节点。 + +prev:前一个子节点,也就是从哪一个子节点开始的下一个子节点,如果为 NULL 表示从第一个子节点开始 + +**返回值:** + +成功则返回找到的下一个子节点,失败返回 NULL。 + +#### of_find_property 函数 + +**函数原型:** + +```cpp +struct property *of_find_property(const struct device_node *np, const char *name, int *lenp); +``` + +**说明:** + +通过属性名称查找指定的属性 + +**参数:** + +np:设备节点 + +name:属性名字 + +lenp:返回属性值的字节数 + +**返回值:** + +成功则返回找到的属性,失败返回 NULL。 + +#### of_get_property 函数 + +**函数原型:** + +```cpp +const void *of_get_property(const struct device_node *np, const char *name, int *lenp) +``` + +**说明:** + +是 of_find_property 函数的扩展,直接返回 property 的 value 属性。 + +**参数:** + +np:设备节点 + +name:属性名字 + +lenp:返回属性值的字节数 + +**返回值:** + +成功则返回找到的 value,失败返回 NULL。 + +#### of_property_count_elems_of_size 函数 + +**函数原型:** + +```cpp +int of_property_count_elems_of_size(const struct device_node *np, const char *propname int elem_size) +``` + +**说明:** + +用于获取属性中元素的数量,比如 reg 属性值是一个数组,那么使用此函数可以获取到这个数组的大小。 + +**参数:** + +np:设备节点。 + +proname: 需要统计元素数量的属性名字。 + +elem_size:元素长度。 + +**返回值:** + +得到的属性元素数量。 + +#### of_property_read_u32_index 函数 + + + + + + +#### 函数 + +**函数原型:** + +```cpp + +``` + +**说明:** + + + +**参数:** + + + +**返回值:** + +