一.? 简介
前面几篇学习了设备树常用的 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
函数。