第十八节、设备树中常用的of操作函数
本节用于介绍设备树中常用的of操作函数
设备都是以节点的形式“挂”到设备树上的,因此要想获取这个设备的其他属性信息,必须先获取到这个设备的节点。
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 属性 */
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中
内容如下
文件位置路径: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;
};
获得设备树文件节点里面资源的步骤:
步骤一:查找我们要找的节点。
步骤二:获取我们需要的属性值。
一、查找节点的常用of函数
<1>of_find_node_by_path 函数
作用:函数通过路径来查找指定的节点
函数原型:
文件位置路径:include/linux/of_irq.h
static inline struct device_node *of_find_node_by_path(const char *path)
{
return of_find_node_opts_by_path(path, NULL);
}
//参数
//path:带有全路径的节点名,可以使用节点的别名,比如"/backlight”就是backlight这个节点的全路径。
//返回值
//成功:返回找到的节点,失败返回NULL。
<2>of_get_parent函数
作用:用于获取指定节点的父节点(如果有父节点的话)
函数原型:
文件位置路径:include/linux/of_irq.h
extern struct device_node *of_get_parent(const struct device_node *node);
//参数
//node:要查找父节点的节点。
//返回值
//找到的父节点。
<3>of_get_next_child函数
作用:用迭代的方式查找子节点
函数原型:
文件位置路径:include/linux/of_irq.h
extern struct device_node *of_get_next_child(const struct device_node *node, struct device_node *prev);
//参数
//node:要查找子节点的节点。
//prev:前一个子节点,也就是从哪一个子节点开始迭代的查找下一个子节点。可以设置为NULL,表示从第一个子节点开始。
//返回值
//找到的下一个子节点
二、查找节点属性的常用of函数
<1>of_find_property函数
作用:用于查找指定的属性
函数原型:
文件位置路径:include/linux/of_irq.h
extern struct property *of_find_property(const struct device_node *np, const char *name, int *lenp);
//参数
//np:设备节点
//name:属性的名称
//lenp:属性值的字节数
//返回值
//找到的属性
<2>获取整数值属性
有些属性只有一个整型值,这四个函数就是用于读取这种只有一个整型值的属性,分别用于读取u8、u16、u32和u64类型属性值,函数原型如下:
文件位置路径:include/linux/of_irq.h
static inline int of_property_read_u8(const struct device_node *np, const char *propname, u8 *out_value)
static inline int of_property_read_u16(const struct device_node *np, const char *propname, u16 *out_value)
static inline int of_property_read_u32(const struct device_node *np, const char *propname, u32 *out_value)
static inline int of_property_read_u64(const struct device_node *np, const char *propname, u64 *out_value)
//参数
//np:设备节点
//propname:属性的名称
//out_value:读取到的整数值
//返回值
//0:读取成功
//负值:读取失败
<3>获取数组属性
这4个函数分别是读取属性中u8、u16、u32和u64类型的数组数据,比如大多数的reg属性都是数组数据,可以使用这4个函数一次读取出reg属性中的所有数据。这四个函数的原型如下:
文件位置路径:include/linux/of_irq.h
static inline int of_property_read_u8_array(const struct device_node *np, const char *propname, u8 *out_values, size_t sz)
static inline int of_property_read_u16_array(const struct device_node *np, const char *propname, u16 *out_values, size_t sz)
static inline int of_property_read_u32_array(const struct device_node *np, const char *propname, u32 *out_values, size_t sz)
static inline int of_property_read_u64_array(const struct device_node *np, const char *propname, u64 *out_values, size_t sz)
//参数
//np:设备节点
//propname:属性的名称
//out_value:读取到的数组值,分别为u8、u16、u32和u64。
//sz:要读取的数组元素数量。
//返回值
//0:读取成功
//负值:读取失败
<4>of_property_read_string函数
作用:用于读取属性中字符串值
函数原型:
文件位置路径:include/linux/of_irq.h
static inline int of_property_read_string(struct device_node *np, const char *propname, const char **out_string)
//参数
//np:设备节点
//propname:属性的名称
//out_string:读取到的字符串值
//返回值
//0:读取成功
//负值:读取失败
<5>of_iomap函数
作用:of_iomap函数用于直接内存映射,以前我们会通过ioremap函数来完成物理地址到虚拟地址的映射。
函数原型:
文件位置路径:include/linux/of_address.h
static inline void __iomem *of_iomap(struct device_node *device, int index)
//参数
//np:设备节点
//index:reg 属性中要完成内存映射的段,如果reg属性只有一段的话index就设置0。
//返回值
//经过内存映射后的虚拟内存首地址,如果为NULL的话表示内存映射失败
<6>of_get_named_gpio函数
作用:此函数获取GPIO编号,因为Linux内核中关于GPIO的API函数都要使用GPIO编号,此函数会将设备树中类似<&gpio1 3 GPIO_ACTIVE_LOW>的属性信息转换为对应的GPIO编号
函数原型:
文件位置路径:include/linux/of_gpio.h
static inline int of_get_named_gpio(struct device_node *np, const char *propname, int index)
//参数
//np:设备节点
//propname:属性的名称
//index:因为一个属性里面可能包含多个GPIO,此参数指定要获取哪个GPIO的编号,如果只有一个GPIO信息的话此参数为0。
//返回值
//成功返回到的GPIO编号
//失败返回一个负数