時間:2018-08-24 00:00:00 來源:信盈達 作者:信盈達
ARM Linux社區(qū)為什么要引入設備樹
Linux之父Linus Torvalds閑來無事,在翻看ARM Linux代碼的時候,有一天終于忍不住了。他在2011年3月17日的ARM Linux郵件列表中說道:“This whole ARM thing is a f*cking pain in the ass”。這句話迫使ARM Linux社區(qū)引入了設備樹。
Linus Torvalds為什么會發(fā)飆呢?而ARM Linux社區(qū)的牛人為什么又乖乖地聽話了?你得首先理解Linux設備驅(qū)動框架中一個非常好的設計:設備信息和驅(qū)動分離。
為了什么說明設備信息和驅(qū)動分離的概念,先來看一個簡單的模擬代碼實例:
【例-1】實現(xiàn)一個代碼,把要使用的信息簡單寫死在代碼中:
int add() /*模擬驅(qū)動代碼*/
{
return 3+5; /*模擬設備信息*/
}
優(yōu)點:簡單
缺點:一旦加數(shù)和被加數(shù)發(fā)生變化就得改代碼
改進設計如下:
【例-2】實現(xiàn)一個代碼,把要使用的信息和操作代碼分離開來:
struct dev{
int id;
int x;
int y;
}; /*模擬設備信息結(jié)構(gòu)*/
strcut drv{
int id;
int (*add)(struct dev *info);
}; /*模擬驅(qū)動結(jié)構(gòu)*/
int add(struct dev *info) /*模擬驅(qū)動代碼*/
{
return info->x + info->y; /*模擬設備信息-通過參數(shù)傳遞進來*/
}
struct drv drv = {
.id = 1,
.add = add,
};
/*模擬設備信息*/
struct dev dev = {
.id = 1,
.x = 3,
.y = 5,
};
/*模擬總線初始化匹配設備信息和驅(qū)動代碼*/
int bus()
{
if(dev.id == drv.id){
return drv.add(&dev);
}
...
}
優(yōu)點:不管加數(shù)和被加數(shù)怎么變化,不需要修改代碼,僅需要修改信息
缺點:結(jié)構(gòu)比較復雜
那這個設備信息和驅(qū)動分離的設計跟驅(qū)動有什么關(guān)系呢?熟悉硬件編程的同學都知道,硬件一般的構(gòu)成可以使用下圖簡單表述:
操作外設的驅(qū)動代碼邏輯,只要硬件是一樣的,就不會變化。但是外設掛到不同的主機上,可能會存在I/O地址的變化,如果有中斷也是一樣的,中斷號也可能不同。這些I/O地址和中斷號就是設備信息,使用這些信息來操作控制硬件的代碼就是驅(qū)動。
如果采用【例-1】的設計方式,那么同一個硬件外設接到不同的主機,或是換了地址線/中斷線,設備信息就變化了,得去修改驅(qū)動。但是采用【例-2】的方式進行設計,問題就迎刃而解:不管同樣的外設硬件接到哪里或是那個平臺,其驅(qū)動代碼邏輯并不需要改動,而僅僅需要改變下設備信息,主要的就是I/O地址和中斷號。
說了這么半天,跟引入設備樹有什么關(guān)系呢?華清教學使用的開發(fā)板(A8/A9)都使用DM9000網(wǎng)卡芯片。DM9000驅(qū)動是開源的,在主線內(nèi)核源碼中就有。我們每次基于A8/A9板子移植的時候,DM9000驅(qū)動并沒有修改過,僅僅是選配了下,主要的工作是在板級文件中添加了設備信息。DM9000驅(qū)動使用的是platform框架,所以添加了一份DM9000網(wǎng)卡芯片的platform_device信息。問題來了,如果使用C代碼的形式來描述設備信息,則在內(nèi)核源碼中,將會有多份DM9000的platform_device設備信息,造成了內(nèi)核代碼冗余。
解決這個問題的辦法就是引入設備樹,改造【例-2】來說明設備樹的作用。
【例-3】實現(xiàn)一個代碼,不僅把要使用的信息和操作代碼分離開來,而且信息不是C代碼編寫的,而是文本配置文件保存的:
struct dev{
int id;
int x;
int y;
}; /*模擬設備信息結(jié)構(gòu)*/
strcut drv{
int id;
int (*add)(struct dev *info);
}; /*模擬驅(qū)動結(jié)構(gòu)*/
int add(struct dev *info) /*模擬驅(qū)動代碼*/
{
return info->x + info->y; /*模擬設備信息-通過參數(shù)傳遞進來*/
}
struct drv drv = {
.id = 1,
.add = add,
};
/*模擬設備樹-一個特殊的配置文件,xxx.dtbs的文本文件*/
/{
......
Dm9000{
x = 3;
y = 5;
};
......
};
/*模擬總線初始化匹配設備信息和驅(qū)動代碼*/
int bus()
{
/*模擬設備樹初始化處理*/
讀文件(xxx.dtbs);
解析文件內(nèi)容(根據(jù)設備樹的規(guī)則來解析);
生成struct dev設備信息;
if(dev.id == drv.id){
return drv.add(&dev);
}
...
}
如果像【例-3】這樣,就可以解決大量設備信息的代碼冗余問題。
推而廣之,系統(tǒng)的軟硬件信息都可以使用設備樹來描述。這樣的話,ARM Linux社區(qū)就不會因為支持板子和驅(qū)動越來越多造成內(nèi)核源碼中出現(xiàn)很多冗余代碼(主要是板級文件),僅僅需要移植者,把系統(tǒng)的軟硬件信息通過設備樹提供出來,選配一下內(nèi)核代碼,就可以了。
信盈達2008年在深圳特區(qū)南山高新科技園成立。自成立至今近九年來專注為企業(yè)和個人提供高端方案設計、高端嵌入式/Android培訓等服務。公司下設信盈達實訓學院、信盈達研發(fā)中心、信盈達教學儀器三大業(yè)務板塊。九年來公司堅持"技術(shù)領(lǐng)先、服務領(lǐng)先",以雄厚的實力和專業(yè)的品質(zhì)成為國內(nèi)唯一有實力從產(chǎn)品最底層研發(fā)到系統(tǒng)層開發(fā)的嵌入式實訓、產(chǎn)品解決方案提供商。為中國IT行業(yè)提供最具價值的職業(yè)教育服務。專業(yè)培訓嵌入式、物聯(lián)網(wǎng)、人工智能、Java、單片機等課程,想了解更多信息點擊立馬咨詢
免費領(lǐng)取試聽卡
申請已經(jīng)提交
老師會馬上給您安排試聽課程!
申請出錯了
您可以加老師QQ:914865590報名咨詢!