深入探讨Linux驱动开发:Linux设备树

news2024/9/24 7:24:33

文章目录

  • 一、设备树介绍
  • 二、设备树框架
    • 1.设备树框架
    • 2.节点基本格式
    • 3.节点部分属性简介
  • 总结


一、设备树介绍

设备树(Device Tree,简称 DT)是一种在嵌入式系统中描述硬件设备的一种数据结构和编程语言。它用于将硬件设备的配置信息以树形结构的方式进行描述,以便操作系统(如 Linux)可以根据这些信息正确地识别、配置和管理硬件设备。

设备树最初被引入到 Linux 内核中,用于解决硬件平台多样性带来的问题。传统上,Linux 内核在编译时需要包含大量的硬件配置信息,这对于支持多种硬件平台的嵌入式系统来说是不实际的。设备树的引入使得硬件配置信息可以从内核中分离出来,作为一种独立的描述性数据结构进行管理,从而实现了硬件配置的可移植性和灵活性。

设备树通常以 .dts(Device Tree Source)文件的形式存在,它是一种类似于 C 语言的语法,用于描述硬件设备的属性、寄存器地址、中断等信息。.dts 文件经过编译后会生成 .dtb(Device Tree Blob)文件,它是一种二进制格式的设备树表示形式,可以被 Linux 内核加载并解析。

在 Linux 内核启动时,设备树会被加载并传递给内核,供内核使用。内核通过解析设备树可以动态地配置硬件设备,加载对应的驱动程序,并建立设备之间的关联关系。

设备树的使用使得嵌入式系统在支持多种硬件平台时更加灵活和可扩展,同时也提供了一种标准化的描述硬件设备的方式,便于硬件厂商、开发者和社区之间的协作和交流。

在这里插入图片描述
设备树描述硬件资源时有两个特点:

①树的主干就是系统总线,在设备树里面称为“根节点”。IIC控制器、GPIO控制器、SPI控制器等都是接到系统主线上的分支,在设备树里称为“根节点的子节点”。

②设备树可以像头文件(.h文件)那样,一个设备树文件引用另外一个设备树文件, 这样可以实现“代码”的重用。例如多个硬件平台都使用i.MX6ULL作为主控芯片, 那么我们可以将i.MX6ULL芯片的硬件资源写到一个单独的设备树文件里面一般使用“.dtsi”后缀, 其他设备树文件直接使用“# includexxx”引用即可。

DTS、DTC和DTB它们是文档中常见的几个缩写。

  • DTS 是指.dts格式的文件,是一种ASII 文本格式的设备树描述,也是我们要编写的设备树源码,一般一个.dts文件对应一个硬件平台,位于Linux源码的“/arch/arm/boot/dts”目录下。
  • DTC 是指编译设备树源码的工具,一般情况下我们需要手动安装这个编译工具。
  • DTB 是设备树源码编译生成的文件,类似于我们C语言中“.C”文件编译生成“.bin”文件。

二、设备树框架

1.设备树框架

我们可以通过路径imx6ull/bsp/kernel/linux-imx/arch/arm/boot/dts/下可以查看igkboard.dts设备树文件如下:

/dts-v1/;

#include "imx6ull.dtsi"     /*头文件*/

/*设备树根节点*/
/ {
    model = "LingYun IoT System Studio IoT Gateway Board";		/*model属性,用于指定设备的制造商和型号*/
        compatible = "fsl,imx6ull-14x14-evk", "fsl,imx6ull";	/*compatible属性,系统用来决定绑定到设备驱动的关键,用来查找节点的方法之一*/

    	/*根节点的子节点*/
        chosen {
                stdout-path = &uart1;
        };
		
    	/*根节点的子节点*/
        memory@80000000 {
                device_type = "memory";
                reg = <0x80000000 0x20000000>;
        };

    	/*根节点的子节点*/
        reserved-memory {
                #address-cells = <1>;
                #size-cells = <1>;
                ranges;
                 linux,cma {
                        compatible = "shared-dma-pool";
                        reusable;
                        size = <0xa000000>;
                        linux,cma-default;
                };
        };
    
    	/*根节点的子节点*/
    	leds {
                compatible = "gpio-leds";
                pinctrl-names = "default";
                pinctrl-0 = <&pinctrl_gpio_leds>;
                status = "okay";

                sysled {
                        lable = "sysled";
                        gpios = <&gpio4 16 GPIO_ACTIVE_HIGH>;
                        linux,default-trigger = "heartbeat";
                        default-state = "off";
                };
           };
      /*-------------以下内容省略-------------*/

};

/*设备树节点追加内容*/
/*+--------------+
  | Misc Modules |
  +--------------+*/
/*而是向原有节点追加内容*/
&uart1 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_uart1>;
        status = "okay";
};

&pwm1 { /* backlight */
        #pwm-cells = <2>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pwm1>;
        status = "okay";
};

&pwm2 {
        #pwm-cells = <2>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pwm2>;
        status = "okay";
};

我们可见设备文件分三个部分:

  • 头文件,设备树是可以像C语言那样使用“#include”引用“.h”后缀的头文件,也可以引用设备树“.dtsi”后缀的头文件。imx6ull.dtsi由NXP官方提供,是一个imx6ull平台“共用”的设备树文件。
  • 设备树节点,“/ {…};”表示“根节点”,每一个设备树只有一个根节点。不同文件的根节点最终会合并为一个。在根节点内部的“chosen{…}”、memory{…}”、“reserved-memory{…}”、“leds{…}”等字符,都是根节点的子节点。
  • 设备树节点追加内容,子节点比根节点下的子节点多了一个“&”, 这表示该节点在向已经存在的子节点追加数据。本代码中的“&pwm1{…}”、“&uart1{…}”等等追加的目标节点,就是定义在“imx6ul.dtsi”中。imx6ul.dtsi头文件在/arch/arm/boot/dts/imx6ull.dtsi路径下。

设备树由一个根节点和众多子节点组成,子节点也可以继续包含其他节点,也就是子节点的子节点。 设备树的组成很简单,下面我们一起来看看节点的基本格式和节点属性。

2.节点基本格式

设备树节点是一种以树形结构组织的硬件描述文件,描述了嵌入式系统中所有硬件设备的信息,包括设备的类型、地址、中断等信息。设备树节点的基本格式如下:

node-name@address {
  compatible = "compatible-string";
  reg = <address size>;
  interrupt-parent = <&parent-node>;
  interrupts = <irq1 flags1 irq2 flags2 ...>;
  // other properties
};

其中:

  • node-name 是节点的名称,通常与驱动程序中使用的设备名相同;
  • address 是设备的物理地址;
  • compatible-string 表示设备的兼容性信息,通常包含设备的厂商名和设备名;
  • reg 是设备地址的范围;
  • interrupt-parent 是中断控制器节点的引用,表示中断的父节点;
  • interrupts 是中断信息,其中 irqN 是中断号,flagsN 是中断标志,如上升沿触发等;还可以有其他的属性。
  • 节点标签,节点名的简写,当其它位置需要引用时可以使用节点标签来向该节点中追加内容。在imx6ul.dtsi头文件中,节点名“pwm”前面多了个“pwm1”,这个“pwm1”就是我们所说的节点标签。
  • 节点路径,通过指定从根节点到所需节点的完整路径,可以唯一地标识设备树中的节点,“不同层次的设备树节点名字可以相同,同层次的设备树节点要唯一”。类似于我们Windows上的文件,一个路径唯一标识一个文件或文件夹,不同目录下的文件文件名可以相同。
  • 节点属性:节点的“{}”中包含的内容是节点属性,通常情况下一个节点包含多个属性信息, 这些属性信息就是要传递到内核的“板级硬件描述信息”,驱动中会通过一些API函数获取这些信息。

设备树最主要的内容是编写节点的节点属性,通常情况下一个节点代表一个设备。

3.节点部分属性简介

1.compatible属性

compatible属性值由一个或多个字符串组成,有多个字符串时使用“,”分隔开。

设备树中的每一个设备的节点都要有一个compatible属性。系统通过compatible属性决定绑定哪一个设备的设备驱动,是用来查找节点的方法之一,也可以通过节点名或节点路径查找指定节点。

例如系统初始化时会初始化platform总线上的设备时,根据设备节点”compatible”属性和驱动中of_match_table对应的值加载对应的驱动。

2.model属性

model属性用于指定设备的制造商和型号。

3.status属性

状态属性用于指示设备的“操作状态”,通过status可以去禁止设备或者启用设备,默认情况下不设置status属性设备是使能的。

4.#address-cells 和 #size-cells

#size-cells和#address-cells决定了子节点的reg属性中哪些数据是“地址”,哪些数据是“长度”信息。

#address-cells,用于指定子节点reg属性“地址字段”所占的长度(单元格cells的个数)。

#size-cells,用于指定子节点reg属性“大小字段”所占的长度(单元格cells的个数)。

例如#address-cells=2,#address-cells=1,则reg内的数据含义为reg =

, 每个cells是一个32位宽的数字。

5.reg属性

ret属性的书写格式为reg = < cells cells cells cells cells cells…>

reg属性描述设备资源在其父总线定义的地址空间内的地址。通常情况下用于表示一块寄存器的起始地址(偏移地址)和长度, 在特定情况下也有不同的含义。

例如#address-cells = <1>,#address-cells = <1>,reg = <0x9000000 x4000>, 其中0x9000000表示的是地址,0x4000表示的是地址长度,这里的reg属性指定了起始地址为0x9000000,长度为0x4000的一块地址空间。

6.ranges

该属性提供了子节点地址空间和父地址空间的映射(转换)方法,常见格式是 <子地址、父地址、地址长度>。如果父地址空间和子地址空间相同则无需转换。

比如对于#address-cells和#size-cells都为1的话,以ranges=<0x0 0x10 0x20>为例,表示将子地址的从0x0~(0x0 + 0x20)的地址空间映射到父地址的0x10~(0x10 + 0x20)。

7.name和device_type

这两个属性很少用(已经被废弃),不推荐使用。name用于指定节点名,在旧的设备树中它用于确定节点名, 现在我们使用的设备树已经弃用。device_type属性也是一个很少用的属性,只用在CPU和内存的节点上。 如上例中所示,device_type用在了CPU节点。

我们在设备树中添加了一个“led”节点, 正常情况下我们可以从这个节点获取编写led驱动所用到的所有信息,例如led相关控制寄存器地址、 led时钟控制寄存器地址等等。

内核提供了一组函数用于从设备节点获取资源(设备节点中定义的属性)的函数,这些函数以of_开头,称为OF操作函数。


总结

本篇博客主要介绍了设备树(Device Tree)的基本概念和框架。首先,简单介绍了设备树的作用,即为系统中的硬件设备提供描述信息,帮助内核识别和驱动硬件设备。其次,详细介绍了设备树的基本框架,包括节点标签、节点路径和节点属性。其中,节点标签用于表示设备节点的类型和名称,节点路径用于表示设备节点在设备树中的位置,节点属性用于描述设备节点的各种属性信息。最后,针对节点属性,本篇博客简单介绍了一些常见的属性类型和属性值。

总体而言,本篇博客为读者提供了一个基础的设备树入门指南,使读者能够了解设备树的基本概念和框架。读者可在此基础上进一步深入学习设备树,并在实际开发中应用设备树技术。

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

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

相关文章

介绍与评测Intel HLE与RTM技术

HLE&#xff08;即Hardware Lock Elision&#xff0c;硬件锁省略&#xff09;以及RTM&#xff08;即Restricted Transactional Memory&#xff0c;受限的事务性存储器&#xff09;是Intel在x86微架构中所引入的两条指令集系统&#xff0c;它们均属于TSX&#xff08;Transaction…

Unity日记22(携程概念)

目录 学习视频 携程 1异步 2调用方法 3优点 4停止方法 5返回值 实例&#xff1a;每过一秒打印当前运行时间 实例&#xff1a;停止数字打印携程 错误方法&#xff1a;&#xff08;携程只能开一个&#xff09; 参考方法 学习视频 https://www.bilibili.com/video/BV1eu…

什么是轻量云服务器,有哪些优势,适用于什么场景?

​  随着互联网的迅速发展&#xff0c;越来越多的企业选择将自己的业务部署到云服务器上。而轻量级云服务器作为云计算领域的一种新的服务模式&#xff0c;也开始受到越来越多企业的青睐。那么&#xff0c;究竟何为轻量级云服务器?其优势又在哪里?又适用于哪些场景?以下将…

前端--移动端--3移动web开发rem适配布局

目标&#xff1a; 能够适应rem单位 能够使用媒体查询的基本语法 能够使用less的基本语法 能够使用less中的嵌套 能够使用less中的运算 能够使用2种rem适配方案 能够独立完成苏宁移动端首页 目录&#xff1a; rem基础 媒体查询 less基础 rem适配方案 苏宁首页案例…

如何修改AS2接收的文件名?

知行之桥EDI系统的AS2端口&#xff0c;负责接收和发送EDI文件。企业通过AS2端口接收来自交易伙伴的文件时&#xff0c;其文件名会和交易伙伴发出的文件名完全一致&#xff1b;如果交易伙伴发过来的请求中没有文件名或者文件名没有出现在AS2 协议规定的位置&#xff0c;AS2端口会…

K_A33_001 基于STM32等单片机驱动RC522射频卡 读写IC卡 串口显示

K_A33_001 基于STM32等单片机驱动RC522射频卡 读写IC卡 串口显示 所有资源导航一、资源说明二、基本参数参数引脚说明 三、驱动说明时序:对应程序: 四、部分代码说明1、接线引脚定义1.1、STC89C52RCRC522射频模块1.2、STM32F103C8T6RC522射频模块 五、基础知识学习与相关资料下…

Django分页+增删改查

Django分页增删改查 演示 源码下载地址&#xff1a;https://download.csdn.net/download/qq_35622606/87719248 其他小笔记&#xff1a; django-admin.exe startproject mysite python .\manage.py startapp app01 python manage.py makemigrations python manage.py migrate…

Docker系列---Docker Compose | 容器编排 | 理论详解

目录 1.Docker Compose 概述&#xff08;YML&#xff09; 2.Docker Compose 安装 3.Docker Compose 配置常用字段 4.Docker Compose 常用命令 5.基于 Compose 创建 镜像 1.首先安装好Compose 2.使用Dockerfile环境&#xff1a; 1.Docker Compose 概述&#xff08;YML&am…

docker + K8S + Rancher + Harbor的安装

docker K8S Rancher Harbor的安装 1. 系统初始化 关闭防火墙 systemctl stop firewalld禁用防火墙开机自启 systemctl disable firewalld永久-关闭selinux sed -i s/enforcing/disabled/ /etc/selinux/config # 重启 reboot关闭swap分区 # 永久 sed -ri s/.*swap.*/#&/…

重启电脑数据丢失怎么恢复?这篇指南很受用!

案例分享&#xff1a;“你好&#xff0c;我重新启动了我的win10电脑&#xff0c;电脑为什么再次开机后&#xff0c;下载的软件就不见了&#xff1f;不仅如此&#xff0c;我的文档也消失不见了&#xff0c;这令我很困惑。请问重启电脑数据丢失怎么恢复&#xff1f;请大家帮帮我&…

系统分析师考试,信息安全常错题

计算机网络---其他 Stub区域是一种比较特殊的区域&#xff0c;因为它不能像其他区域那样&#xff0c;经过该区域中的ABR接收其他OSPF AS路由。在Stub区域的内部路由器仅需要配置一条到达该区域ABR的默认路由&#xff08;0.0.0.0.0.0.0.0&#xff09;来实现与同一AS中不同区域间…

CloudCompare插件开发之如何设计界面ui与功能实现?

文章目录 0.引言1.使用文件说明2.添加界面ui相关文件到插件目录3.修改工程相关文件并生成4.结果展示 0.引言 CloudCompare源代码编译成功后&#xff0c;即可进行二次开发&#xff0c;可通过修改源码实现二次开发基础功能&#xff08;见&#xff1a;CloudCompare如何进行二次开发…

#mysql binlog 备份恢复数据流程#

模式&#xff1a;mysql全量备份binlog日志完整恢复数据 首先&#xff0c;数据库在误操作之前必须已经开启了binlog日志功能&#xff0c;且binlog日志的保存周期必须大于全备份的时间周期&#xff01; 所谓恢复&#xff0c;就是让将全备份的数据全部恢复后&#xff0c;再使用my…

HTB-Time

HTB-Time 信息收集80端口 立足pericles -> root 信息收集 80端口 有两个功能&#xff0c;一个是美化JSON数据。 一个是验证JSON&#xff0c;并且输入{“abc”:“abc”}之类的会出现报错。 Validation failed: Unhandled Java exception: com.fasterxml.jackson.core.JsonPa…

当⻉借⼒阿⾥云落地云原⽣架构转型,运维降本、效率稳定性双升

作者&#xff1a;当贝技术团队 随着业务飞速发展&#xff0c;当贝的传统 IT 资产也渐显臃肿&#xff0c;为了避免制约发展的瓶颈&#xff0c;痛定思痛&#xff0c;技术团队果断变革&#xff1a;核心业务云原生化之后&#xff0c;运维效率、整体稳定性和研发效率均得到了全面提…

网络基础知识

网络基础知识 一、什么是二层互通与三层互通&#xff1f;1.1 二层网络互通1.2 三层网络互通 二、什么是Overlay网络&#xff1f;2.1 Underlay网络2.2 Overlay网络2.3 Underlay网络 vs Overlay网络 三、什么是SNMP&#xff1f;3.1 SNMP概念3.2 为什么需要SNMP&#xff1f;3.3 SN…

基于ubuntu18.04.6 LTS服务器安装nvidia驱动

1对于一个刚刚配置的服务器&#xff0c;首先nvidia-smi&#xff0c;自然无法显示Driver Version、最高cuda版本等信息。 nvidia-smi: command not found 需要我们自己安装nvidia驱动 2禁用老驱动 禁用自带nouveau驱动 sudo vim /etc/modprobe.d/blacklist.conf 打开后在CONF文…

本地配置nacos例子

nacos的加载顺序 0、application.properties 1、bootstrap.properties 2、bootstrap-{profile}.properties #本地启动 nacos的配置文件的生成规则&#xff0c;当我正常启动项目时 nacos的配置文件名字生成规则为 ${spring.application.name}.yaml spring:application:name…

面试redis之两大金刚,你懂吗

前言 Redis持久化&#xff0c;一个老掉牙的问题&#xff0c;但是面试官就是喜欢问。这也是我们学Redis必会的一个知识点。Redis作为内存数据库&#xff0c;它工作时&#xff0c;数据都保存在内存里&#xff0c;这也是它为什么很快的一个原因。但存到内存里肯定是有丢数据的风险…

为什么我们能判断声音的远近

想象一下&#xff0c;当我们走在路上时&#xff0c;听到了头顶的鸟儿在树梢间的叫声&#xff0c;即使无法透过浓密的树叶看见它&#xff0c;也可以大致知道鸟儿的距离。此时身后传来由远到近自行车铃铛声&#xff0c;我们并不需要回过头去看&#xff0c;便为它让开了道路。这些…