? ? ?大家好,今天給大家分享一下,linux系統(tǒng)中常見的注冊(cè)函數(shù)register_chrdev_region()、register_chrdev()、 alloc_chrdev_region()的使用方法。
一、函數(shù)包含的頭文件:
分配設(shè)備編號(hào),注冊(cè)設(shè)備與注銷設(shè)備的函數(shù)均在fs.h中申明,如下:
extern int register_chrdev_region(dev_t, unsigned, const char *); //靜態(tài)的申請(qǐng)和注冊(cè)設(shè)備號(hào)?
extern int? alloc_chrdev_region(dev_t, unsigned, const char *);? ? ?//動(dòng)態(tài)的申請(qǐng)注冊(cè)一個(gè)設(shè)備號(hào)
extern int register_chrdev(unsigned int, const char *,struct file_operations *);//int為0時(shí)候動(dòng)態(tài)注冊(cè),非零時(shí)候靜態(tài)注冊(cè)。
extern int unregister_chrdev(unsigned int, const char *);? ?//注銷設(shè)備號(hào)
extern void unregister_chrdev_region(dev_t, unsigned);? ?//注銷設(shè)備號(hào)
二、注冊(cè)設(shè)備號(hào)
靜態(tài)注冊(cè):
使用register_chrdev_region()首先需要定義一個(gè)dev_t變量來作為一個(gè)設(shè)備號(hào),
dev_t? ?dev_num;?
要想注冊(cè)一個(gè)設(shè)備則需要一個(gè)主設(shè)備號(hào)。
根據(jù)主設(shè)備號(hào)獲取設(shè)備號(hào):
dev_num=MKDEV(major,minor);? major是一個(gè)表示設(shè)備號(hào)的主設(shè)備號(hào),minor次設(shè)備號(hào)
注冊(cè):
register_chrdev_region(dev_num,2,"dev_name");
第一個(gè)參數(shù)表示設(shè)備號(hào),第二個(gè)參數(shù)表示注冊(cè)的此設(shè)備數(shù)目,第三個(gè)表示設(shè)備名稱。
動(dòng)態(tài)注冊(cè):
如果我們提前知道設(shè)備的編號(hào),那么就用register_chrdev_region(),但是如果我們不知道呢,我們就使用動(dòng)態(tài)申請(qǐng)?jiān)O(shè)備編號(hào)。
alloc_chrdev_region(&dev_num, minor, 2, "dev_name");
第一個(gè)參數(shù)保存生成的設(shè)備號(hào),第二個(gè)參數(shù)注冊(cè)設(shè)備的數(shù)目,第三個(gè)參數(shù)表示設(shè)備名稱。
根據(jù)設(shè)備號(hào)獲取主設(shè)備號(hào):
dev_major = MAJOR(dev_num);?
三、向內(nèi)核中添加設(shè)備
struct cdev? devno;
cdev_init(&devno,&file_ops); //初始化設(shè)備
devno.owner = THIS_MODULE;? ?//.owner這表示誰擁有你這個(gè)驅(qū)動(dòng)程序,
devno.ops = &mem_fops;
對(duì)于已經(jīng)知道了主設(shè)備號(hào),就用cdev_add(&devno, dev_num,count);來添加設(shè)備
如果是動(dòng)態(tài)申請(qǐng)的設(shè)備號(hào),就用cdev_add(&devno, MKDEV(mem_major, 0), count);
向內(nèi)核添加設(shè)備,第一個(gè)參數(shù)是設(shè)備,第二個(gè)參數(shù)是設(shè)備號(hào),第三個(gè)參數(shù)是要注冊(cè)的次設(shè)備數(shù)目,mem_major在動(dòng)態(tài)申請(qǐng)時(shí)候保存起來了。
四、注銷設(shè)備
注銷設(shè)備時(shí)候,使用unregister_chrdev_region(dev_t, unsigned);第一個(gè)參數(shù)設(shè)備號(hào),和注冊(cè)時(shí)候的要一致,因此如果是動(dòng)態(tài)分配的就需要保存起來,第二個(gè)參數(shù)是次設(shè)備的個(gè)數(shù)。
五、register_chrdev()函數(shù)的不一致
register_chrdev(unsigned int, const char *,struct file_operations *); // 申請(qǐng)注冊(cè)設(shè)備號(hào)以第一個(gè)參數(shù)來辨別動(dòng)態(tài)與靜態(tài)。
1、如果第一個(gè)參數(shù)是0,表示動(dòng)態(tài)的分配給此驅(qū)動(dòng)程序一個(gè)主設(shè)備號(hào),
2、非零時(shí)候,表示備驅(qū)動(dòng)程序向系統(tǒng)申請(qǐng)主設(shè)備號(hào),
第二個(gè)是設(shè)備名,第三個(gè)file_operations,如果是動(dòng)態(tài)分配的,則函數(shù)返回分配的主設(shè)備號(hào)。
對(duì)應(yīng)的使用unregister_chrdev(unsigned int, const char *);來注銷設(shè)備,第一個(gè)參數(shù)是主設(shè)備號(hào),必須和注冊(cè)時(shí)候的主設(shè)備號(hào)一致,如果注冊(cè)時(shí)候是動(dòng)態(tài)的分配的主設(shè)備號(hào),就需要保存起來,第二個(gè)是設(shè)備名。
綜上得出:register_chrdev_region()比register_chrdev()多了一步,就是想內(nèi)核注冊(cè)添加cdev設(shè)備的步驟。
register_chrdev_region()是register_chrdev()的升級(jí)版本。
審核編輯:湯梓紅
評(píng)論
查看更多