Linux驱动之设备树的基础知识
前期知识
1. 如何编写一个简单的Linux驱动(一)——驱动的基本框架
2. 如何编写一个简单的Linux驱动(二)——设备操作集file_operations
3. 如何编写一个简单的Linux驱动(三)——完善设备驱动
前言
在前面的文章中,我们只介绍了如何对驱动和设备节点进行操作,并没有涉及到对具体硬件设备的操作。从本篇开始,将介绍对硬件设备的操作。这里,我们要引入一个新的概念——设备树。
在学习Linux驱动时,我们一般会用到ARM开发板。ARM开发板的厂商有很多,我们熟知的有正点原子、迅为、友善之臂、天嵌等等。我们可以想象这样一种场景,每家开发板厂商都自己开发板载设备的驱动,即使使用同一款处理器,但每款板子的厂商对于板载硬件的定义是不相同的,为了板载硬件能够正常工作,每家厂商都会根据自己的板载硬件来设计不同于其他厂商的驱动,并将其提交到ARM社区,ARM社区再将它们添加到Linux内核。显然,随着使用Linux的设备越来越多,这些驱动就像是一层层的sh*t一样,糊在Linux内核上,导致Linux内核越来越臃肿。
在几年前,ARM社区真的是这么做的,这就惹恼了大神Linus,于是Linus就给ARM社区来了套素质N连。于是,ARM社区学习了PowerPC的模式,把设备从内核中独立出来,形成设备树。
1.什么是设备树
设备树是用来描述板级设备的文件,板子上所有的设备信息都汇集在这一个文件中,如图。
系统总线是设备树的主干;CAN控制器、GPIO控制器等是系统总线的分支;GPIOA、CAN1、IIC1是更进一步的分支;GPIOA1、AT24C02、MCP2515就是具体设备。这样将设备按照类别组成一棵树,就组成了一整棵设备树。我们可以在系统的"proc/device-tree"目录下看到系统的设备树信息。
2.DTS文件和DTSI文件
设备树源文件一般包括两种,dts
文件和dtsi
文件,dtsi文件是dts文件的头文件,此外,dts文件还可以像C语言那样包含.h
格式的头文件。就像下面这样。
//这是一个dts文件
/dts-v1/; //这条语句必须有
#include "xxx.h" //像C语言一样包含.h头文件
#include "xxxx.dtsi" //包含dtsi头文件
...
...
需要注意的是,在dts文件中,文件开始处的/dts-v1/;
语句是必备的。可以看到,dts文件在包含头文件方面和C语言十分相似,都使用#include
。
dtsi文件一般用来描述较为通用的SOC级别的信息,比如CPU信息,外设控制器信息、主频信息等等。而dts文件则用来描述具象化的外设信息,例如要把GPIOA1用作按键,就需要在dts文件中进行描述。
3.设备树源文件分析
3.1根节点和普通节点
/{};
是根节点,其他的node_name{};
是普通节点。当某个结点在多个关联文件中都出现时,不会产生冲突,出现的后者会对前者作为补充;如果后者与前者有相同的属性,则后者的属性会覆盖掉前者的属性。
比如:在dtsi头文件中有对adc的描述
adc: adc@126C0000 {
compatible = "samsung,exynos-adc-v1";
reg = <0x126C0000 0x100>;
interrupt-parent = <&combiner>;
interrupts = <10 3>;
clocks = <&clock CLK_TSADC>;
clock-names = "adc";
#io-channel-cells = <1>;
io-channel-ranges;
samsung,syscon-phandle = <&pmu_system_controller>;
status = "disabled"; //adc不工作
};
可以在dts文件中对adc描述进行追加
&adc {
/*vdd-supply = <&ldo3_reg>;*/
status = "okay"; //覆盖头文件中的status,使能adc
};
3.2特殊的设备节点
aliases
节点:用于保存其他节点的别名。chosen
节点:该节点并不是一个真的设备,它的主要功能是帮助uboot向内核传递数据,最主要的参数是bootargs参数。
3.3设备节点的命名
设备节点的命名方式有三种。
node-name{};
; node-name是结点名称。node-name@unit-address{};
:unit-address是设备地址或寄存器首地址。label: node-name@unit-address{};
:label是节点标签,可以使用&label快捷地访问节点。
3.4设备树节点的标准属性
- 根节点的
compatible
属性:用于标识设备树能否与Linux内核匹配,该属性值的一半格式为"厂商,板子名称"
。 - 普通节点的
compatible
属性:指兼容性。该属性值的一般格式为"厂商,设备驱动名"
。如果Linux内核中的匹配表中有与compatible属性中的值相同的值,则该Linux内核可以使用该设备驱动。当驱动的兼容性信息与设备树的compatible属性匹配后,会运行驱动代码里的probe函数。 status
属性:标识设备可用(“okay”)还是不可用(“disabled”)。当然也有其他的值。#address-cells
和#size-cells
属性:用于标明该如何编写reg属性值。#address-cells用于标明reg属性中address所占字长数,size-cells用于标明length所占的字长数。reg
属性:该属性的格式一般为reg = <address,length, address,length,…>
,address
表示其实地址,length
表示地址长度,一般用于内存中(也可以用于其他设备)。例:
#address-cells = <2>; //起始地址占两个字长
#size-cells = <1>; //地址长度占一个字长
reg = <0x400080,0x600040,0x4000>; //表示0x400080和0x600040是起始地址,地址长度为0x4000
4. 驱动程序如何获取设备树信息
Linux内核的"linux/of.h"
文件中提供了一系列以of
开头的函数,其中包含了可以获取设备树信息的函数。
5.DTS、DTB和DTC
dts是设备树源文件的一种格式,dtb是设备树文件编译后形成的二进制文件的格式,dtc是用来编译设备树文件的编译工具。
Linux驱动之设备树的基础知识的更多相关文章
- 2.Linux系统之硬盘与分区基础知识
我们是在虚拟机上安装的Linux系统.在安装的过程中,可能会遇到磁盘分区的问题,我们下面简单介绍一下分区的原理. 1.硬盘的基础知识 下面是一块空白的硬盘: 这是一块格式化后的硬盘: 格式化就是,在空 ...
- 基于tiny4412的Linux内核移植 -- 设备树的展开
作者信息 作者: 彭东林 邮箱:pengdonglin137@163.com QQ:405728433 平台简介 开发板:tiny4412ADK + S700 + 4GB Flash 要移植的内核版本 ...
- [Windows驱动开发](二)基础知识——数据结构
本节主要介绍驱动开发的一些基础知识. 1. 驱动程序的基本组成 1.1. 最经常见到的数据结构 a. DRIVER_OBJECT驱动对象 // WDK中对驱动对象的定义 // 每个驱动程序都会有一个唯 ...
- 基于tiny4412的Linux内核移植 -- 设备树的展开【转】
转自:https://www.cnblogs.com/pengdonglin137/p/5248114.html#_lab2_3_1 阅读目录(Content) 作者信息 平台简介 摘要 正文 一.根 ...
- Android驱动之设备树简介
目录 一. 设备树简介 2 1. 问题一:为什么需要设备树? 2 ①名词解释: 2 ②DT详细介绍: 2 ③DTS是DT的源文件,描述Device Tree中的设备 ...
- linux驱动之设备模型
linux 设备驱动模型 inux2.6提供了新的设备模型:总线.驱动.设备.基本关系简要的概括如下: 驱动核心可以注册多种类型的总线. 每种总线下面可以挂载许多设备.(通过kset devices) ...
- [Windows驱动开发](三)基础知识——驱动例程
一.NT式驱动的基本例程 1. 驱动入口函数——DriverEntry // 驱动程序的一般性定义 NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObje ...
- 【Linux 驱动】设备驱动程序再理解
学习设备驱动编程也有一段时间了,也写过了几个驱动程序,因此有对设备驱动程序有了一些新的理解和认识,总结一下.学习设备驱动编程也有一段时间了,也写过了几个驱动程序.因此有对设备驱动程序有了一些新的理解和 ...
- Linux 驱动框架---设备文件devfs
设备文件系统 Linux引入了虚拟文件系统,从而使设备的访问可以像访问普通文件系统一样.因此在内核中描述打开文件的数据inode中的rdev成员用来记录设备文件对应到的设备号.设备文件也由一个对应的f ...
随机推荐
- 通过实际案例摸清楚Spring事务传播的行为
@ 目录 事务传播 案例准备 案例解析 1.无事务 2. Propagation.REQUIRED 3. Propagation.SUPPORTS 4. Propagation.MANDATORY 5 ...
- Python | 浅谈并发锁与死锁问题
本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是Python专题的第24篇文章,我们一起来聊聊多线程场景当中不可或缺的另外一个部分--锁. 如果你学过操作系统,那么对于锁应该不陌生. ...
- 解决 Could not resolve type alias 'com.deppon.gis.module.job.server.util.SdoGeometryTypeHandler'. 的办法
单元测试提示下面错误: 核心错误: Failed to parse mapping resource: 'file [D:\490993\安装程序\DPAP2.1\dpap_v2.0.1\dpap_v ...
- 重回OI的第一篇博客
太久没学OI了, 代码都不会写了, 先写一篇BFS练练手, 是我太菜了qwq #include<cstdio> #include<queue> #include<iost ...
- google protocol buffer——protobuf的基本使用和模型分析
这一系列文章主要是对protocol buffer这种编码格式的使用方式.特点.使用技巧进行说明,并在原生protobuf的基础上进行扩展和优化,使得它能更好地为我们服务. 1.什么是protobuf ...
- Kubernetes 的层级命名空间介绍
原文链接:https://fuckcloudnative.io/posts/introducing-hierarchical-namespaces/ 在单个 Kubernetes 集群上安全托管大量用 ...
- (java)剑指offer二维数组中的查找
在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从 上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. pu ...
- <抽奖奇遇>
时间如同指间沙一般,转眼间一个月就过去了,今天是出去抽奖的日子,这种事情本来性格就淡漠的我不想去参和,怎奈老爸非让我去,我也感到很是无奈.我的运气一直都不好,所以就没抱什么希望,就当是出门去看看热闹 ...
- Linux查看系统硬件信息命令汇总
对工作中,经常用的查看系统硬件命令的一个简单总结 1.查看磁盘类型(是否SSD盘)cat /sys/block/sda/queue/rotational注意:命令中的sba是你的磁盘名称,可以通过df ...
- Node.js 学习笔记之四:使用数据库
这部分示例将示范SQLite3.MongoDB这两种不同类型的数据库在 Node.js 中的使用方法.首先,我们要在code目录下执行mkdir 06_database命令来创建用于存放这一组示例的目 ...