在线时间4072 小时
UID3441752
注册时间2017-11-21
NXP金币750299
TA的每日心情 | 开心 2024-3-26 15:16 |
---|
签到天数: 266 天 [LV.8]以坛为家I
管理员
- 积分
- 32091
- 最后登录
- 2024-5-8
|
看过前几篇系列文章的小伙伴们应该对这两个新名词不会很陌生,因为这哥俩儿几乎已经贯穿了Zephyr的所有构建阶段。可以说,他们是ZephyrOS的特殊之处,也是ZephyrOS构建系统的基础,通俗点讲,DeviceTree负责ZephyrOS中硬件资源的描述/管理,而Kconfig负责软件代码的管理。
现在我们开始聊聊DeviceTree,当然,还是先从他是谁聊起。
DeviceTree(设备树)发源于PowerPC架构,为了消除代码中冗余的各种device注册代码而产生,现在已经成为了Linux的通用机制。
DeviceTree的结构非常简单,由两种元素组成:Node(节点)、Property(属性)。作为一种用来描述板载硬件资源的层级数据结构。Zephyr使用他来表示支持板子上的可用资源,当然,还包括一些硬件的初始化配置信息。
本篇所涉及的DeviceTree仅针对于ZephyrOS中所使用的DeviceTree概念,与原生Linux上使用的DeviceTree会有些许不同,特别体现在设备树文件的使用上。
在Linux下,设备树文件通常会被DTC编译为DTB文件,放到外部存储设备,在启动时,DTB文件会由Bootloader送给内核使用。
但是,对于资源有限设备,这套机制可能过于庞大。因此,Zephyr采用了一种builtin的方式来使用设备树文件,其过程如下:
首先我们看到,有两种格式的文件作为输入,其中一种叫做Devicetree源文件,这些文件可以理解为设备树文件本身;第二种是Devicetree binding文件,这些文件负责描述设备树文件中的内容,包括数据类型等。
随后,构建系统会将他们解析处理为C头文件,这里还有一个比较重要的文件,叫做devicetree.h,里面定义了一些工具宏,辅助我们获取设备树节点信息,这样一来,所有包含了devicetree.h的源文件,都可以借助这些宏来访问设备树信息,后面会举例说明。
接下来,我们来聊聊一个设备树的基本构成:
上图里我们定义了一个最简单的设备树节点,下面来分开说明我们在这里都定义了什么:
/dts-1/: 指示DTS的版本信息
/ :代表这是一个根节点
a-node: 一个子节点, 在其中又包含了一个子节点,a-sub-node
subnode_label: 子节点的label,可以在其他设备树文件中被引用
foo:一个属性参数,并且有一个值,3,目前支持三种参数类型:
a) 32-bit整形:<>
b) 字符串: “hello_world”
c) 字节: [00 01 1b]
以上这几个要素就构成了一个最简单的设备树文件,下面我们来看看一个真正反映物理硬件层级的例子,以I2C为例,当I2C控制器拥有下面这一拓扑结构时:
其对应的设备树结构就类似于:
再看一个真正的I2C节点定义的例子,这里的属性就用来描述或是硬件节点配置信息,例如i2c地址。
这一拓扑结构下,对应的设备树文件就是这个样子:
我们来展开说明一下,设备树中的一些重要属性:
compatible:用来说明当前节点指代了什么硬件设备
node:设备名字
reg:用来指定设备的地址,一般由两部分构成,<地址 长度>,例如针对于i2c设备地址就是其对应到i2c控制器中的slave地址。针对于i2c控制器来说,这个地址是其寄存器地址。长度信息可以省略
status:字符串用来描述当前节点是否有效,包括“okay”,“disabled”, “reserved”, “fail”
interrupts:描述中断信息,中断号,中断优先级等
当然,Zephyr的设备树中,往往还会有一个叫做chosen的节点,这个节点往往是赋予节点一个特殊功能,例如挂载uart0为zephyr的控制台输出:
这里我们还看到了一个叫做aliases的节点,这个节点用于为现有节点起一个别名,以供程序调用。
说完设备树,相信大家一定还记得一个叫做bingding的文件,他是和设备树文件一起作为输入,生成最终的C头文件的,那么他是用来做什么的呢?
我们知道,设备树是用来描述硬件构成和硬件层级结构的,但是他不会告诉Zephyr构建系统哪些属性/定义是有用的。那么此时就需要bingding文件了,首先他是一个yaml格式的文件,提供了设备树所需要的另一半信息,即属性定义以及哪些属性是必须的,这样一来,构建系统才可以生成正确的代码,同时要注意,bingding文件的名字要和设备树节点定义时的compatible属性中的名字一模一样:
这里是一个ITCM设备树节点对应的bingding文件,指示我们的ITCM节点拥有一个属性,reg,其描述了ITCM的地址和长度。
最后我们来看看我们要如何使用devicetree.h中提供的工具宏才获取设备树节点信息,假设我们有这么一个设备树节点:
最终会生成类似这样的宏字段:
我们就以获取这个寄存器地址为例进行说明,想要获取寄存器的基地址,我们只需要在程序中调用DT_INST_REG_ADDR(0)即可,0代表的是第一个I2C实例,因为我们的芯片往往会有多个I2C控制器。访问其他信息大致雷同,比如我们想获取中断号信息,可以使用DT_INST_IRQn(0)来获取中断号。其他API还请大家自行探索,小编就不一一举例了。
简单总结一下,小编今天主要和大家分享了Zephyr中设备树的概念,包括什么是设备树,设备树节点定义,以及最后如何在程序中,通过devicetree.h中提供的API获取设备树节点信息。还是一些比较基础的内容,大家可以自行深入探索。
|
|