字元裝置驅動開發流程詳解

2021-07-24 15:00:56 字數 3027 閱讀 9003

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 命令載入驅動模組。在除錯...