深入描述dts和dtsi的区别

QA:dts和dtsi的区别

在嵌入式 Linux 系统中,DTS(Device Tree Source)和 DTSI(Device Tree Source Include)是描述硬件设备树的文件格式。它们本质上是同一种语法的文件,但在使用上有一定区别。以下是两者的主要差异和用途:

1. 文件类型和用途

  • DTS (Device Tree Source)
    DTS 文件是设备树的主文件,描述了一个具体设备或板子的硬件配置。每个具体的硬件设备都会有一个对应的 DTS 文件,它是系统用来解析设备硬件结构的主要输入。
    例如:board.dts

  • DTSI (Device Tree Source Include)
    DTSI 文件是设备树的包含文件,通常是一个共享的硬件描述片段,供多个 DTS 文件引用。DTSI 文件中定义的是通用或模块化的硬件配置,目的是实现代码复用。
    例如:chip.dtsi


2. 内容层次

  • DTS
    通常定义特定板级硬件相关的配置,例如 GPIO 引脚分配、外设启用等。

    /dts-v1/;
    /include/ "chip.dtsi"/ {model = "Custom Board";compatible = "custom,board";aliases {serial0 = &uart0;};chosen {stdout-path = &uart0;};
    };

  • DTSI
    通常定义 SoC(芯片)级或通用硬件部分的配置,适用于多个设备树文件。

    /dts-v1/;/ {soc {uart0: serial@10000000 {compatible = "ns16550";reg = <0x10000000 0x1000>;clock-frequency = <24000000>;};};
    };


3. 继承和覆盖

DTS 文件通过 /include/ 指令包含 DTSI 文件中的内容,然后可以覆盖其中的属性。

例如:

  • 在 chip.dtsi 中定义了 UART 外设;
  • 在 board.dts 中可以基于 chip.dtsi,启用或修改 UART 的配置。
继承示例

chip.dtsi:

/include/ "chip.dtsi"&uart0 {status = "okay"; // 覆盖为启用
};

board.dts:

/include/ "chip.dtsi"&uart0 {status = "okay"; // 覆盖为启用
};

4. 文件组织

  • DTSI 通常由芯片厂商或 SoC 开发人员提供,用于定义通用部分,例如 CPU、外设等。
  • DTS 通常由板级开发人员创建,用于描述特定开发板或产品的具体硬件配置。

5. 总结对比

属性DTSDTSI
用途定义具体设备或板级配置定义共享或通用硬件配置
作用具体化设备树描述模块化、复用
包含关系可引用多个 DTSI 文件通常不引用其他文件
适用范围针对单个设备/板子针对芯片级或通用配置

通过这种分层结构,可以实现设备树文件的模块化和复用,从而简化开发和维护工作。

QA:如果我是板级工程师,那么我不应该修改dtsi文件,而是只能新增或者修改dts文件?

是的,作为板级工程师,一般不建议直接修改 DTSI 文件,而是通过新增或修改 DTS 文件来完成硬件描述。这样做的原因如下:


为什么不建议修改 DTSI 文件?

  1. DTSI 文件通常由芯片厂商或 BSP 提供

    • DTSI 文件一般描述的是芯片级(SoC 级)的硬件资源和特性,这些内容是通用的,适用于多种不同的开发板或设备。修改 DTSI 可能会影响其他使用相同芯片的项目。
    • 如果您修改了 DTSI 文件,在后续升级厂商提供的 BSP(Board Support Package)时,可能会导致冲突,甚至丢失修改内容。
  2. 分层设计的目的

    • DTSI 文件的作用是描述通用硬件资源,而 DTS 文件是为具体板级定制的。通过继承和覆盖,可以避免直接修改通用内容,从而维护良好的分层结构。
  3. 方便维护和协作

    • 当多个工程师协作开发时,如果每个人都能随意修改 DTSI 文件,会导致难以追踪改动来源,增加协作复杂度。
    • 如果只修改 DTS 文件,改动是板级特有的,容易维护和调试。

正确的做法:通过 DTS 文件实现定制化

如果需要在板级启用或修改某些硬件资源,可以在 DTS 文件中通过继承和覆盖的方式实现。以下是常见情况的处理方式:

1. 启用某些外设

DTSI 文件中通常将外设状态设置为 "disabled",您可以在 DTS 文件中将其改为 "okay"

/include/ "chip.dtsi"&uart0 {status = "okay";  // 启用 UART0pinctrl-names = "default";pinctrl-0 = <&uart0_pins>;
};

2. 添加板级特有的外设

如果板子上有芯片厂商未定义的外设,比如额外的传感器或定制模块,可以直接在 DTS 文件中新增节点,而无需修改 DTSI 文件。

&i2c1 {status = "okay";temp_sensor@48 {compatible = "mycompany,temp-sensor";reg = <0x48>;};
};

3. 覆盖特定配置

如果板级需要调整某些硬件资源(例如 GPIO 引脚或时钟频率),可以在 DTS 中覆盖 DTSI 的默认配置:

&spi0 {status = "okay";cs-gpios = <&gpio1 5 GPIO_ACTIVE_LOW>;  // 修改片选引脚
};

如果修改 DTSI 是必需的情况

尽管一般不建议修改 DTSI 文件,但在以下情况下,可以考虑调整:

  1. 厂商提供的 DTSI 文件存在错误

    如果您确认芯片厂商的 DTSI 文件有问题(如硬件地址或属性错误),可以修复后在项目内使用。
  2. 特定项目的定制需求

    如果您确定该 DTSI 文件仅用于当前项目,且不会影响其他设备或板子,可以直接修改,但需要清楚记录原因。
  3. 实验性调试

    如果某些问题需要快速验证,您可以临时修改 DTSI,但在正式实现时应将更改移到 DTS 文件中。

总结建议

  • 优先修改 DTS 文件:通过覆盖或新增节点实现板级定制。
  • 尽量避免修改 DTSI 文件:保持芯片级硬件描述的通用性。
  • 如需修改 DTSI 文件:确保原因充分,并明确记录,以便后续维护。

通过这种方式,可以既满足项目需求,又维持代码的模块化和可维护性。

 QA:有人说dts和dtsi的关系就像.c文件和.h文件的include关系。这样的说法准确吗?

网上将 DTS 和 DTSI 的关系类比为 .c 文件和 .h 文件的关系,并不完全准确。这种类比可能有助于初学者快速理解它们的引用方式,但实际上两者的作用和结构存在显著差异。


为什么类比不准确?

1. .h 文件与 .c 文件的分工明确
  • .h 文件:主要是接口声明,定义函数、变量或结构体的原型。它不包含具体实现。
  • .c 文件:主要是实现具体功能,编写函数的逻辑代码。

这种分工明确的方式在 DTS 和 DTSI 中并不存在,因为 DTSI 文件不仅包含“声明”内容,还包含许多具体配置(属性和硬件节点),可以直接被系统解析和使用。

2. DTSI 文件包含具体实现

DTSI 文件并不是简单的“声明文件”,而是包含大量具体硬件配置。例如:

uart0: serial@10000000 {compatible = "ns16550";reg = <0x10000000 0x1000>;clock-frequency = <24000000>;status = "disabled";
};

以上代码实际上已经定义了 UART 的硬件地址、寄存器大小和时钟频率,这些是完整的硬件描述,直接参与设备树解析,并非简单的“接口声明”。

3. DTS 和 DTSI 的关系是“继承与覆盖”

DTS 文件从 DTSI 文件中“继承”节点配置,并可以通过覆盖来调整具体的属性值。这种行为更接近面向对象编程中的“继承”关系,而不是简单的“引用”关系。


更贴切的类比是什么?

将 DTSI 比作一个“父类”或“模板”,将 DTS 比作一个“子类”可能更恰当:

  1. DTSI 定义了通用的硬件节点和默认配置,相当于父类提供的通用功能和默认属性。
  2. DTS 则在继承 DTSI 内容的基础上,进一步细化或修改配置,相当于子类对父类进行扩展或覆盖。
示例(继承与覆盖关系)
// chip.dtsi
soc {uart0: serial@10000000 {compatible = "ns16550";reg = <0x10000000 0x1000>;clock-frequency = <24000000>;status = "disabled";  // 默认禁用};
};
// board.dts
/include/ "chip.dtsi"&uart0 {status = "okay";  // 覆盖为启用
};

在这个例子中:

  • chip.dtsi 定义了通用的 UART 硬件节点和属性;
  • board.dts 继承了 chip.dtsi 中的内容,并根据具体板级需求调整状态。

总结:为什么网上的类比有局限性?

  • DTSI 文件不仅仅是“声明”性质,它包含具体实现,而 .h 文件不包含实现。
  • DTS 文件不是从零开始实现所有功能,而是基于 DTSI 的内容进行扩展或覆盖。
  • 它们的关系更接近“模板(父类)”与“实例(子类)”,而不是“接口与实现”。

因此,用 继承与覆盖 来描述 DTS 和 DTSI 的关系,比简单的 .c 和 .h 文件类比更准确,也更符合设备树的实际用法。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/60891.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LinkedHashMap实现LRU

LRU 环境&#xff1a;JDK11 最近接触LRU(Least Recently Used)&#xff0c;即最近最少使用&#xff0c;也称淘汰算法&#xff0c;在JDK中LinkedHashMap有相关实现 LRU的LinkedHashMap实现 LinkedHashMap继承HashMap。所以内存的存储结构和HashMap一样&#xff0c;但是LinkedH…

IDEA部署AI代写插件

前言 Hello大家好&#xff0c;当下是AI盛行的时代&#xff0c;好多好多东西在AI大模型的趋势下都变得非常的简单。 比如之前想画一幅风景画得先去采风&#xff0c;然后写实什么的&#xff0c;现在你只需描述出你想要的效果AI就能够根据你的描述在几分钟之内画出一幅你想要的风景…

27-压力测试

测试目标 & 测试数据 ● 测试目标 ○ 测试集群的读写性能 / 做集群容量规划 ○ 对 ES 配置参数进行修改&#xff0c;评估优化效果 ○ 修改 Mapping 和 Setting&#xff0c;对数据建模进行优化&#xff0c;并测试评估性能改进 ○ 测试 ES 新版本&#xff0c;结合实际场…

4. Spring Cloud Ribbon 实现“负载均衡”的详细配置说明

4. Spring Cloud Ribbon 实现“负载均衡”的详细配置说明 文章目录 4. Spring Cloud Ribbon 实现“负载均衡”的详细配置说明前言1. Ribbon 介绍1.1 LB(Load Balance 负载均衡) 2. Ribbon 原理2.2 Ribbon 机制 3. Spring Cloud Ribbon 实现负载均衡算法-应用实例4. 总结&#x…

vue3【实战】切换全屏【组件封装】FullScreen.vue

效果预览 原理解析 使用 vueUse 里的 useFullscreen() 实现 代码实现 技术方案 vue3 vite UnoCSS vueUse 组件封装 src/components/FullScreen.vue <template><component:is"tag"click"toggle":class"[!isFullscreen ? i-ep:full-sc…

docker:基于Dockerfile镜像制作完整案例

目录 摘要目录结构介绍起始目录package目录target目录sh目录init.sh脚本start.sh脚本stop.sh脚本restart.sh脚本 config目录 步骤1、编写dockerfilescript.sh脚本 2、构件镜像查看镜像 3、保存镜像到本地服务器4、复制镜像文件到指定目录&#xff0c;并执行init.sh脚本5、查看挂…

微澜:用 OceanBase 搭建基于知识图谱的实时资讯流的应用实践

本文作者&#xff1a; 北京深鉴智源科技有限公司架构师 郑荣凯 本文整理自北京深鉴智源科技有限公司架构师郑荣凯&#xff0c;在《深入浅出 OceanBase 第四期》的分享。 知识图谱是一项综合性的系统工程&#xff0c;需要在在各种应用场景中向用户展示经过分页的一度关系。 微…

消息中间件分类

消息中间件&#xff08;Message Middleware&#xff09;是一种在分布式系统中实现跨平台、跨应用通信的软件架构。它基于消息传递机制&#xff0c;允许不同系统、不同编程语言的应用之间进行异步通信。 常见的消息中间件类型包括&#xff1a; 1. JMS&#xff08;Java Message S…

Mac上详细配置java开发环境和软件(更新中)

文章目录 概要JDK的配置JDK下载安装配置JDK环境变量文件 Idea的安装Mysql安装和配置Navicat Premium16.1安装安装Vscode安装和配置Maven配置本地仓库配置阿里云私服Idea集成Maven 概要 这里使用的是M3型片 14.6版本的Mac 用到的资源放在网盘 链接: https://pan.baidu.com/s/17…

[⑧5G NR]: PBCH payload生成

本篇博客记录下5G PBCH信道中payload数据的生成方式。PBCH payload一共32个比特&#xff0c;基本结构如下图&#xff1a; 根据SSB PDU中bchPayloadFlag的值有三种方式得到PBCH payload。 bchPayloadFlag 0&#xff1a;全部32比特由MAC层提供。 bchPayloadFlag 1&#xff1a;M…

预处理(1)(手绘)

大家好&#xff0c;今天给大家分享一下编译器预处理阶段&#xff0c;那么我们来看看。 上面是一些预处理阶段的知识&#xff0c;那么明天给大家讲讲宏吧。 今天分享就到这里&#xff0c;谢谢大家&#xff01;&#xff01;

EEG+EMG学习系列 (2) :实时 EEG-EMG 人机界面的下肢外骨骼控制系统

[TOC]( EEGEMG学习系列(2):实时 EEG-EMG 人机界面的下肢外骨骼控制系统) 论文地址&#xff1a;https://ieeexplore.ieee.org/abstract/document/9084126 论文题目&#xff1a;Real-Time EEG–EMG Human–Machine Interface-Based Control System for a Lower-Limb Exoskeleton …

用指针遍历数组

#include<stdio.h> int main() {//定义一个二维数组int arr[3][4] {{1,2,3,4},{2,3,4,5},{3,4,5,6},};//获取二维数组的指针int (*p)[4] arr;//二维数组里存的是一维数组int[4]for (int i 0; i < 3; i){//遍历一维数组for (int j 0; j <4; j){printf("%d &…

动态规划子数组系列(二) 环形子数组的最大和

题目&#xff1a; 解析&#xff1a; 代码&#xff1a; public int maxSubarraySumCircular(int[] nums) {int sum 0;int n nums.length;int[] f new int[n1];int[] g new int[n1];int ret 0, fmax -0x3f3f3f3f, gmin Integer.MAX_VALUE;for(int i 1; i < n; i)…

element ui 搜索框中搜索关键字标红展示

示例如图 el-select上绑定remote-method属性 <el-select v-model"checkForm.type" filterable remote reserve-keyword :remote-method"remoteMethod" :loading"loading"><el-option v-for"item in options" :key"ite…

LeetCode654.最大二叉树

LeetCode刷题记录 文章目录 &#x1f4dc;题目描述&#x1f4a1;解题思路⌨C代码 &#x1f4dc;题目描述 给定一个不重复的整数数组 nums 。 最大二叉树 可以用下面的算法从 nums 递归地构建: 创建一个根节点&#xff0c;其值为 nums 中的最大值。 递归地在最大值 左边 的 子…

Charles抓https包-配置系统证书(雷电)

1、导出证书 2、下载 主页上传资源中有安装包&#xff0c;免费的 openssl 安装教程自己搜 openssl x509 -subject_hash_old -in charles.pem 3、修改证书名、后缀改成点0 雷电打开root和磁盘写入 4、导入雷电证书根目录 证书拖进去&#xff0c;基本就完成了&#xff…

Java基础——多线程

1. 线程 是一个程序内部的一条执行流程程序中如果只有一条执行流程&#xff0c;那这个程序就是单线程的程序 2. 多线程 指从软硬件上实现的多条执行流程的技术&#xff08;多条线程由CPU负责调度执行&#xff09; 2.1. 如何创建多条线程 Java通过java.lang.Thread类的对象…

【React】状态管理之Zustand

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 状态管理之Zustand引言1. Zustand 的核心特点1.1 简单直观的 API1.2 无需 Provi…

虎扑APP数据采集:JavaScript与AJAX的结合使用

引言 虎扑APP的数据采集涉及到前端和后端的交互&#xff0c;其中AJAX&#xff08;Asynchronous JavaScript and XML&#xff09;技术允许在不重新加载整个页面的情况下&#xff0c;与服务器进行数据交换和更新部分网页内容。这种技术使得数据采集过程更加高效和用户友好。然而…