L1. 內(nèi)核驅(qū)動(dòng)注冊(cè)流程

1.申請(qǐng)?jiān)O(shè)備號(hào)

? ? ? ?驅(qū)動(dòng)結(jié)構(gòu)體填充完畢后,需要注冊(cè)到內(nèi)核之中,其中有三種方法來注冊(cè)設(shè)備驅(qū)動(dòng):

(1) 動(dòng)態(tài)注冊(cè)申請(qǐng)?jiān)O(shè)備號(hào) + cdev? 注冊(cè)設(shè)備驅(qū)動(dòng)

? ? ? ?在不知道設(shè)備號(hào)的情況下,通過動(dòng)態(tài)注冊(cè)驅(qū)動(dòng)申請(qǐng)到的設(shè)備號(hào)并存到dev_t 類型中,通過cdev_init將驅(qū)動(dòng)結(jié)構(gòu)體ops賦值給cdev->ops,然后通過cdev_add將cdev結(jié)構(gòu)體與設(shè)備號(hào)關(guān)聯(lián)。

動(dòng)態(tài)注冊(cè)并申請(qǐng)?jiān)O(shè)備號(hào)API:

? ? alloc_chrdev_region(dev_t*dev, unsigned baseminor, unsigned count, constchar *name)

? ? dev:? ? ? ? ? ? ? ?alloc_chrdev_region函數(shù)向內(nèi)核申請(qǐng)下來的設(shè)備號(hào)結(jié)構(gòu)體

? ? baseminor :? ?次設(shè)備號(hào)的起始

? ? count:? ? ? ? ? ? 申請(qǐng)次設(shè)備號(hào)的個(gè)數(shù)

? ? name :? ? ? ? ? ?執(zhí)行cat?/proc/devices顯示的名稱

cdev的使用:

? ? a. 執(zhí)行cdev_init函數(shù),將cdev和file_operations關(guān)聯(lián)起來

? ? b. 使用cdev_add函數(shù),將cdev和設(shè)備號(hào)關(guān)聯(lián)起來

卸載API:

? ? unregister_chrdev_region(dev *dev, int num);

eg:??

? ? 驅(qū)動(dòng)動(dòng)態(tài)設(shè)備號(hào)注冊(cè)實(shí)例:? flashlight_devno為被賦值的結(jié)構(gòu)體變量

1.1 動(dòng)態(tài)注冊(cè)

? ? cdev_init原型

1.2 cdev_init原型

? ? cdev_add原型

1.3 cdev_add原型

? ? cdev卸載API: void cdev_del(structcdev *p)

(2) 靜態(tài)申請(qǐng)?jiān)O(shè)備號(hào) + cdev 注冊(cè)設(shè)備驅(qū)動(dòng)

? ? 在已知驅(qū)動(dòng)主設(shè)備號(hào)的情況下,可以通過靜態(tài)注冊(cè)驅(qū)動(dòng)。其步驟與動(dòng)態(tài)注冊(cè)有些區(qū)別。需要先定義一個(gè)dev_t結(jié)構(gòu)體,然后通過MKDEV將主設(shè)備號(hào)與此設(shè)備號(hào)合成賦值給dev_t。

靜態(tài)注冊(cè)驅(qū)動(dòng)API:

? ? int register_chrdev_region(dev_t*dev, unsigned int count, char *name);

? ? dev: 由已知的主設(shè)備號(hào)合成的設(shè)備號(hào)結(jié)構(gòu)體MKDEV(major,mnior)的返回值

? ? count: 申請(qǐng)此設(shè)備號(hào)個(gè)數(shù)

? ? name: 設(shè)備名 出現(xiàn)在/proc/devices

卸載靜態(tài)注冊(cè)API:

? ? unregister_chrdev_region(dev *dev, int num);

eg.靜態(tài)注冊(cè)獲取設(shè)備號(hào),其中major為已經(jīng)被賦值的變量

1.4 靜態(tài)注冊(cè)驅(qū)動(dòng)

(3) 自動(dòng)識(shí)別靜態(tài)、動(dòng)態(tài)分配

? ? 程序也可以自動(dòng)選擇靜態(tài)或動(dòng)態(tài)分配API:

? ? int register_chrdev(unsigned int num, const char *name,struct file_operations *ops)

? ? num:為0時(shí)動(dòng)態(tài)注冊(cè),非零時(shí)以num為主設(shè)備號(hào)靜態(tài)注冊(cè)。

? ? Name:設(shè)備名

? ? ops: 驅(qū)動(dòng)結(jié)構(gòu)體

卸載API:int unregister_chrdev(unsigned int major, const? char *name)

? ? 與上兩個(gè)注冊(cè)方法不同的是,int register_chrdev會(huì)自動(dòng)將ops與設(shè)備號(hào)關(guān)聯(lián),不用手動(dòng)cdev_init、cdev_add。且當(dāng)創(chuàng)建class節(jié)點(diǎn)需要設(shè)備號(hào)結(jié)構(gòu)體時(shí),需要MKDEV(major,minor)返回值。但是此API較為耗資源。

eg.自動(dòng)識(shí)別靜態(tài)、動(dòng)態(tài)分配

1.5 自動(dòng)識(shí)別注冊(cè)

根據(jù)主次設(shè)備號(hào)獲取設(shè)備號(hào)結(jié)構(gòu)體API:

? ? dev_num=MKDEV(major,minor);? major是一個(gè)表示設(shè)備號(hào)的主設(shè)備號(hào),minor次設(shè)備號(hào)

根據(jù)設(shè)備號(hào)結(jié)構(gòu)體獲取主次設(shè)備號(hào)API:

? ? major = MAJOR(dev_num); 獲取主設(shè)備號(hào)

? ? minor = MINOR(dev_num); 獲取從設(shè)備號(hào)

? ? 設(shè)備注冊(cè)成功后,在/pro/device可查看

2.創(chuàng)建節(jié)點(diǎn)

? ? 設(shè)備注冊(cè)進(jìn)去后,需要?jiǎng)?chuàng)建節(jié)點(diǎn)才可以使驅(qū)動(dòng)被調(diào)用。

? ? 在/sys/class創(chuàng)建節(jié)點(diǎn)類API:

? ? struct class *class_create(structmodule *owner, const char *name)

?? ?owner:模塊所有者

? ? name: 指定類名?? //在/sys/下可見

? ? 在/sys/class/name已知類節(jié)點(diǎn)下創(chuàng)建設(shè)備節(jié)點(diǎn)API:

? ? struct device *device_create(struct class*cls, struct device *parent, dev_t devt, void *drvdata,const char *fmt, ...);

? ? eg.創(chuàng)建節(jié)點(diǎn)

2.1 創(chuàng)建節(jié)點(diǎn)

? ? 注意:/sys/class/xx/device與/dev/device區(qū)別(xx表示設(shè)備類名,device表示設(shè)備名)

? ? 在驅(qū)動(dòng)注冊(cè)成功后,需要軟件創(chuàng)建設(shè)備節(jié)點(diǎn)。在設(shè)備節(jié)點(diǎn)創(chuàng)建成功后,內(nèi)核就會(huì)在/dev/下生成設(shè)備名。其中/dev/下存的是真實(shí)的設(shè)備,/sys/class/xx/存的是設(shè)備節(jié)點(diǎn)名,反映驅(qū)動(dòng)設(shè)備的層次。調(diào)用驅(qū)動(dòng)時(shí)需要將/dev下的設(shè)備作為路徑,也可以通過設(shè)備節(jié)點(diǎn)名再下一級(jí)的節(jié)點(diǎn)傳參。即”/sys/class/xx/device”不能作為調(diào)用路徑,”/dev/device”可以作為調(diào)用路徑。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容