设备树的编程思想

# 引言

在当今这个技术高速发展的时代,创造和拥有一项技术资源固然非常牛逼,但如果能很好地整合已有的技术资源,不也很香吗?

在Linux内核源程序中,已经包含了很多各种大牛实现的、稳定的、简洁的驱动程序文件,大部分开发工作其实不是去实现一种新的驱动程序代码,而只要根据硬件设备信息,然后站在大牛的肩膀上稍微做一点点匹配,就能实现功能。

不过初学者初看设备树文件,会习惯性地去参照C语言去理解,但设备树文件也有其自身的特点,照搬一种套路会管中窥豹,如果能凝练出一种编程思想来学习和理解设备树文件,将会带给童鞋们省时省力、豁然开朗的感觉。

现在,准备好了吗?听本人道来。

 

# 概念

设备树的概念自行搜索,此次不再累述,只需知道设备树是一种静态配置文件,通过语法规则形成树状结构,为Linux驱动加载。

 

# 设备树的编程思想

## 属性

属性就是设备树文件中最常出现的表达式形式,也就是属性名=属性值。

 

## 树状结构

设备树是一种描述硬件的数据结构,由一系列节点(node)组成,就是成对的“{}”,大括号中是对节点的描述,也就是属性,而节点本身可包含子节点,从根节点到子节点不断衍生,就像一颗开枝散叶的树。

 

## 抽象

在Linux内核源文件arch/arm/boot/dts路径下会有大量的dts,不同的硬件会对应一个dts,这也是设备树容易让初次接触的人眼花缭乱的地方。但编程的最高境界就是凝练,化繁为简才是精髓。

相同的节点和属性一般会写在一个文件中,考虑到ARM本身就是大家同用的核,因此一定有一些内容是共用的,同一公司的一个系列的ARM有相同的内容,那么可以将共用的部分抽象出来,形成一个设备树头文件(dtsi),其他的不同的文件只需要调用(include)。

那么,要从上到下完整理解一种硬件开发板的设备树结构,可以参考基类与派生的编程思想:相同的部分进行抽象,不同的部分通过继承的实现。

 

## C语法

注释使用/**/,可以屏蔽单行或多行代码,和C语法一致。

每个节点{}后面会跟一个“;”,就像定义了一个结构体。

#include可以加载h文件、dts文件或者dtsi文件,设备树沿用了这部分C语句的语法,在dts和dtsi的文件中大量使用,就是将一些宏定义include到dts文件中。

 

# 实现

设备树的编程思想_第1张图片

设备树实现驱动代码与设备信息相分离。针对驱动开发者而言,如果只是硬件的某些配置信息发生了变化,但没有驱动逻辑的变化,那么只需要修改设备树中的内容就能快速实现。很多和实际硬件相关的设备树文件的开发和修改其实并没有真正增加多少代码,因为大部分需要的功能已经在所引用的dts和基础的dtsi文件语实现。以飞思卡尔的imx6ul核心板为例实现设备树。

从内到外依次是skeleton.dtsi、imx6ul.dtsi、imx6ul-14x14-evk和imx6ul-14x14-evk-emmc.dts。

skeleton.dtsi

设备树头文件

ARM核心共用的一些硬件定义信息

imx6ul.dtsi

设备树头文件

SoC(片上外设)共用的硬件信息

imx6ul-14x14-evk.dts

设备树文件

ARM与相关外设的硬件信息

imx6ul-14x14-evk-emmc.dts

设备树文件

基于eMMC的imx6ul芯片的硬件信息

还包括了7寸屏幕的驱动配置文件imx6ul-14x14-evk-emmc-c-7-1024x600.dts,通过编译形成了imx6ul-14x14-evk-emmc-c-7-1024x600.dtb,同步更新到设备中,让Linux在运行时正确加载和配置了相应的驱动程序,从而实现了预设的功能。

 

# 结论

本文所凝练的分析设备树文件的编程思想,可以在C语法的基础上,通过抽象的方法快速分析一类硬件的设备树文件的语法,可以快速地理解并修改设备树文件,从而帮助初学者用少代码甚至无代码的实现Linux驱动功能。

你可能感兴趣的