1.裝置描述結構cdev
驅動模型種類繁多,這就需要我從眾多的模型中提取出他們的一些共性:
a.驅動初始化
a.1 分配裝置描述結構
a.2 初始化裝置描述結構
a.3 註冊裝置描述結構
a.4 硬體初始化
b.實現裝置操作
c.驅動登出
裝置描述結構:
在任何一種驅動模型中,裝置都會用的核心中的一種結構來描述,我們的字元裝置在核心中使用struct cdev 來來描述。
struct cdev ;
檢視/dev目錄下的裝置號:
ls -l /dev
每行的第五,六分別為主次裝置號。
主裝置號將驅動程式與裝置檔案建立聯絡,
次裝置號是讓驅動程式區分串列埠1,串列埠2.區分同型別的裝置。
a.裝置號操作:
linux核心中使用dev_t型別來定義裝置號,dev_t這種型別其實質為32為的unsigned int ,其中高12為為主裝置號,低20為為此裝置號。
1.如何知道主次裝置號。怎麼組合成dev_t型別?
dev_t dev = mkdev
2.如何從dev_t中分解出主次裝置號?
主裝置號=major(dev_t dev)
次裝置號=minor(dev_t dev)
b.裝置號分配:
靜態申請:開發者自己選擇乙個數字作為主裝置號,然後通過函式register_chrdev_region向核心申請使用,缺點:如果申請使用的裝置號已經被核心中的其他驅動使用了,則申請失敗。
動態分配:
使用alloc_chrdev_region由核心分配乙個可用的主裝置號。
優點:因為核心知道哪些號已經被使用了,所以不會導致分配到已經被使用的號 。
c.裝置號登出:
不管使用何種方法分配裝置號,都應該在驅動退出時,使用unregister_chrdev_region函式釋放這些裝置號。
操作函式集
const struct file_operation *ops;充當了乙個對映關係表的作用。
file_operation類似於一張表,將系統呼叫函式,與驅動程式中的函式對應起來。
對應不支援的操作則設定函式指標為null,
struct file_operation dev_fops =
2.字元裝置驅動模型
a.驅動初始化
a.1 分配描述結構:
cdev變數的定義可以採用靜態和動態兩種方法
靜態分配:struct cdev mdev
動態分配:struct cdev *pdev = cdev_alloc();
a.2 初始化描述結構
struct cdev的初始化使用cdev_init函式來完成。
cdev_init(struct cdev *cdev,const struct file_operation *fops)
cdev:待初始化的cdev結構
fops:裝置對應的操作函式集
a.3註冊描述結構
字元裝置的註冊使用cdev_add函式來完成
cdev_add(struct cdev *p,dev_t dev,unsigned count)
p:待新增到核心的字元裝置結構
dev:裝置號
count:該類裝置的裝置個數
a.4硬體初始化
b.實現裝置操作
open release write llseek read (這些操作別名裝置方法)
了解操作什麼時候被呼叫,了解這些操作要完成一些什麼功能?
int (*open)(struct inode*,struct file*):開啟裝置,相應open系統。
int(*release)(struct inode*,struct file*):關閉裝置,響應close系統呼叫。
loff_t(*llseek)(struct file*,loff_t,int):重定位讀寫指標,響應lseek系統呼叫。
ssize_t(*read)(struct file*,char __user*,size_t,loff_t*):從裝置讀取資料,響應read系統呼叫
ssize_t(*write)(struct file*,const char __user*,size_t,loff_t*):向裝置寫入資料,響應write系統呼叫。
struct file:在linux系統中,每乙個開啟的檔案,在核心中都會關聯乙個struct file,它由核心在開啟檔案時建立,在檔案關閉後釋放。
loff_t f_pos /*檔案讀寫指標*/
struct file_operations *f_op/*該檔案所對應的操作*/
struct inode:每乙個檔案系統裡面的檔案都會關聯乙個inode結構,該結構主要用來記錄檔案物理上的資訊,因此,它和代表開啟檔案的file 結構是不同的,乙個檔案沒有被開啟時不會關聯file結構,但是卻會關聯乙個inode結構。
dev_t i_rdev:裝置號。
裝置操作
open :表明次裝置號,啟動裝置。
release:關閉裝置
read:從裝置中讀取資料,將讀取到的資料返回給應用程式。
注意:buff引數是**於使用者空間的指標,這類指標都不能被核心**直接引用,必須使用專門的函式
int copy_from_user(void*to,const_void __user* from,int n)
int copy_to_user(void __user*to,const void *from,int n)
ssize_t (*read) (struct file *filp, char __user *buff, size_t count, loff_t *offp)
引數分析:
filp:與字元裝置檔案關聯的file結構指標, 由核心建立。
buff : 從裝置讀取到的資料,需要儲存到的位置。由read系統呼叫提供該引數。
count: 請求傳輸的資料量,由read系統呼叫提供該引數。
offp: 檔案的讀寫位置,由核心從file結構中取出後,傳遞進來。
驅動登出:
使用函式cdev_del
字元裝置驅動模型
字元裝置是指在i o傳輸過程中以字元為單位進行傳輸的裝置,例如鍵盤,印表機等。cdev結構體 描述乙個字元裝置 struct cdev linux核心提供的一組函式用於操作cdev結構體 void cdev init 初始化cdev成員,建立cdev與file operations的連線 struc...
Linux 字元裝置驅動模型
一。使用字元裝置驅動程式 1.編譯 安裝驅動 在linux系統中,驅動程式通常採用核心模組的程式結構來進行編碼。因此,編譯 安裝乙個驅動程式,其實質就是編譯 安裝乙個核心模組 2.建立裝置檔案 通過字元裝置檔案,應用程式可以使用相應的字元裝置驅動程式來控制字元裝置。建立字元裝置檔案的方法一般有兩種 ...
裝置驅動模型
linux裝置模型中三個很重要的概念就是匯流排 裝置和驅動,即bus,device和driver。它們分別對應的資料結構分別為struct bus type,struct device和struct device driver。struct device 操作函式 註冊 int device reg...