写点什么

Linux 内核 设备树操作常用 API

用户头像
赖猫
关注
发布于: 2021 年 03 月 08 日

Linux 设备树语法详解一文中介绍了设备树的语法,这里主要介绍内核中提供的操作设备树的 API,这些 API 通常都在"include/of.h"中声明。

device_node,内核中用下面的这个结构描述设备树中的一个节点,后面的 API 都需要一个 device_node 对象作为参数传入。


//include/of.h


  struct device_node {          const char *name;          const char *type;          phandle phandle;          const char *full_`name;            struct  property *properties;          struct  property *deadprops;    /* removed properties */          struct  device_node *parent;          struct  device_node *child;          struct  device_node *sibling;          struct  device_node *next;      /* next device of same type */          struct  device_node *allnext;   /* next in list of all nodes */          struct  proc_dir_entry *pde;    /* this node's proc directory */          struct  kref kref;          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  };
复制代码


struct device_node

---->节点名

---->设备类型

---->全路径节点名

---->父节点指针

---->子节点指针


查找节点 API

/**


of_find_compatible_node

 - 通过 compatible 属性查找指定节点

@from - 指向开始路径的节点,如果为 NULL,则从根节点开始

@type - device_type 设备类型,可以为 NULL

@compat - 指向节点的 compatible 属性的值(字符串)的首地址

成功:得到节点的首地址;失败:NULL

*/

struct device_node *of_find_compatible_node(struct device_node *from,const char type, const charcompat);

/

of_find_matching_node

 - 通过 compatible 属性查找指定节点

@from - 指向开始路径的节点,如果为 NULL,则从根节点开始

@matches - 指向设备 ID 表,注意 ID 表必须以 NULL 结束

范例: const struct of_device_id mydemo_of_match[] = {

{ .compatible = “fs4412,mydemo”, },

{}

};

成功:得到节点的首地址;失败:NULL

*/


struct device_node *of_find_matching_node(struct device_node *from,const struct of_device_id *matches);


/**


of_find_node_by_path

 - 通过路径查找指定节点

@path - 带全路径的节点名,也可以是节点的别名

成功:得到节点的首地址;失败:NULL

*/

struct device_node of_find_node_by_path(const charpath);

/

of_find_node_by_name

 - 通过节点名查找指定节点

@from - 开始查找节点,如果为 NULL,则从根节点开始

@name- 节点名

成功:得到节点的首地址;失败:NULL

*/

struct device_node *of_find_node_by_name(struct device_node from,const charname);

提取通用属性 API

/

of_find_property

 - 提取指定属性的值

@np - 设备节点指针

@name - 属性名称

@lenp - 属性值的字节数

成功:属性值的首地址;失败:NULL

*/

struct property *of_find_property(const struct device_node *np, const char name, intlenp);

/

of_property_count_elems_of_size - 得到属性值中数据的数量

@np - 设备节点指针

@propname - 属性名称

@elem_size - 每个数据的单位(字节数)

成功:属性值的数据个数;失败:负数,绝对值是错误码

*/

int of_property_count_elems_of_size(const struct device_node np,const charpropname, int elem_size);

/

of_property_read_u32_index

 - 得到属性值中指定标号的 32 位数据值

@np - 设备节点指针

@propname - 属性名称

@index - 属性值中指定数据的标号

@out_value - 输出参数,得到指定数据的值

成功:0;失败:负数,绝对值是错误码

*/

int of_property_read_u32_index(const struct device_node *np, const char propname, u32 index, u32out_value);

/

of_property_read_string

 - 提取字符串(属性值)

@np - 设备节点指针

@propname - 属性名称

@out_string - 输出参数,指向字符串(属性值)

成功:0;失败:负数,绝对值是错误码

*/

int of_property_read_string(struct device_node *np, const char *propname, const char out_string);

提取 addr 属性 API

/

of_n_addr_cells

 - 提取默认属性“#address-cells”的值

@np - 设备节点指针

成功:地址的数量;失败:负数,绝对值是错误码

/

int of_n_addr_cells(struct device_nodenp);

/

of_n_size_cells

 - 提取默认属性“#size-cells”的值

@np - 设备节点指针

成功:地址长度的数量;失败:负数,绝对值是错误码

/

int of_n_size_cells(struct device_nodenp);

/

of_get_address

 - 提取 I/O 口地址

@np - 设备节点指针

@index - 地址的标号

@size - 输出参数,I/O 口地址的长度

@flags - 输出参数,类型(IORESOURCE_IO、IORESOURCE_MEM)

成功:I/O 口地址的首地址;失败:NULL

*/

__be32 *of_get_address(struct device_node *dev, int index, u64 size, unsigned intflags);

/

of_translate_address

 - 从设备树中提取 I/O 口地址转换成物理地址

@np - 设备节点指针

@in_addr - 设备树提取的 I/O 地址

成功:物理地址;失败:OF_BAD_ADDR

*/

u64 of_translate_address(struct device_node dev, const __be32in_addr);

/

of_iomap

 - 提取 I/O 口地址并映射成虚拟地址

@np - 设备节点指针

@index - I/O 地址的标号

成功:映射好虚拟地址;失败:NULL

*/

void __iomem of_iomap(struct device_nodenp, int index);

/

功能:提取 I/O 口地址并申请 I/O 资源及映射成虚拟地址

@np - 设备节点指针

@index - I/O 地址的标号

@name - 设备名,申请 I/O 地址时使用

成功:映射好虚拟地址;失败:NULL

*/

void __iomem *of_io_request_and_map(struct device_node np, int index, const charname);

提取 resource 属性 API

/

of_address_to_resource

 - 从设备树中提取资源 resource(I/O 地址)

@np - 设备节点指针

@index - I/O 地址资源的标号

@r - 输出参数,指向资源 resource(I/O 地址)

成功:0;失败:负数,绝对值是错误码

*/

int of_address_to_resource(struct device_node dev, int index, struct resourcer);

提取 GPIO 属性 API

/

include/of_gpio.h

of_get_named_gpio

 - 从设备树中提取 gpio 口

@np - 设备节点指针

@propname - 属性名

@index - gpio 口引脚标号

成功:得到 GPIO 口编号;失败:负数,绝对值是错误码

*/

int of_get_named_gpio(struct device_node np, const charpropname, int index);

提取 irq 属性 API

/

of_irq_count

从设备树中提取中断的数量

@np - 设备节点指针

成功:大于等于 0,实际中断数量,0 则表示没有中断

/

int of_irq_count(struct device_nodedev);

/

of_irq_get

 - 从设备树中提取中断号

@np - 设备节点指针

@index - 要提取的中断号的标号

成功:中断号;失败:负数,其绝对值是错误码

int of_irq_get(struct device_node dev, int index);

提取其他属性 API

/*

of_get_mac_address

 - 从设备树中提取 MAC 地址

@np - 设备节点指针

@成功:MAC(6 字节)的首地址;失败:NULL

*/

void *of_get_mac_address(struct device_node *np);


自己的Linux、C/C++技术交流群:【960994558】整理了一些个人觉得比较好的学习书籍、大厂面试题、和热门技术教学视频资料共享在里面(包括 C/C++,Linux,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK 等等.),有需要的可以自行添加哦!~



以上有不足的地方欢迎指出讨论,觉得不错的朋友希望能得到您的转发支持,同时可以持续关注我,每天分享 Linux C/C++后台开发干货内容!


用户头像

赖猫

关注

还未添加个人签名 2020.11.28 加入

纸上得来终觉浅,绝知此事要躬行

评论

发布
暂无评论
Linux内核 设备树操作常用API