设备树中常用的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;
};

或者设备树文件节点里面资源的步骤:

  1. 步骤一:查找我们要找的节点。
  2. 步骤二:获取我们需要的属性值。

查找节点的常用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");
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值