前期知识

  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特殊的设备节点

  1. aliases节点:用于保存其他节点的别名。
  2. chosen节点:该节点并不是一个真的设备,它的主要功能是帮助uboot向内核传递数据,最主要的参数是bootargs参数。

3.3设备节点的命名

  设备节点的命名方式有三种。

  1. node-name{}; ; node-name是结点名称。
  2. node-name@unit-address{}; :unit-address是设备地址或寄存器首地址。
  3. label: node-name@unit-address{}; :label是节点标签,可以使用&label快捷地访问节点。

3.4设备树节点的标准属性

  1. 根节点的compatible属性:用于标识设备树能否与Linux内核匹配,该属性值的一半格式为"厂商,板子名称"
  2. 普通节点的compatible属性:指兼容性。该属性值的一般格式为"厂商,设备驱动名"。如果Linux内核中的匹配表中有与compatible属性中的值相同的值,则该Linux内核可以使用该设备驱动。当驱动的兼容性信息与设备树的compatible属性匹配后,会运行驱动代码里的probe函数。
  3. status属性:标识设备可用(“okay”)还是不可用(“disabled”)。当然也有其他的值。
  4. #address-cells#size-cells属性:用于标明该如何编写reg属性值。#address-cells用于标明reg属性中address所占字长数,size-cells用于标明length所占的字长数。
  5. 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驱动之设备树的基础知识的更多相关文章

  1. 2.Linux系统之硬盘与分区基础知识

    我们是在虚拟机上安装的Linux系统.在安装的过程中,可能会遇到磁盘分区的问题,我们下面简单介绍一下分区的原理. 1.硬盘的基础知识 下面是一块空白的硬盘: 这是一块格式化后的硬盘: 格式化就是,在空 ...

  2. 基于tiny4412的Linux内核移植 -- 设备树的展开

    作者信息 作者: 彭东林 邮箱:pengdonglin137@163.com QQ:405728433 平台简介 开发板:tiny4412ADK + S700 + 4GB Flash 要移植的内核版本 ...

  3. [Windows驱动开发](二)基础知识——数据结构

    本节主要介绍驱动开发的一些基础知识. 1. 驱动程序的基本组成 1.1. 最经常见到的数据结构 a. DRIVER_OBJECT驱动对象 // WDK中对驱动对象的定义 // 每个驱动程序都会有一个唯 ...

  4. 基于tiny4412的Linux内核移植 -- 设备树的展开【转】

    转自:https://www.cnblogs.com/pengdonglin137/p/5248114.html#_lab2_3_1 阅读目录(Content) 作者信息 平台简介 摘要 正文 一.根 ...

  5. Android驱动之设备树简介

    目录 一.    设备树简介    2 1.    问题一:为什么需要设备树?    2 ①名词解释:    2 ②DT详细介绍:    2 ③DTS是DT的源文件,描述Device Tree中的设备 ...

  6. linux驱动之设备模型

    linux 设备驱动模型 inux2.6提供了新的设备模型:总线.驱动.设备.基本关系简要的概括如下: 驱动核心可以注册多种类型的总线. 每种总线下面可以挂载许多设备.(通过kset devices) ...

  7. [Windows驱动开发](三)基础知识——驱动例程

    一.NT式驱动的基本例程 1. 驱动入口函数——DriverEntry // 驱动程序的一般性定义 NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObje ...

  8. 【Linux 驱动】设备驱动程序再理解

    学习设备驱动编程也有一段时间了,也写过了几个驱动程序,因此有对设备驱动程序有了一些新的理解和认识,总结一下.学习设备驱动编程也有一段时间了,也写过了几个驱动程序.因此有对设备驱动程序有了一些新的理解和 ...

  9. Linux 驱动框架---设备文件devfs

    设备文件系统 Linux引入了虚拟文件系统,从而使设备的访问可以像访问普通文件系统一样.因此在内核中描述打开文件的数据inode中的rdev成员用来记录设备文件对应到的设备号.设备文件也由一个对应的f ...

随机推荐

  1. HTML基础-05

    字体 文本颜色:color:red;字体分类: 衬线字体serif --字体宽度各异,有衬线 --Times.Georgia.宋体 无衬线字体sans-serif --字体宽度各异,无衬线 --Hel ...

  2. Java引用类型之软引用(2)

    下面接着上一篇介绍第2阶段和第3阶段的处理逻辑. 2.process_phase2() 第2个阶段移除所有的referent还存活的Reference,也就是从refs_list中移除Referenc ...

  3. C#,js和sql实用技巧选2

    1.为什么"foo".Equals()不是好做法?因为当正确的写法是"foo".Equals(obj.value),却写成了"foo".Eq ...

  4. SpringSecurity权限管理系统实战—一、项目简介和开发环境准备

    目录 SpringSecurity权限管理系统实战-一.项目简介和开发环境准备 SpringSecurity权限管理系统实战-二.日志.接口文档等实现 SpringSecurity权限管理系统实战-三 ...

  5. python基础 Day4

    python Day4 1.列表 列表初识 之前的的三种str.int.bool在有的条件下不够用 str:存储少量的数据. 切片还是对其进行任何操作,获取的内容都是str类型.存储的数据单一. 列表 ...

  6. HDFS的数据流读写数据 (面试开发重点)

    1 HDFS写数据流程 1.1 剖析文件写入 HDFS写数据流程,如图所示 1)客户端通过Distributed FileSystem模块向NameNode请求上传文件,NameNode检查目标文件是 ...

  7. ASP.NET Core 3.1 WebAPI的跨域问题

    1.nuget要加上 Microsoft.AspNetCore.Cors 中间件. 2.在Startup类里先定义一个全局变量. private readonly string AllowSpecif ...

  8. Mysql 5.6创建新用户并授权指定数据库相应权限

    一.环境 Centos 6.9 Mysql 5.6.40 二.步骤 1.使用root用户登陆mysql mysql -uroot -p 输入密码: 2.创建新用户 CREATE USER 'user' ...

  9. maven文件合集

    maven项目目录结构 聚合项目的pom.xml <?xml version="1.0" encoding="UTF-8"?> <projec ...

  10. python爬虫-爬取百度图片

    python爬虫-爬取百度图片(转) #!/usr/bin/python# coding=utf-8# 作者 :Y0010026# 创建时间 :2018/12/16 16:16# 文件 :spider ...