Zephyr Devicetree详解 概述
Devicetree起源于Open Firmware(OF),最开始主要应用于PowerPC架构的计算机。之后Devicetree在Linux内核中逐渐被采纳,并在各种硬件平台上广泛应用。Devicetree的主要优势在于它可以将硬件描述与驱动程序解耦,使得驱动程序可以在不同的硬件平台上重用,从而降低了开发和维护成本。嵌入式系统通常具有丰富的硬件设备和定制化的硬件配置,因此Devicetree对于嵌入式系统尤为重要。对于Zephyr这种支持多架构和丰富硬件的RTOS来说使用Devicetree也是不二选择
概述 链接到标题
Devicetree是一种分层数据结构,主要用于描述硬件,Zephyr将Devicetree作为其标准组件,在以下两个方面使用Devicetree:
- 向设备驱动模型描述硬件
- 提供该硬件的初始配置
因此Devicetree既是 Zephyr 的硬件描述语言,也是配置语言。Zephyr的Devicetree符合Devicetree的标准spec。
Zephyr的Devicetree有两类文件:
- Devicetree源文件:.dts, .dtsi, .overlay,源文件是Devicetree本身向设备驱动描述硬件和硬件的初始化配置
- Devicetree绑定文件:.yaml,绑定文件用来描述Devicetree应该有那些内容,以及这些内容的数据类型。
Zephyr的构建系统使用 Devicetree 源和绑定来生成C宏,生成的宏由 devicetree.h 中提供的API 进行访问,在驱动和应用中使用这些API就可从Devicetree中获取硬件信息。 图片摘自Zephyr官方文档.
Zephyr 的驱动程序、应用程序、测试、内核等代码文件都可以包含和使用 devicetree.h
与Linux Devicetree的差异 链接到标题
两者都使用Devicetree作为硬件描述语言,基本的Devicetree语法结构一致。不同点如下:
- 处理工具和结果:Zephyr使用python脚本生存C宏, Linux使用DTC生成DTB
- 处理时机:Zephyr在编译时处理Devicetree,Linux在运行时解析Devicetree二进制文件
- 内存使用:Zephyr设计目标是最小化内存使用,编译时优化,没使用的信息编译时就被去除。Linux内存使用相对较大,运行时保持完整的Devicetree结构.
- 绑定:Zephyr使用专门的yaml绑定文件,解析时自动检查,Linux使用绑定文档进行描述
- 动态性:Zephyr主要用于静态配置,运行时修改能力有限。Linux可在运行时修改Devicetree
- 配置集成:Zephyr的Devicetree和Kconfig关联。Linux则相对独立。
- 访问方法:Zephyr通过生成C宏访问。Linux使用API访问。
设计目标 链接到标题
Devicetree是Zephyr硬件信息的单一来源,Zephyr 的内置设备驱动程序和示例应用程序只应从 Devicetree 获取可配置的硬件描述。
- 新的设备驱动程序应使用 devicetree.h中的 API 来确定要创建哪些设备
- Zephyr 自带的内示例应用程序应按照Devicetree中的aliases来使用设备
- 新 SoC 的启动时引脚复用和引脚控制应通过基于 Devicetree 的 pinctrl 描述来进行
Zephyr中使用解析处理Devicetree的工具是通用的,同样适用于其它Devicetree用户(例如Linux)
- Zephyr 的 Devicetree 源解析器 dtlib.py 与 dtc 等其他工具都源兼容: dtlib.py 可以解析 dtc 输出, dtc 也可以解析 dtlib.py 输出。
- Zephyr 的“扩展 dtlib”库 edtlib.py 不应包含 Zephyr 特定的功能
Zephyr的Devicetree绑定语言允许定义Zephyr独有的属性,但不应该用来表达仅在Zephyr中存在的特殊关系。
- 只有构建在 edtlib.py 之上的 gen_defines.py 脚本包含 Zephyr 特定的知识和功能
- 由于绑定语言不灵活,Zephyr 无法支持 Linux 支持的全套绑定
参考 链接到标题
https://docs.zephyrproject.org/latest/build/dts/intro-scope-purpose.html https://docs.zephyrproject.org/latest/build/dts/design.html