設備樹-內核從設備樹獲取屬性常用函數


驅動獲取設備樹內描述屬性的一般步驟

  • 查找想要的節點
  • 獲取節點中的屬性值

常用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);


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM