设备树-内核从设备树获取属性常用函数

驱动获取设备树内描述属性的一般步骤

  • 查找想要的节点
  • 获取节点中的属性值

常用of操作函数

include/linux/of.h

在内核中以of开头的函数,一般是来操作设备树的

查找结点的函数

static inline struct device_node *of_find_node_by_path(const char *path);
//参数:全路径的节点名,就是要从根节点一直到要找的节点。比如"/backlight"0
//返回值:成功返回找到的节点,失败返回NULL

查找节点中指定的属性

struct property *of_find_property(const struct device_node *np,
					 const char *name,
					 int *lenp);
//np:设备节点;name:属性名字;lenp:获取属性值的字节数
//返回值:找到的属性

获取节点的父节点

struct device_node *of_get_parent(const struct device_node *node);
//参数:要查找父节点的节点
//返回值:查找到的父节点 或者 NULL

迭代查找子节点

struct device_node *of_get_next_child(const struct device_node *node,
					     struct device_node *prev);

读取属性中的数据

/*
of_property_read_u8(const struct device_node *np,const char *propname,u8 *out_value)
of_property_read_u16(const struct device_node *np,const char *propname,u16 *out_value)
of_property_read_u32(const struct device_node *np,const char *propname,u32 *out_value)
of_property_read_u64(const struct device_node *np,const char *propname,u64 *out_value)
of_property_read_u8_array
of_property_read_u16_array
of_property_read_u32_array
of_property_read_u64_array
of_property_read_string
of_property_read_string_array
*/


static inline int of_property_read_u8(const struct device_node *np,
				       const char *propname,
				       u8 *out_value)
{
	return of_property_read_u8_array(np, propname, out_value, 1);
}
//np设备节点;propname要读取的属性名字;out_value读到的值指针
//返回值,成功0,失败负数


static inline int of_property_read_u8_array(const struct device_node *np,
					    const char *propname,
					    u8 *out_values, size_t sz){...}
//np设备节点;propname要读取的属性名字;out_value读到的值指针;sz要读取的字节数
//返回值,成功0,失败负数


static inline int of_property_read_string(const struct device_node *np,
					  const char *propname,
					  const char **out_string){...}
//np设备节点;propname要读取的属性名字;out_string读到的字符串
//返回值,成功0,失败负数

static inline int of_property_read_string_array(const struct device_node *np,
						const char *propname, const char **out_strs,
						size_t sz){...}

of_iomap

<linux/of_address.h>

of_iomap函数用于直接内存映射,使用ioremap也可以。

void __iomem *of_iomap(struct device_node *np, int index);

np: 设备节点

index:reg属性中要完成内存映射的段

返回:经过内存映射后的虚拟内存的首地址,失败返回NULL

例如设备树中
&test{
	reg = < 0x20ac000 0x0000004
			0x20ac004 0x0000004
	>;
};
说明reg属性有两段
如果index填0,代表转换0x20ac000的地址;填1转换0x20ac004的地址

重要的结构体

Linux内核使用device_node结构体来描述一个节点,结构体定义在include/linux/of.h中

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;	/* removed properties */
	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
};

property属性参数,保存了驱动所需的内容

struct property {
	char	*name;  //属性名字
	int	length;    //属性长度
	void	*value;  //属性值
	struct property *next;  //下一个属性
	unsigned long _flags;
	unsigned int unique_id;
	struct bin_attribute attr;
};

函数使用演示

struct device_node device_node_test;
device_node_test = of_find_node_by_path("/test");  //查找test节点

int sizeCom;
struct property *property_test;
property_test = of_find_property( device_node_test, "compatible", &sizeCom); //获取节点中的compatible属性

int regValue[2]={0};
int ret;
ret = of_property_read_u32_array( device_node_test, "reg", regValue, 2); //获取reg属性的数据数组

const char *stra;
int ret2;
ret2 = of_property_read_string( device_node_test, "status", stra);
posted @ 2021-10-10 17:09  WuYunTaXue  阅读(1056)  评论(0编辑  收藏  举报