本文主要是介绍设备树接口函数,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
0.前言
在前一篇博客里面,写设备树语法介绍和接口函数的时候,写到一半发现csdn有篇幅限制,现在在此篇进行补充。
之前的文章路径如下
驱动开发之设备树语法-CSDN博客
1.接口函数
1.1.of_property_read_xx_array 函数
int of_property_read_u8_array(const struct device_node *np,
const char *propname,
u8 *out_values,
size_t sz)
int of_property_read_u16_array(const struct device_node *np,const char *propname, u16 *out_values, size_t sz)
int of_property_read_u32_array(const struct device_node *np,const char *propname, u32 *out_values,size_t sz)
int of_property_read_u64_array(const struct device_node *np,const char *propname, u64 *out_values,
size_t sz)
np:设备节点
proname: 要读取的属性名字
out_value:读取到的数组值,分别为 u8、u16、u32 和 u64。
sz:要读取的数组元素数量。
返回值:0,读取成功,负值,读取失败,-EINVAL 表示属性不存在,-ENODATA 表示没 有要读取的数据,-EOVERFLOW 表示属性值列表太小。
1.2.of_property_read_xx_array 函数
of_property_read_u8 函数 of_property_read_u16 函数 of_property_read_u32 函数 of_property_read_u64 函数, 有些属性只有一个整形值,这四个函数就是用于读取这种只有一个整形值的属性,分别用 于读取 u8、u16、u32 和 u64 类型属性值
int of_property_read_u8(const struct device_node *np,
const char *propname,
u8 *out_value)
int of_property_read_u16(const struct device_node *np,
const char *propname,
u16 *out_value)
int of_property_read_u32(const struct device_node *np,
const char *propname,
u32 *out_value)
int of_property_read_u64(const struct device_node *np,
const char *propname,
u64 *out_value)
np:设备节点
proname: 要读取的属性名字
out_value:读取到的数组值
返回值:0,读取成功,负值,读取失败,-EINVAL 表示属性不存在,-ENODATA 表示没 有要读取的数据,-EOVERFLOW 表示属性值列表太小
1.3.of_property_read_string 函数
of_property_read_string 函数用于读取属性中字符串值,
int of_property_read_string(struct device_node *np, const char *propname, const char **out_string)
np:设备节点
proname: 要读取的属性名字
out_string:读取到的字符串值
返回值:0,读取成功,负值,读取失败
1.4.of_n_addr_cells 函数
of_n_addr_cells 函数用于获取#address-cells 属性值,
int of_n_addr_cells(struct device_node *np)
np:设备节点。
返回值:获取到的#address-cells 属性值。
1.5.of_n_size_cells 函数
of_size_cells 函数用于获取#size-cells 属性值,
int of_n_size_cells(struct device_node *np)
np:设备节点。
返回值:获取到的#size-cells 属性值。
1.6.of_device_is_compatible 函数
of_device_is_compatible 函数用于查看节点的 compatible 属性是否有包含 compat 指定的字 符串,也就是检查设备节点的兼容性
int of_device_is_compatible(const struct device_node *device, const char *compat)
device:设备节点。
compat:要查看的字符串。
返回值:0,节点的 compatible 属性中不包含 compat 指定的字符串;正数,节点的 compatible 属性中包含 compat 指定的字符串。
1.7.of_get_address 函数
of_get_address 函数用于获取地址相关属性,主要是“reg”或者“assigned-addresses”属性 值
const __be32 *of_get_address(struct device_node *dev, int index, u64 *size, unsigned int *flags) dev:设备节点。
index:要读取的地址标号。
size:地址长度。
flags:参数,比如 IORESOURCE_IO、IORESOURCE_MEM 等
返回值:读取到的地址数据首地址,为 NULL 的话表示读取失败。
1.8.of_translate_address 函数
of_translate_address 函数负责将从设备树读取到的地址转换为物理地址,函数原型如下: u64 of_translate_address(struct device_node *dev, const __be32 *in_addr)
dev:设备节点。
in_addr:要转换的地址。
返回值:得到的物理地址,如果为 OF_BAD_ADDR 的话表示转换失败。
1.9.of_address_to_resource 函数
IIC、SPI、GPIO 等这些外设都有对应的寄存器,这些寄存器其实就是一组内存空间,Linux 内核使用 resource 结构体来描述一段内存空间,“resource”翻译出来就是“资源”,因此用 resource 结构体描述的都是设备资源信息,resource 结构体定义在文件 include/linux/ioport.h 中,定义如 下
struct resource {
resource_size_t start;
resource_size_t end;
const char *name;
unsigned long flags;
struct resource *parent, *sibling, *child;
};
对于 32 位的 SOC 来说,resource_size_t 是 u32 类型的。其中 start 表示开始地址,end 表示 结束地址,name 是这个资源的名字,flags 是资源标志位,一般表示资源类型,可选的资源标志 定义在文件 include/linux/ioport.h 中
#define IORESOURCE_BITS 0x000000ff
#define IORESOURCE_TYPE_BITS 0x00001f00
#define IORESOURCE_IO 0x00000100
#define IORESOURCE_MEM 0x00000200
#define IORESOURCE_REG 0x00000300
#define IORESOURCE_IRQ 0x00000400
#define IORESOURCE_DMA 0x00000800
#define IORESOURCE_BUS 0x00001000
#define IORESOURCE_PREFETCH 0x00002000
#define IORESOURCE_READONLY 0x00004000
#define IORESOURCE_CACHEABLE 0x00008000
#define IORESOURCE_RANGELENGTH 0x00010000
#define IORESOURCE_SHADOWABLE 0x00020000
#define IORESOURCE_SIZEALIGN 0x00040000
#define IORESOURCE_STARTALIGN 0x00080000
#define IORESOURCE_MEM_64 0x00100000
#define IORESOURCE_WINDOW 0x00200000
#define IORESOURCE_MUXED 0x00400000
#define IORESOURCE_EXCLUSIVE 0x08000000
#define IORESOURCE_DISABLED 0x10000000
#define IORESOURCE_UNSET 0x20000000
#define IORESOURCE_AUTO 0x40000000
#define IORESOURCE_BUSY 0x80000000
这些在platform实验里面有使用过,如果感兴趣可以看看下面这个文章
驱动开发之platform总线-CSDN博客
最 常 见 的 资 源 标 志 就 是 IORESOURCE_MEM 、 IORESOURCE_REG 和 IORESOURCE_IRQ 等。
of_address_to_resource 函数,此函数是从设 备树里面提取资源值,但是本质上就是将 reg 属性值,然后将其转换为 resource 结构体类型
函数原型如下所示 int of_address_to_resource(struct device_node *dev, int index, struct resource *r)
dev:设备节点
index:地址资源标号。
r:得到的 resource 类型的资源值。
返回值:0,成功;负值,失败。
1.10.of_iomap 函数
of_iomap 函数用于直接内存映射,以前我们会通过 ioremap 函数来完成物理地址到虚拟地 址的映射,采用设备树以后就可以直接通过 of_iomap 函数来获取内存地址所对应的虚拟地址, 不需要使用 ioremap 函数了。当然了,你也可以使用 ioremap 函数来完成物理地址到虚拟地址 的内存映射,只是在采用设备树以后,大部分的驱动都使用 of_iomap 函数了。of_iomap 函数本 质上也是将 reg 属性中地址信息转换为虚拟地址,如果 reg 属性有多段的话,可以通过 index 参 数指定要完成内存映射的是哪一段
of_iomap 函数原型如下:
void __iomem *of_iomap(struct device_node *np, int index)
np:设备节点。
index:reg 属性中要完成内存映射的段,如果 reg 属性只有一段的话 index 就设置为 0。
返回值:经过内存映射后的虚拟内存首地址,如果为 NULL 的话表示内存映射失败。
2.实验
接口使用的实验后续补充
这篇关于设备树接口函数的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!