使用cdev_add注册字符设备
在前面已經(jīng)提到設(shè)備號(hào)有主設(shè)備號(hào)和次設(shè)備號(hào),其中主設(shè)備號(hào)表示設(shè)備類?型,對(duì)應(yīng)于確定的驅(qū)動(dòng)程序,具備相同主設(shè)備號(hào)的設(shè)備之間共用同一個(gè)驅(qū)動(dòng)程?序,而用次設(shè)備號(hào)來(lái)標(biāo)識(shí)具體物理設(shè)備。因此在創(chuàng)建字符設(shè)備之前,必須先獲?得設(shè)備的編號(hào)(可能需要分配多個(gè)設(shè)備號(hào))。
在?Linux?2.6?的版本中,用?dev_t?類型來(lái)描述設(shè)備號(hào)(dev_t?是?32?位數(shù)值類型,其?中高?12?位表示主設(shè)備號(hào),低?20?位表示次設(shè)備號(hào))。用兩個(gè)宏?MAJOR?和?MINOR?分別?獲得?dev_t?設(shè)備號(hào)的主設(shè)備號(hào)和次設(shè)備號(hào),而且用?MKDEV?宏來(lái)實(shí)現(xiàn)逆過(guò)程,即組合?主設(shè)備號(hào)和次設(shè)備號(hào)而獲得?dev_t?類型設(shè)備號(hào)。
分配設(shè)備號(hào)有靜態(tài)和動(dòng)態(tài)的兩種方法。靜態(tài)分配(register_chrdev_region()函數(shù))是?指在事先知道設(shè)備主設(shè)備號(hào)的情況下,通過(guò)參數(shù)函數(shù)指定第一個(gè)設(shè)備號(hào)(它的次設(shè)備?號(hào)通常為?0)而向系統(tǒng)申請(qǐng)分配一定數(shù)目的設(shè)備號(hào)。動(dòng)態(tài)分配(alloc_chrdev_region())?是指通過(guò)參數(shù)僅設(shè)置第一個(gè)次設(shè)備號(hào)(通常為?0,事先不會(huì)知道主設(shè)備號(hào))和要分配?的設(shè)備數(shù)目而系統(tǒng)動(dòng)態(tài)分配所需的設(shè)備號(hào)。通過(guò)?unregister_chrdev_region()函數(shù)釋放已分配的(無(wú)論是靜態(tài)的還是動(dòng)態(tài)的)設(shè)?備號(hào)。
在Linux 2.6內(nèi)核中的字符設(shè)備用cdev結(jié)構(gòu)來(lái)描述,其定義如下:
下面一組函數(shù)用來(lái)對(duì)cdev結(jié)構(gòu)進(jìn)行操作: struct?cdev?*cdev_alloc(void);//分配一個(gè)cdev ? void?cdev_init(struct?cdev?*,?const?struct?file_operations?*);//初始化cdev的file_operation ? void?cdev_put(struct?cdev?*p);//?//減少使用計(jì)數(shù) ? //注冊(cè)設(shè)備,通常發(fā)生在驅(qū)動(dòng)模塊的加載函數(shù)中 ? int?cdev_add(struct?cdev?*,?dev_t,?unsigned);? ? //注銷設(shè)備,通常發(fā)生在驅(qū)動(dòng)模塊的卸載函數(shù)中 ? void?cdev_del(struct?cdev?*);??
使用cdev_add注冊(cè)字符設(shè)備前應(yīng)該先調(diào)用register_chrdev_region或alloc_chrdev_region分配設(shè)備號(hào)。register_chrdev_region函數(shù)用于指定設(shè)備號(hào)的情況,alloc_chrdev_region函數(shù)用于動(dòng)態(tài)申請(qǐng)?jiān)O(shè)備號(hào),系統(tǒng)自動(dòng)返回沒(méi)有占用的設(shè)備號(hào)。
int?register_chrdev_region(dev_t?from,?unsigned?count,?const?char?*name)?; ? int?alloc_chrdev_region(dev_t?*dev,unsigned?baseminor,unsigned?count,const?char?*name);?函數(shù)傳入值 | first:要分配的設(shè)備號(hào)的初始值 ?count:要分配(釋放)的設(shè)備號(hào)數(shù)目 ?name:要申請(qǐng)?jiān)O(shè)備號(hào)的設(shè)備名稱(在/proc/devices?和?sysfs?中顯示)? dev:動(dòng)態(tài)分配的第一個(gè)設(shè)備號(hào) |
函數(shù)返回值
??????????????? 成功:0(只限于兩種注冊(cè)函數(shù))
??????????????? 出錯(cuò):?1(只限于兩種注冊(cè)函數(shù))
alloc_chrdev_region申請(qǐng)一個(gè)動(dòng)態(tài)主設(shè)備號(hào),并申請(qǐng)一系列次設(shè)備號(hào)。baseminor為起始次設(shè)備號(hào),count為次設(shè)備號(hào)的數(shù)量。注銷設(shè)備號(hào)(cdev_del)后使用unregister_chrdev_region:
這里講解?2.6?內(nèi)核中的字符設(shè)備的注冊(cè)和注銷過(guò)程。
在?Linux?內(nèi)核中使用?struct?cdev?結(jié)構(gòu)來(lái)描述字符設(shè)備,我們?cè)隍?qū)動(dòng)程序中必?須將已分配到的設(shè)備號(hào)以及設(shè)備操作接口(即為?struct?file_operations?結(jié)構(gòu))賦予?struct?cdev?結(jié)構(gòu)變量。首先使用?cdev_alloc()函數(shù)向系統(tǒng)申請(qǐng)分配?struct?cdev?結(jié)構(gòu),?再用?cdev_init()函數(shù)初始化已分配到的結(jié)構(gòu)并與?file_operations?結(jié)構(gòu)關(guān)聯(lián)起來(lái)。最?后調(diào)用?cdev_add()函數(shù)將設(shè)備號(hào)與?struct??cdev?結(jié)構(gòu)進(jìn)行關(guān)聯(lián)并向內(nèi)核正式報(bào)告新?設(shè)備的注冊(cè),這樣新設(shè)備可以被用起來(lái)了。
如果要從系統(tǒng)中刪除一個(gè)設(shè)備,則要調(diào)用?cdev_del()函數(shù)。
例1.4? cdev_add注冊(cè)字符設(shè)備實(shí)例
代碼見(jiàn)光盤\src\1drivermodel\1-4cdev。核心代碼如下所示:
本例的應(yīng)用層代碼與運(yùn)行結(jié)果同上例。 與50位技術(shù)專家面對(duì)面20年技術(shù)見(jiàn)證,附贈(zèng)技術(shù)全景圖
總結(jié)
以上是生活随笔為你收集整理的使用cdev_add注册字符设备的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 使用register_chrdev注册字
- 下一篇: 字符设备的读写