字元驅動裝置原理及其相關函式(二)
參看朱有鵬老師嵌入式視屏,第五部分第三章
1、(1)老介面:register_chrdev
(2)新介面:register_chrdev_region/alloc_chrdev_region + cdev
register_chrdev_region/alloc_chrdev_region註冊裝置號的作用,register_chrdev_region的作用是靜態給一個裝置號,alloc_chrdev_region的作用的由系統動態分配一個裝置號;cdev是註冊驅動,與file_operations掛鉤
2、cdev結構體
cdev結構體路徑:kernel/include/linux/cdev.h
(1) 我們關心的有兩個,file_operation結構體、dev_t裝置號
(2)相關函式:cdev_alloc(給結構體建立記憶體空間)、cdev_init(初始化)、cdev_add(像核心中註冊驅動)、cdev_del(登出驅動)
3、函式解析
(1)cdev_init()函式講解
void cdev_init(struct cdev *cdev, const struct file_operations *fops)
引數:*cdev表示cdev結構體,*fops表示file_operations結構體
沒有返回值,作用是初始化cdev結構體、初始化file_operations結構體
(2)cdev_add()函式講解
int cdev_add(struct cdev *p, dev_t dev, unsigned count)
引數:
p表示這個裝置的cdev結構體
dev表示裝置標號
count表示裝置數量
返回值,大於0表示調價失敗,等於0表示新增裝置成功。
(3)int register_chrdev_region(dev_t from,unsigned int count,char*name)
//from為第一個裝置編號,count為連續的裝置個數,即是驅動程式所管理的裝置個數,name為驅動程式名
例項如下:
現假設有一個裝置驅動程式使用的主裝置號是257,次裝置號分別是0,1,2,3
其呼叫
int ret=register_chrdev_region(MKDEV(257,0),4,"demodev");
接下來還要判斷ret返回值,若果返回值大於0,則說明建立裝置號失敗,否則建立成功。
(4)alloc_chrdev_region函式
該函式由系統協助分配裝置號,分配的主裝置號在1-254間
int alloc_chrdev_region(dev_t *dev,unisgned baseminor,unsigned count,const char*name)
//dev僅用於輸出的引數,在成功完成呼叫後將儲存以分配範圍的第一個編號。baseminor所請求的第一個編號,count是連續的分配個數,char為驅動程式名
4、使用class_create()函式和device_create()函式自動建立裝置檔案
問題:之前insmod xxx.ko安裝一個模組之後,還要在命令列中執行【mknod /dev/test c 250 0】去手工建立裝置檔案,這樣非常麻煩。現在要做的就是執行insmod之後,系統自動建立裝置檔案;執行rmmod之後,系統自動刪除裝置檔案。
實現方式, (1)class_create 對應 class_destroy
(2)device_create 對應 device_destroy
5、在chrdev_init中註冊裝置檔案完成之後,用如下程式碼去實現自動建立裝置檔案。建立裝置檔案之後,才可以在應用層去訪問這個裝置。
// 註冊字元裝置驅動完成後,新增裝置類的操作,以讓核心幫我們發信息
// 給udev,讓udev自動建立和刪除裝置檔案
test_class = class_create(THIS_MODULE, "aston_class");
if (IS_ERR(test_class))
return -EINVAL;
// 最後1個引數字串,就是我們將來要在/dev目錄下建立的裝置檔案的名字
// 所以我們這裡要的檔名是/dev/test
device_create(test_class, NULL, mydev, NULL, "test111");
在實驗時,可以看到執行insmod指令之後,直接去/dev目錄下檢視裝置,可以看到裝置是存在的,我們這裡命名裝置為test111
同時ls /sys/class,可以看到目錄中有我們建立的類aston_class.