设备树-内核从设备树获取属性常用函数
驱动获取设备树内描述属性的一般步骤
- 查找想要的节点
- 获取节点中的属性值
常用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);