Linux設(shè)備驅(qū)動(dòng)統(tǒng)一模型解析
1. 設(shè)備樹概念
1.1.設(shè)備樹感性認(rèn)識(shí)
設(shè)備樹(Device Tree),將這個(gè)詞分開就是“設(shè)備”和“樹”,描述設(shè)備樹的文件叫做DTS(Device Tree Source),這個(gè)DTS 文件采用樹形結(jié)構(gòu)描述板級(jí)設(shè)備,比如CPU 數(shù)量、 內(nèi)存基地址、IIC 接口上接了哪些設(shè)備、SPI 接口上接了哪些設(shè)備等等。設(shè)備樹是樹形數(shù)據(jù)結(jié)構(gòu),具有描述系統(tǒng)中設(shè)備的節(jié)點(diǎn)。每個(gè)節(jié)點(diǎn)都有描述所代表設(shè)備特征的鍵值對(duì)。每個(gè)節(jié)點(diǎn)只有一個(gè)父節(jié)點(diǎn),而根節(jié)點(diǎn)則沒有父節(jié)點(diǎn)。
1.2.DTS、DTB、DTC
DTS:設(shè)備樹源碼文件;DTB:將DTS編譯后得到的二進(jìn)制文件;DTC:DTS的編譯工具,其源碼在內(nèi)核的scriptsdtc目錄下;谕瑯觓rm架構(gòu)的CPU有很多,同一個(gè)CPU會(huì)制作很多配置不一的板子,如何正確的編譯所選的板子的DTS文件呢?在內(nèi)核的arch/arm/boot/dts/Makefile中:
dtb-$(CONFIG_ARCH_XXX) += xxx.dtb
dtb-$(CONFIG_ARCH_XXX) += xxx-sip.dtb
dtb-$(CONFIG_ARCH_XXX) += xxx.dtb
dtb-$(CONFIG_ARCH_XXX) += xxx.dtb
例如xxxx的開發(fā)板,只要設(shè)置CONFIG_ARCH_xxx=y(tǒng),所有用到這顆SOC的DTS都會(huì)編譯成DTB。如果后續(xù)還用到了這顆SOC設(shè)計(jì)的開發(fā)板,只要新建一個(gè)DTS文件,并將對(duì)應(yīng)名稱的DTB文件名加到dtb-$(CONFIG_ARCH_xxx)中,在編譯設(shè)備樹時(shí)就會(huì)將DTS編譯為二進(jìn)制的DTB文件。
1.3.Device Tree語法
以下語法分析均以xxx.dts為例。
1.3.1. dtsi頭文件
設(shè)備樹的頭文件擴(kuò)展名為 .dtsi。以xxx.dts為例,其包含以下頭文件。
#include "skeleton.dtsi"
#include xxx.h"
#include "xxx-clocks.dtsi"
#include "xxx-pinctrl.dtsi"
#include "xxx-camera.dtsi"
需要注意的是.dts文件不但可以引用.dtsi文件,還可以引用.h文件和其他的.dts文件。Q1:每一個(gè).dtsi和.dts都有自己的根節(jié)點(diǎn),但是一個(gè)設(shè)備樹文件只允許有一個(gè)根節(jié)點(diǎn),DTC如何處理?將根節(jié)點(diǎn)合并,保留最后一級(jí)的根節(jié)點(diǎn)。包含的頭文件內(nèi)容會(huì)被展開,展開的位置在/memory和/cpus之間。(存疑,只用xxx.dts編譯過)Q2:如果包含過程中有重復(fù)的compatible,DTC怎么處理?編譯時(shí)不會(huì)報(bào)錯(cuò),會(huì)生成兩個(gè)compatible屬性一樣的節(jié)點(diǎn)。
1.3.2. 設(shè)備節(jié)點(diǎn)
設(shè)備樹中的每一個(gè)節(jié)點(diǎn)都按照以下格式命名:
node-name@unit-address
node-name表示節(jié)點(diǎn)名稱,它的長(zhǎng)度范圍應(yīng)該是1~31個(gè)字符,可以由以下的字符組成:
字符說明0~9數(shù)字a-z小寫字母A-Z大寫字母,逗號(hào)(英文).句號(hào)(英文)_下劃線(英文)+加號(hào)-減號(hào)
表 2-1節(jié)點(diǎn)名稱的有效字符
節(jié)點(diǎn)名稱應(yīng)以較低或大寫字符開頭,并應(yīng)描述設(shè)備的一般類別。節(jié)點(diǎn)的單位地址特定于節(jié)點(diǎn)所在的總線類型。它由表2-1中字符集中的一個(gè)或多個(gè)ASCII字符組成。單位地址必須與節(jié)點(diǎn)的reg屬性中指定的第一個(gè)地址匹配。如果節(jié)點(diǎn)沒有reg屬性,則必須省略@unit-address,并且單獨(dú)使用節(jié)點(diǎn)名稱將節(jié)點(diǎn)與樹中相同級(jí)別的其他節(jié)點(diǎn)區(qū)分開來。對(duì)于reg格式和單位地址,特定總線的綁定可能會(huì)指定附加更具體的要求。根節(jié)點(diǎn)沒有節(jié)點(diǎn)名稱或單位地址。它由正斜杠(/)標(biāo)識(shí)。
圖 2-1節(jié)點(diǎn)名稱示例
在圖2-1中,節(jié)點(diǎn)名稱為cpu的兩個(gè)節(jié)點(diǎn)通過uint-address 0和1區(qū)分;節(jié)點(diǎn)名稱為ethernet的兩個(gè)節(jié)點(diǎn)通過uint-address fe002000和fe003000區(qū)分。在設(shè)備樹中經(jīng)常會(huì)看到以下設(shè)備名稱:
watchdog: watchdog@04009800
冒號(hào)前的是節(jié)點(diǎn)標(biāo)簽(label),冒號(hào)后是節(jié)點(diǎn)名稱。引入label的目的是方便訪問節(jié)點(diǎn),可以直接通過&label來訪問這個(gè)節(jié)點(diǎn)。比如上述節(jié)點(diǎn)就可以使用&watchdog來訪問。
1.3.2.1. 通用名稱建議
節(jié)點(diǎn)的名稱應(yīng)該有些通用,反映設(shè)備的功能,而不是其精確的編程模型。如適用,名稱應(yīng)為以下選擇之一:
? adc ? accelerometer
? atm ? audio-codec
? audio-controller ? backlight:
? bluetooth ? bus
? cache-controller ? camera
? can ? charger
? clock: ? clock-controller
? compact-flash ? cpu
? cpus ? crypto
? disk ? display
? dma-controller ? dsp
? eeprom ? efuse:
? mdio ? memory
? memory-controller ? mmc
? mmc-slot ? mouse
? nand-controller ? nvram
? oscillator ? parallel
? pc-card ? pci
? pcie ? phy
? pinctrl ? pmic
? pmu ? port
? ports ? pwm
1.3.2.2. 路徑名稱
通過指定從根節(jié)點(diǎn)到所需節(jié)點(diǎn)的完整路徑(通過所有子節(jié)點(diǎn)),可以唯一識(shí)別devicetree中的節(jié)點(diǎn)。指定設(shè)備路徑的約定是:
/node-name-1/node-name-2/.../node-name-N
例如,在圖2-1中,到cpu#1的設(shè)備路徑為:
/cpus/cpu@1
/為根節(jié)點(diǎn),在保證完整路徑明確的前提下,可以省略u(píng)int-address。
1.3.3. 屬性
設(shè)備樹中的每個(gè)節(jié)點(diǎn)都有描述節(jié)點(diǎn)特性的屬性。屬性由名稱和值組成。
1.3.3.1. 屬性名稱
屬性名稱的長(zhǎng)度范圍應(yīng)該是1~31個(gè)字符,可以由以下的字符組成:
字符說明0~9數(shù)字a-z小寫字母A-Z大寫字母,逗號(hào)(英文).句號(hào)(英文)_下劃線(英文)+加號(hào)?問號(hào)(英文)##號(hào)(hash)
非標(biāo)準(zhǔn)屬性名稱應(yīng)指定唯一的字符串前綴,例如股票代號(hào),用于標(biāo)識(shí)定義該屬性的公司或組織的名稱。示例:
xxx,pin-function = <6>;
fsl,channel-fifo-len
linux,network-index
ibm,ppc-interrupt-server#s
1.3.3.2. 屬性值
屬性值是包含與屬性關(guān)聯(lián)的信息的零或多個(gè)字節(jié)的數(shù)組。
數(shù)值描述、值為空,用于描述bool信息。個(gè)人理解類似于flag參數(shù)、32位整數(shù),采用big-endian格式。示例:32位值0x11223344將在內(nèi)存中表示為:地址 11 地址 + 1 22 地址 + 2 33 地址 + 3 44、表示采用big-endian格式的64位整數(shù)。包括兩個(gè)值,其中第一個(gè)值包含整數(shù)的最有效位,第二個(gè)值包含最小有效位。例如:64位值0x1122334455667788將表示為兩個(gè)單元格:<0x11223344 0x55667788>。、格式特定于屬性,參見屬性定義。、字符串可打印且以空值()結(jié)尾。、一個(gè)值。phandle值是引用設(shè)備樹中另一個(gè)節(jié)點(diǎn)的方法。可被引用的任何節(jié)點(diǎn)都用唯一的定義了phandle屬性數(shù)值。該數(shù)字用于帶有phandle值類型的屬性值。、串聯(lián)在一起的值列表。
big-endian和little-endian(大小端):big-endian:是指低地址端存放高位字節(jié);little-endian:是指高地址端存放低位字節(jié);
1.3.3.3. 標(biāo)準(zhǔn)屬性Compatible(兼容)屬性名稱兼容值值類型<stringlist>描述兼容屬性值由定義設(shè)備特定編程模型的一個(gè)或多個(gè)字符串組成。客戶端程序應(yīng)使用此字符串列表選擇設(shè)備驅(qū)動(dòng)程序。該屬性值包含一個(gè)從最特定到最通用的null終止字符串的串聯(lián)列表。它們?cè)试S設(shè)備表達(dá)其與一系列類似設(shè)備的兼容性,可能允許單個(gè)設(shè)備驅(qū)動(dòng)器與幾個(gè)設(shè)備匹配。推薦的格式是“制造商,型號(hào)”,其中制造商是描述制造商名稱的字符串(如股票代號(hào))。
示例:
compatible =“fsl,mpc8641”,“ns16550”;
在此示例中,操作系統(tǒng)將首先嘗試查找支持fsl,mpc8641-uartmpc8641的設(shè)備驅(qū)動(dòng)程序。如果找不到驅(qū)動(dòng)程序,然后,它將嘗試定位受支持的更通用的ns16550設(shè)備類型驅(qū)動(dòng)程序 。
一般驅(qū)動(dòng)程序文件都會(huì)有個(gè)OF匹配表,此匹配表保存著一些compatible值,如果設(shè)備節(jié)點(diǎn)的 compatible屬性值和OF匹配表中的任何一個(gè)值相等,那么就表示設(shè)備可以使用這驅(qū)動(dòng)。比如在文件drvier/misc/memctrl.c中:
static struct of_device_id_xxx_memctrl_of_match[] = {
{ .compatible = "xxxx,memctrl", },
{},
};
對(duì)應(yīng)的,在arch/arm/boot/dts/xxx.dts中有:
memctrl: memctrl {
compatible = "xxxx,memctrl";
reg = <0x0121B000 0x1044>;
clocks = <&sdram_bandw_clk>, <&mem_axi_clk>;
clock-names = "sdram_bandwidth_clk", "mem_axi_clk";
interrupts = <GIC_SPI INT_SDRAM IRQ_TYPE_LEVEL_HIGH>;
interrupt-controller;
#interrupt-cells = <1>;
};
Model(型號(hào))屬性名稱模型值值類型
描述指定設(shè)備的制造商型號(hào)。推薦的格式為:“制造商,型號(hào)”,其中制造商是描述制造商名稱的字符串(如股票代號(hào))。
示例:
model =“fsl,MPC8349EMITX”;
Phandle(pointer handle)屬性名稱pointer handle值值類型
描述phandle屬性指定設(shè)備樹中唯一節(jié)點(diǎn)的數(shù)字標(biāo)識(shí)符。phandle屬性值被需要引用與該屬性關(guān)聯(lián)的節(jié)點(diǎn)的其他節(jié)點(diǎn)使用。
示例:
pic@10000000 {
phandle = <1>;
interrupt-controller;
};
定義了1的phandle值。另一個(gè)設(shè)備節(jié)點(diǎn)可以引用phandle值為1的pic節(jié)點(diǎn):
another-device-node {
interrupt-parent = <1>;
};
Status屬性名稱狀態(tài)值值類型<string>描述狀態(tài)屬性指示設(shè)備的操作狀態(tài),其有效值如下:"okay":指示設(shè)備可運(yùn)行。"disabled":表明設(shè)備目前尚未運(yùn)行,但未來可能會(huì)運(yùn)行(例如,未插入或關(guān)閉某物)。"fail":表示設(shè)備無法運(yùn)行,在設(shè)備中檢測(cè)到嚴(yán)重錯(cuò)誤,如果不進(jìn)行維修就不太可能運(yùn)行"fail-sss":表示設(shè)備無法運(yùn)行,在設(shè)備中檢測(cè)到嚴(yán)重錯(cuò)誤,如果不進(jìn)行維修就不太可能運(yùn)行,sss部分特定于設(shè)備,并指示檢測(cè)到的錯(cuò)誤情況。#address-cells and #size-cells屬性名稱#address-cells,#size-cells值類型<u32>描述#address-cells和#size-cells屬性可用于設(shè)備樹層次結(jié)構(gòu)中包含子節(jié)點(diǎn)并描述如何解決子設(shè)備節(jié)點(diǎn)的任何設(shè)備節(jié)點(diǎn)。#address-cells屬性定義用于編碼子節(jié)點(diǎn)的reg屬性中地址字段的個(gè)單元格的數(shù)量。#size-cells屬性定義用于編碼子節(jié)點(diǎn)的reg屬性中大小字段的個(gè)單元格的數(shù)量。#address-cells = <1>;
#size-cells = <0>;
表示reg屬性中有一個(gè)u32表示address,沒有表示reg大小的數(shù)據(jù),所以:reg = <0x0>; 即reg的起始地址為0x0,不描述其大小
#address-cells = <1>;
#size-cells = <1>;
表示reg屬性中有一個(gè)u32表示address,有一個(gè)u32表示size,所以:reg = <0x00000000 0x00040000>; 即reg的起始地址為0x00000000,大小是0x00040000
Reg屬性名稱reg值類型<prop-encoded-array> 編碼為任意數(shù)量(地址、長(zhǎng)度)對(duì)描述reg屬性描述設(shè)備資源在其父總線定義的地址空間內(nèi)的地址。這通常意味著內(nèi)存映射IO寄存器塊的偏移和長(zhǎng)度,但在某些總線類型上可能有不同的含義。根節(jié)點(diǎn)定義的地址空間中的地址為cpu真實(shí)地址。該值是一個(gè),由任意數(shù)量的地址和長(zhǎng)度對(duì)組成,<地址長(zhǎng)度>。指定地址和長(zhǎng)度所需的單元格的數(shù)量是總線特定的,由設(shè)備節(jié)點(diǎn)父級(jí)中的#address-cells和#size-cells屬性指定。如果父節(jié)點(diǎn)為#size-cells單元格指定值0,則應(yīng)忽略reg值中的長(zhǎng)度字段。
示例:假設(shè)系統(tǒng)芯片中的設(shè)備包含兩個(gè)寄存器塊,SOC中偏移0x3000的32字節(jié)塊和偏移0xFE00的256字節(jié)塊。reg屬性的編碼如下(假設(shè)#address-cells和#size-cells值為1):
reg=<0x3000 0x20 0xFE00 0x100>;
virtual-reg屬性名稱virtual-reg值類型<u32>描述virtual-reg屬性指定一個(gè)有效地址,該地址映射到設(shè)備節(jié)點(diǎn)的reg屬性中指定的第一個(gè)物理地址。此屬性使引導(dǎo)程序能夠?yàn)榭蛻舳顺绦蛱峁┮言O(shè)置的虛擬到物理映射。Ranges屬性名稱range值類型<empty>或編碼為任意數(shù)量的(子總線地址、父總線地址、長(zhǎng)度)三聯(lián)體描述range屬性提供了一種在總線地址空間(子地址空間)和總線節(jié)點(diǎn)父地址空間(父地址空間)之間定義映射或轉(zhuǎn)換的方法。range屬性值的格式是任意數(shù)量的三聯(lián)體(子總線地址、父總線地址、長(zhǎng)度):1.子總線地址是子總線地址空間內(nèi)的物理地址。表示地址的單元格數(shù)取決于總線,可以通過此節(jié)點(diǎn)(出現(xiàn)range屬性的節(jié)點(diǎn))的#address-cells確定。2. 父總線地址是父總線地址空間中的物理地址。表示父地址的單元格數(shù)取決于總線,可以通過定義父地址空間的節(jié)點(diǎn)的#address-cells屬性確定。3. 長(zhǎng)度指定子地址空間中范圍的大小。表示大小的單元格數(shù)可以根據(jù)該節(jié)點(diǎn)(出現(xiàn)range屬性的節(jié)點(diǎn))的#size-cells確定。如果屬性用值定義,則它指定父地址和子地址空間相同,并且不需要地址轉(zhuǎn)換。如果總線節(jié)點(diǎn)中不存在該屬性,則假設(shè)節(jié)點(diǎn)的子節(jié)點(diǎn)和父地址空間之間不存在映射。
示例:
soc {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
ranges = <0x0 0xe0000000 0x00100000>;
serial {
device_type = "serial";
compatible = "ns16550";
reg = <0x4600 0x100>;
clock-frequency = <0>;
interrupts = <0xA 0x8>;
interrupt-parent = <&ipic>;
};
};
發(fā)表評(píng)論
請(qǐng)輸入評(píng)論內(nèi)容...
請(qǐng)輸入評(píng)論/評(píng)論長(zhǎng)度6~500個(gè)字
最新活動(dòng)更多
-
即日-10.29立即報(bào)名>> 2024德州儀器嵌入式技術(shù)創(chuàng)新發(fā)展研討會(huì)
-
10月31日立即下載>> 【限時(shí)免費(fèi)下載】TE暖通空調(diào)系統(tǒng)高效可靠的組件解決方案
-
即日-11.13立即報(bào)名>>> 【在線會(huì)議】多物理場(chǎng)仿真助跑新能源汽車
-
11月14日立即報(bào)名>> 2024工程師系列—工業(yè)電子技術(shù)在線會(huì)議
-
12月19日立即報(bào)名>> 【線下會(huì)議】OFweek 2024(第九屆)物聯(lián)網(wǎng)產(chǎn)業(yè)大會(huì)
-
即日-12.26火熱報(bào)名中>> OFweek2024中國(guó)智造CIO在線峰會(huì)
推薦專題
- 1 Intel宣布40年來最重大轉(zhuǎn)型:年底前裁員15000人、拋掉2/3房產(chǎn)
- 2 因美封殺TikTok,字節(jié)股價(jià)骨折!估值僅Meta1/5
- 3 宏山激光重磅發(fā)布行業(yè)解決方案,助力智能制造產(chǎn)業(yè)新飛躍
- 4 國(guó)產(chǎn)AI芯片公司破產(chǎn)!白菜價(jià)拍賣
- 5 具身智能火了,但規(guī)模落地還需時(shí)間
- 6 國(guó)產(chǎn)英偉達(dá)們,抓緊沖刺A股
- 7 三次錯(cuò)失風(fēng)口!OpenAI前員工殺回AI編程賽道,老東家捧金相助
- 8 英特爾賦能智慧醫(yī)療,共創(chuàng)數(shù)字化未來
- 9 英偉達(dá)的麻煩在后頭?
- 10 將“網(wǎng)紅”變成“商品”,AI“爆改”實(shí)力拉滿
- 高級(jí)軟件工程師 廣東省/深圳市
- 自動(dòng)化高級(jí)工程師 廣東省/深圳市
- 光器件研發(fā)工程師 福建省/福州市
- 銷售總監(jiān)(光器件) 北京市/海淀區(qū)
- 激光器高級(jí)銷售經(jīng)理 上海市/虹口區(qū)
- 光器件物理工程師 北京市/海淀區(qū)
- 激光研發(fā)工程師 北京市/昌平區(qū)
- 技術(shù)專家 廣東省/江門市
- 封裝工程師 北京市/海淀區(qū)
- 結(jié)構(gòu)工程師 廣東省/深圳市