1裝置描述結構*
在任何一種驅動模型,字元、網絡卡驅動等,裝置都會用核心的一種結構來描述。我們的字元裝置在核心中使用struct cdev來描述
struct cdev;
**2、裝置號
1主裝置號
字元裝置檔案如何與字元驅動程式建立關係?
通過字元裝置檔案找到字元驅動程式,字元裝置檔案與字元驅動程式對應數字相同,即主裝置號裝置相同
我們建立字元裝置檔案時。cat /proc/devices檢視裝置驅動程式的主裝置號,然後在根據這個主裝置下建立乙個同樣主裝置號的字元裝置檔案,主裝置號反應裝置型別。
2.次裝置號
乙個驅動程式並不是只可以處理乙個裝置,例如開發板上面的3個串列埠只有乙個串列埠驅動程式,但3個串列埠會對應3個不同的裝置檔案,3個裝置檔案的不同之處是次裝置號,不同的次裝置號區分同型別的不同裝置。應用程式帶呼叫3個裝置檔案,所以次裝置號不同,3個裝置檔案需要通過主裝置號訪問同乙個驅動程式,因而主裝置號相同,如果3個裝置檔案沒有其他資訊,則驅動程式也無法區分是哪個檔案,所以不同檔案的次裝置號不同。
3.linux核心中使用dev_t,通過source insight查詢到即為32位的unsigned int, 其中高12位為主裝置號,低20位為次裝置號。
主裝置號和次裝置號組合成dev_t型別
dev_t dev = mkdev(主裝置號,次裝置號);
dev_t分解主裝置號
次裝置號=najor(dev_t dev);
dev_t分解次裝置號
次裝置號=minor(dev_t dev);
**3.裝置號分配
次裝置號可以自己定義,但主裝置分配的不對會造成衝突。
*3.1.靜態申請
開發者自己選擇乙個數字作為主裝置號,然後通過函式register_chrdev_region向核心申請使用。缺點:如果申請
使用的裝置號已經被核心中的其他驅動使用了,則申請失敗。
*3.2動態分配
使用alloc_chrdev_region由核心分配乙個可用的主裝置號。優點:因為核心知道哪些號已經被使用了,所以不會導致分
配到已經被使用的號。
*3.3.裝置號登出
在退出來登出裝置號,unregister_chrdev_region函式釋放裝置號
**4、操作函式集
struct file_operations是乙個函式指標的集合,定義能在裝置上進行操作。結構中的函式指標指向驅動中的函式。
struct file_operations dev_fops;
1.1分配裝置描述結構。字元裝置是cdev
cdev變數的定義採用動態和靜態分配
靜態:struct cdev mdev
動態:struct cdev *pdev = cdev_alloc();
1.2描述結構初始化
struct_cdev的初始化使用cdev_init函式來完成
cdev_init(struct cdev *cdev,const struct file_operation *fops)
引數:
cdev:待初始化的cdev結構
fops:裝置對應的操作函式集5.3
1.3字元裝置註冊
字元裝置註冊使用cdev_add函式來完成
cdev_add(struct cdev *p,dev_t dev,unsigned count)
引數:
p:待新增到核心的字元裝置結構
dev:裝置號
count:該裝置的裝置個數
1.4.硬體初始化
開啟裝置,響應open系統
裝置操作-open
open裝置方法是驅動程式用來為以後的操作完成初始化準備工作的,在大部分驅動程式中,open完成如下工作
標明次裝置號
啟動裝置
關閉裝置,響應close系統呼叫,release方法的作用正好與open相反。這個裝置方法有時也稱為close,它應該:
關閉裝置
重定位讀寫指標,響應lseek系統呼叫
從裝置讀取資料,響應read系統呼叫,read裝置方法通常完成2件事情:
從裝置中讀取資料(屬於硬體訪問類操作)
將讀取到的資料返回給應用程式
引數分析:
filp:與字元裝置檔案關聯的file結構指標, 由核心建立。
buff : 從裝置讀取到的資料,需要儲存到的位置。由read系統呼叫提供該引數。
count: 請求傳輸的資料量,由read系統呼叫提供該引數。
offp: 檔案的讀寫位置,由核心從file結構中取出後,傳遞進來。
buff引數是**於使用者空間的指標,這類指標都不能被核心**直接引用,必須使用專門的函式
int copy_to_user(void __user *to, const void *from, int n)//read使用
向裝置寫入資料,響應write系統呼叫,write裝置方法通常完成2件事情:
從應用程式提供的位址中取出資料
將資料寫入裝置(屬於硬體訪問類操作)
其引數類似於read
int copy_from_user(void *to, const void __user *from, int n)
以上函式裡面都使用了struct file型別,linux系統中,每乙個開啟的檔案,在核心中都會關聯乙個struct file,它由開啟檔案時建立,在檔案關閉後釋放
重要成員:
loff_t f_pos/檔案讀寫指標/
struct file_operation fop/該檔案所對應的操作*/
struct inode
每乙個存在於檔案系統裡面的檔案都會關聯乙個inode結構,該結構主要用來記錄檔案上的資訊,因此,它和代表開啟檔案的file結構是不同的。乙個檔案沒有被開啟時不會關聯file結構,但是卻會關聯乙個inode結果。
重要成員:
devt i_rdev:裝置號
struct inode記錄檔案物理資訊
cdev_del函式來完成字元裝置的登出
字元裝置驅動開發流程
首先要知道 應用程式裡的open close read write等函式在驅動程式也有對應的open close read write等函式,這些函式都有對應的系統編號。如上圖所示在unisd32.件中,read函式對應的系統編號就是3 linux 裡面一切皆檔案,驅動裝置的表現就是乙個 dev 下...
驅動 linux裝置驅動 字元裝置驅動開發
preface 前面對linux裝置驅動的相應知識點進行了總結,現在進入實踐階段!linux 裝置驅動入門篇 linux 裝置驅動掃盲篇 fedora下的字元裝置驅動開發 開發乙個基本的字元裝置驅動 在linux核心驅動中,字元裝置是最基本的裝置驅動。字元裝置包括了裝置最基本的操作,如開啟裝置 關閉...
字元裝置驅動開發
一 驅動模組的載入和解除安裝 linux 驅動有兩種執行方式,第一種就是將驅動編譯進 linux 核心中,這樣當 linux 核心啟動的時候就會自動執行驅動程式。第二種就是將驅動編譯成模組 linux 下模組擴充套件名為 ko 在 linux 核心啟動以後使用 insmod 命令載入驅動模組。在除錯...