驅動獲取設備樹內描述屬性的一般步驟
- 查找想要的節點
- 獲取節點中的屬性值
常用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);