一. 简介
前面几篇学习了设备树常用的 OF操作函数,文章地址如下:
设备树常用 OF 操作函数说明一-CSDN博客
设备树常用 OF 操作函数说明二-CSDN博客
本文继续学习设备树 常用的一些其他的 OF操作函数。
二. 设备树常用的其他 OF操作函数
下面学习设备树其他的 OF操作函数。
1. 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 指定的字符串。
2. 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 的话表示读取失败。
3. of_translate_address 函数
of_translate_address 函数负责将从设备树读取到的地址转换为物理地址,函数原型如下:
u64 of_translate_address(struct device_node *dev, const __be32 *in_addr)
函数参数和返回值含义如下:
dev :设备节点。
in_addr :要转换的地址。
返回值: 得到的物理地址,如果为 OF_BAD_ADDR 的话表示转换失败。
4. of_address_to_resource 函数
IIC 、 SPI 、 GPIO 等这些外设都有对应的寄存器,这些寄存器其实就是一组内存空间, Linux 内核使用 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 中。
大 家 一 般 最 常 见 的 资 源 标 志 就 是 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 ,成功;负值,失败。
5. 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 的话表示内存映射失败。
三. 总结
关于设备树常用的 OF 函数就先讲解到这里, Linux 内核中关于设备树的 OF 函数不仅仅只有前面讲的这几个,还有很多 OF 函数我们并没有讲解,这些没有讲解的 OF 函数要结合具体 的驱动,例如,获取中断号的 OF 函数、获取 GPIO 的 OF 函数等等,这些 OF 函数我们在后面的 驱动实验中再详细的讲解。
关于设备树就讲解到这里,关于设备树我们重点要了解一下几点内容:
① DTS 、 DTB 和 DTC 之间的区别,如何将 .dts 文件编译为 .dtb 文件。
② 设备树语法,这个是重点,因为在实际工作中我们是需要修改设备树的。
③ 设备树的几个特殊子节点。
④ 关于设备树的 OF 操作函数,也是重点,因为设备树最终是被驱动文件所使用的,而 驱动文件必须要读取设备树中的属性信息,比如内存信息、 GPIO 信息、中断信息等等。要想在 驱动中读取设备树的属性值,那么就必须使用 Linux 内核提供的众多的 OF 函数。