# 引言
在當今這個技術高速發展的時代,創造和擁有一項技術資源固然非常牛逼,但如果能很好地整合已有的技術資源,不也很香嗎?
在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文件中。
# 實現
設備樹實現驅動代碼與設備信息相分離。針對驅動開發者而言,如果只是硬件的某些配置信息發生了變化,但沒有驅動邏輯的變化,那么只需要修改設備樹中的內容就能快速實現。很多和實際硬件相關的設備樹文件的開發和修改其實並沒有真正增加多少代碼,因為大部分需要的功能已經在所引用的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驅動功能。