设备树中常用的of操作函数-20
Posted 杨斌并
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设备树中常用的of操作函数-20相关的知识,希望对你有一定的参考价值。
设备树中常用的of操作函数
设备都是以节点的形式“挂”到设备树上的,因此要想获取这个设备的其他属性信息,必须先获取到这个设备的节点。
- Linux内核使用device_node结构体来描述一个节点,此结构体定义在文件include/linux/of.h中,定义如下
struct device_node {
const char *name;/*节点名字*/I
const char *type; *设备类型*/
phandle phandle;
const char*full_name;/*节点全名*/
struct fwnode_handle fwnode;
struct property*properties;/*属性*/
struct property *deadprops; /* removed属性*/
struct device_node *parent;/*父节点*/
struct device_node *child;*子节点*/
struct device_node *sibling;
struct kobject 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
}
- 节点的属性信息里面保存了驱动所需要的内容,因此对于属性值的提取非常重要,Linux内核中使用结构体 property,表示属性,此结构体同样定义在文件include/linux/of.h 中,内容如下:
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_path函数作用:函数通过路径来查找指定的节点
函数原型:
inline struct device_node *of_find_node_by_path(const char *path)
参数:
- path:带有全路径的节点名,可以使用节点的别名,比如“/backlight”就是backlight这个节点的全路径。
- 返回值:成功:返回找到的节点,失败返回NULL。
of_get_parent函数
作用:用于获取指定节点的父节点(如果有父节点的话),
函数原型:
struct device_node *of_get_parent(const struct device_node *node)
函数参数:
- node:要查找的父节点的节点。
- 返回值:找到的父节点。
of_get_next_child函数
of_get_next_child 函数用迭代的查找子节点,
函数原型:
struct device_node *of_get_next_child(const struct device_node *node, struct device_node *prev)
参数如下:
- node:父节点。
- prev:前一个子节点,也就是从哪一个子节点开始迭代的查找下一个子节点。可以设置为NULL,表示从第一个子节点开始。
- 返回值:找到的下一个子节点。
查找节点属性的常用of函数:
of_find_property函数
of_find_property函数用于查找指定的属性函数原型:
property *of_find_property(const struct device_node *np,const char *name,int *lenp)
参数:
- np:设备节点。
- name:属性名字。
- lenp:属性值的字节数返回值:找到的属性。
of_property_read_u8函数
of_property_read_u16函数
of_property_read_u32函数
of_property_read_u64函数
有些属性只有一个整型值,这四个函数就是用于读取这种只有一个整型值的属性,分别用于读取u8、u16、u32和u64类型属性值,函数原型如下:
int of_property_read_u8(const struct device_node *np,const char *propname,u8*out value)
int of property_read_u16(const struct device_node *np,const char*propname,u16*out_ value)
int of_property_read_u32(const struct device_node *np,const char *propname,u32 *out_value)
int of property_read_u64(const struct device_node *np,const char *propname,u64*out_ value)
参数:
- np:设备节点。
- proname:要读取的属性名字。
- out_value:读取到的数组值。
- 返回值:0,读取成功,负值,读取失败
of_property_read_u8_array函数
of_property_read_u16_array 函数
of_property_read_u32_array 函数
of_property_read_u64_array函数
这4个函数分别是读取属性中u8、u16、u32和u64类型的数组数据,比如大多数的reg属性都是数组数据,可以使用这4个函数一次读取出reg属性中的所有数据。这四个函数的原型如下:
int of _property_read_u8_array(const struct device_node *np,const char*propname,u8 *out values,size_t sz)
int of_property_read_u16_array(const struct device_node *np,const char *propname,u16 *out_values,size_t sz)
int of_property_read_u32_array(const struct device_node *np,const char*propname,u32*out_values,size_t sz)
int of_property_read_u64_array(const struct device_node*np,const char *propname,u64 *out_values,size t sz)
参数:
- np:设备节点。
- proname:要读取的属性名字。
- out_value:读取到的数组值,分别为u8、u16、u32和u64。Sz:要读取的数组元素数量。
- 返回值:0,读取成功,负值,读取失败
of_property_read_string 函数
of_property_read_string函数用于读取属性中字符串值函数原型:
int of_property_read_string(struct device_node *np,const char *propname,const char **out string)
参数:
- np:设备节点。
- proname:要读取的属性名字。
- out_string:读取到的字符串值。
- 返回值:0,读取成功,负值,读取失败
代码
#include <linux/init.h>
#include <linux/module.h>
#include <linux/of.h>
struct device_node *test_device_node;
struct property *test_node_property;
int size;
const char *str;
u32 out_value[2] = {0};
static int hello_init(void){
int ret = 0;
printk(KERN_EMERG "hello world enter \\n");
//查找我们要的节点
test_device_node = of_find_node_by_path("/test");
if (test_device_node == NULL)
{
printk("of_find_node_by_path is error \\n");
return -1;
}
printk("test_device_node name is %s \\n", test_device_node->name);
//获取属性
test_node_property = of_find_property(test_device_node, "compatible", &size);
if ( test_node_property == NULL )
{
printk("of_find_property is error \\n");
return -1;
}
printk("of_find_property compatible name = %s \\n", test_node_property->name);
printk("of_find_property compatible value = %s \\n", (char *)test_node_property->value);
ret = of_property_read_u32_array(test_device_node, "reg", out_value, 2);
if ( ret < 0)
{
printk("of_property_read_u32_array is error \\n");
return -1;
}
printk("out_value[0] = 0x%08x \\n", out_value[0]);
printk("out_value[1] = 0x%08x \\n", out_value[1]);
ret = of_property_read_string(test_device_node, "status", &str);
if ( ret <0 )
{
printk("of_property_read_string is error \\n");
return -1;
}
printk("status value is %s \\n", str);
return 0;
}
static void hello_exit(void){
printk(KERN_EMERG "hello world exit! \\n");
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("LIYU");
以上是关于设备树中常用的of操作函数-20的主要内容,如果未能解决你的问题,请参考以下文章
Linux——Linux驱动之设备树常用的of操作函数获取节点信息实践(设备树中如何添加自定义节点,如何获取节点的信息?)
Linux DTS (Device Tree Source)设备树源码