當(dāng)前位置:首頁 > 嵌入式 > 嵌入式軟件

作者:李強,華清遠(yuǎn)見嵌入式學(xué)院講師。

在Linux設(shè)備驅(qū)動中,設(shè)備號設(shè)一個很重要的概念和變量。不論是主設(shè)備號,還是次設(shè)備號,在設(shè)備驅(qū)動中都占據(jù)了很重要的地位。那么他在Kernel中是如何操作的?這個數(shù)據(jù)結(jié)構(gòu)都是通過那些函數(shù)可以很容易的在我們寫Linux設(shè)備驅(qū)動模塊時被我們所使用呢?

在include/linux/type.h文件中我們能看到一個關(guān)于dev_t的定義如下:

...

typedef __u32 __kernel_dev_t;

typedef __kernel_fd_set fd_set;

typedef __kernel_dev_t dev_t;

...

從這個定義中我們能看到dev_t是一個無符號的32位的整型。

首先我們需要說明的是,在linux中主次設(shè)備號是放置在一個無符號的32位的整型中,那么這32位整型對于主次設(shè)備號如何分配呢?

從源代碼中我們可以看到,主設(shè)備號占據(jù)12個位,次設(shè)備好占據(jù)20位。這在一定的時期內(nèi),主次設(shè)備號是完全可以滿足系統(tǒng)需要的。

同時在include/linux/kdev_t.h文件中我們能發(fā)現(xiàn)很多函數(shù)或者宏定義的操作都是針對dev_t的。

具體可以看到我們經(jīng)常用到的MAJOR(dev)、MINOR(dev)、MKDEV(ma,mi)。

下面我們就具體分析下這三個我們經(jīng)常用到的宏定義:

#define MINORBITS 20

#define MINORMASK ((1U << MINORBITS) - 1)

#define MAJOR(dev) ((unsigned int) ((dev) >> MINORBITS))

從這個宏定義中我們可以看到其把無符號的32位的整型做位操作運算:右移20位。

在C語言中如果是右移,那么左邊補0,這樣在這32位的整型中通過這個操作就只保留了原先第19位到31位的有效值,而這也正是我們所需要的。

下面我們看下MINOR這個宏定義:

#define MINOR(dev) ((unsigned int) ((dev) & MINORMASK))

要明白這個宏定義的具體是多少,我們需要首先明白宏定義MINORMASK是什么?

我們從前面的宏定義中,我們看到:

#define MINORMASK ((1U << MINORBITS) - 1)

MINORMASK 是1U也就是1左移位20個字節(jié),二進(jìn)制的話就是10000000000000000000,也就是1后面帶20個0。

然后在減1呢,就成了二進(jìn)制11111111111111111111,也就是20個1,十六進(jìn)制的話是0xFFFFF。

好現(xiàn)在我們知道MINORMASK是20個1,也就是十六進(jìn)制0xFFFFF,那么我們在與dev_t做一個位的與運算,就把32位中的前12為置0,保留其后面的20位,也正是我們想要的表是設(shè)備次設(shè)備號的后20個字節(jié)。

好下面我們看下如果我們知道了主設(shè)備號、次設(shè)備號,我們?nèi)绾紊梢粋€dev_t的數(shù)據(jù)結(jié)構(gòu)。

宏定義:

#define MKDEV(ma,mi) (((ma) << MINORBITS) | (mi))

明白了前面我們所說的,其實這個就比較簡單了,把主設(shè)備號左移20位,然后與上次設(shè)備號,就是我們所需要的dev_t的數(shù)據(jù)結(jié)構(gòu)。

那么我們前面所說的關(guān)于dev_t的操作是新的2.6.x系列中的,在之前的2.4.x系列中,由于對設(shè)備號的總共就16個字節(jié),也就是一個短整型,那么一個系統(tǒng)中所能擁有的設(shè)備號就是及其有限的了。

我們看下在老版本中的內(nèi)核中他們的表示:

#define MAJOR(dev) ((dev)>>8)

#define MINOR(dev) ((dev) & 0xff)

#define MKDEV(ma,mi) ((ma)<<8 | (mi))

從中我們可以看出,他是以8為為分界線,高8位為主設(shè)備號,低8位為次設(shè)備號,那么一個8位所能表示的最多也即是255個數(shù)值,那么當(dāng)我們系統(tǒng)中如果擁有的設(shè)備大于這個數(shù)值的時候,在老版本的內(nèi)核中就沒有辦法處理了。

在內(nèi)核實現(xiàn)中還實現(xiàn)了兩個打印的函數(shù),其實也是宏定義:

#define print_dev_t(buffer, dev) \

sprintf((buffer), "%u:%u\n", MAJOR(dev), MINOR(dev))

#define format_dev_t(buffer, dev) \

({ \

sprintf(buffer, "%u:%u", MAJOR(dev), MINOR(dev)); \

buffer; \

})

從代碼中我們可以看出。

第一就是把設(shè)備的主設(shè)備號和次設(shè)備號以字符串的形式存放到buffer中,在使用這個宏定義的時候需要注意的是:

buffer需要提前開辟空間,而且還需要是夠用的空間。

第二所實現(xiàn)的功能和第一個很類似。這兒我們就不具體說明,請參考第一個宏定義的實現(xiàn)。

在這個文件中還有很多的函數(shù),這些函數(shù)的主要功能就是和老版本的內(nèi)核代碼兼容而產(chǎn)生的,比如:

static inline int old_valid_dev(dev_t dev)

{

return MAJOR(dev) < 256 && MINOR(dev) < 256;

}

此函數(shù)是判斷一個dev_t是否可以轉(zhuǎn)換成舊制的dev_t。

static inline u16 old_encode_dev(dev_t dev)

{

return (MAJOR(dev) << 8) | MINOR(dev);

}

把32位的設(shè)備號轉(zhuǎn)換成16位的舊制的設(shè)備號。

其中主要操作為:首先把主設(shè)備號左移8位,為次設(shè)備好空出8位的位置,然后與上次設(shè)備號。

在使用這個函數(shù)的時候需要注意的就是需要首先判斷下32位的設(shè)備號是否可以有效的轉(zhuǎn)換成16位的設(shè)備號。

static inline dev_t old_decode_dev(u16 val)

{

return MKDEV((val >> 8) & 255, val & 255);

}

上面函數(shù)的反操作。

主設(shè)備號右移8位,然后與上255,即8個1。也就是取此變量的低8位,

次設(shè)備號與上255,也是取此變量的低8位即可。

static inline u32 new_encode_dev(dev_t dev)

{

unsigned major = MAJOR(dev);

unsigned minor = MINOR(dev);

return (minor & 0xff) | (major << 8) | ((minor & ~0xff) << 12);

^^^^^^^^^^^^^

次設(shè)備號取其低8位 ^^^^^^^^^^^^^^

主設(shè)備號左移8位。

^^^^^^^^^^^^^^^^^^^^^^^

次設(shè)備號低8位清零,左移12位。

}

static inline dev_t new_decode_dev(u32 dev)

{

unsigned major = (dev & 0xfff00) >> 8;

unsigned minor = (dev & 0xff) | ((dev >> 12) & 0xfff00);

return MKDEV(major, minor);

}

次函數(shù)比較簡單,再次就不多說了,請參考前面的實現(xiàn)。

“本文由華清遠(yuǎn)見http://www.embedu.org/index.htm提供”



華清遠(yuǎn)見

本站聲明: 本文章由作者或相關(guān)機構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫毥谦F公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數(shù)字化轉(zhuǎn)型技術(shù)解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關(guān)鍵字: AWS AN BSP 數(shù)字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動 BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運行,同時企業(yè)卻面臨越來越多業(yè)務(wù)中斷的風(fēng)險,如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報道,騰訊和網(wǎng)易近期正在縮減他們對日本游戲市場的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機 衛(wèi)星通信

要點: 有效應(yīng)對環(huán)境變化,經(jīng)營業(yè)績穩(wěn)中有升 落實提質(zhì)增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競爭力 堅持高質(zhì)量發(fā)展策略,塑強核心競爭優(yōu)勢...

關(guān)鍵字: 通信 BSP 電信運營商 數(shù)字經(jīng)濟

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術(shù)學(xué)會聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會上宣布正式成立。 活動現(xiàn)場 NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會上,軟通動力信息技術(shù)(集團)股份有限公司(以下簡稱"軟通動力")與長三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉