Linux中很多設備都是字符設備,使用ls -l查看/dev下的設備,前面帶c的都是字符設備。
字符設備的創建比較容易,而且有一套固定的模式,掌握了模式完全可以“套模板”。更多的精力應該花在業務邏輯的部分。
Linux的每個設備都有一個主設備號和次設備號,創建字符設備第一步就是給它分配設備號。如果是自己用,可以任意給定一個沒有用過的設備號,也可以讓系統自動分配。但是如果要發布給不同的人不同的機器使用,就不能隨便。推薦使用系統自動分配的方式。
下面代碼中根據有沒有給定設備號決定是指定還是自動分配設備號,dev變量里包含了主設備號和次設備號。MKDEV就是將兩個數字合成的。register_chrdev_region()函數注冊字符設備,alloc_chrdev_region()函數自動分配設備號。主設備號是關鍵,次設備號可以看成是該類設備的計數。通過MAJOR()可以得到主設備號。
字符設備一般會創建一個數據結構,里邊包含了cdev結構、設備數據和其他數據,可以根據自己實際需求添加。然后創建該結構的指針。
分配完設備號,接下來給字符設備數據結構分配存儲空間。
創建設備類
初始化字符設備、添加字符設備到內核和創建設備。
這里涉及到一個結構file_operations,這個結構里包含了文件操作函數列表,所有操作這個字符設備的動作函數地址都保存在這個結構里。
結構的定義在頭文件fs.h中,這個結構有很多內容,不過常用的就那么幾個。
如果沒遇到問題,到這里字符設備就創建成功了。如果失敗,就會goto到錯誤處理的地方,這里用goto是因為失敗后要把前面可能申請的資源釋放掉,而且有順序,這里一定要注意。
在exit函數中要有對應的注銷或釋放資源的操作,順序跟創建時相反,后創建的先釋放,先創建的后釋放。
下面要完成的工作就是實現file_operations結構中的函數。對于簡單的字符設備,最常見的操作是open、read、write、ioctl、release等。
open函數這里只是簡單的獲取了一下字符數據結構體的指針。container_of函數很有意思,可以根據結構成員的地址找到結構體數據的地址。
read函數要實現將內核空間的數據傳到用戶空間的功能,copy_to_user()函數就是干這個的,第一個和第三個參數就是read函數的形參,中間是內核的數據。這里的count是字節個數。
write函數實現的功能與read相反,使用copy_from_user()和memdup_user()函數可以實現。
ioctl函數實現一些設備獨有操作的函數,i2c設備和spi設備就大量使用了ioctl。
release函數就是在設備文件關閉時需要做的操作。這里的關閉是指打開該文件的文件描述符個數為0了,如果不為0只會將計數減1而不會真正調用release函數。
具體的實例可以參看Linux源碼中i2c-dev.c中i2c設備驅動的實現。
必要的頭文件:
編譯模塊并插入到內核后,在/dev目錄下會創建對應的設備文件。
在/sys/class下會創建對應的設備類目錄。
ok,以上就是簡單的創建字符設備的過程,通過字符設備可以實現內核與用戶空間的數據交換。學習字符設備的創建也是學習linux驅動開發的第一步。
-
存儲
+關注
關注
13文章
4262瀏覽量
85670 -
Linux
+關注
關注
87文章
11227瀏覽量
208924 -
設備
+關注
關注
2文章
4472瀏覽量
70539 -
字符
+關注
關注
0文章
232瀏覽量
25173 -
函數
+關注
關注
3文章
4305瀏覽量
62430
發布評論請先 登錄
相關推薦
評論