基本驅動模型

應用程序使用驅動:

一個設備驅動其實就是一個內核模塊

應用程序使用一個字符設備是通過使用其設備文件來完成的,通過對其設備文件的讀寫來完成對設備的交互:

842584-20151124234354937-217085811.jpg

 

那麼,想要使用字符設備驅動就首先得有一個字符設備文件,創建一個字符設備文件的方式有兩種:

842584-20151124234355890-1470832730.jpg

 

 

驅動初始化

因爲驅動程序是一個內核模塊,所以驅動的初始化操作是放在內核模塊的初始化函數裏:

 

   主要流程如下:

842584-20151124234357249-80895572.jpg

 

下面展示一段示例代碼:

 842584-20151124234402187-1781457910.jpg

842584-20151124234404359-839343434.jpg

 

842584-20151124234406718-1014406329.jpg

 

842584-20151124234407562-1773521861.jpg

 

 

下面來解釋一下這段初始化代碼中的函數和數據結構:

Struct cdev是用來表示設備的結構體,具體實現如下:

842584-20151124234409406-577686238.jpg

 

其中比較重要的就是其中特殊顏色的幾個屬性,設備操作集是指一些操作函數。設備號是用來標示設備的。設備數是用來表示同類型的設備一共有幾個,這幾個設備的主設備號相同,次設備號不同。比如串口1,串口2,它們的主設備號相同,次設備號不同

Cdev有兩種分配方式:

842584-20151124234410062-915929908.jpg

 

 

Det_t類型,指的是設備號。實際爲32位的無符號整型。這個32位無符號整型包含了兩部分,分別是主設備號,和次設備號,它們相互轉化的方式爲:

842584-20151124234413140-1956389234.jpg

 

分配一個設備號的方式有兩種:

842584-20151124234416296-819805339.jpg

 

因爲設備號是一種資源,所以當驅動退出的時候,應該使用unregister_chrdev_region函數釋放掉這個設備號

 

Struct file_operations是一個函數指針的集合,定義的是能在設備上進行的操作,這個結構體裏就是各種函數指針,你需要重新給這些函數指針賦值,來重定向各種文件操作。下面是給這個結構體賦值的語句。

842584-20151124234417812-1075629020.jpg

 

關於上面那種賦值方式只說明兩點:1.無所謂順序。2.注意下面:

842584-20151124234419406-854590578.jpg

 

  

Cedv_init函數使用來初始化cdev結構體的,主要是爲了將操作函數集加入到cdev中。

   842584-20151124234420312-1677907883.jpg

 

  Cdev_add用來向內核註冊一個設備:

842584-20151124234421374-829477975.jpg

 

 

實現設備操作:

一般來說:常用的設備操作有以下幾個:

v int (*open) (struct inode *, struct file *)打開設備,響應open系統

Open設備方法是驅動程序用來爲以後的操作完成初始化準備工作的,在絕大部分驅動程序中,open完成如下工作:

1. 標明設備號。

2. 啓動設備

      解釋一下其中的比較重要的結構體:

  Struct file,在linux系統中,每一個打開的文件關聯一個struct file結構,在內核打開文件的時候創建,在文件關閉後釋放。他的重要成員如下:

  842584-20151124234422687-1377790553.jpg

 

      Struct inode,在linux中,每一個存在於文件系統裏的文件都會關聯一個inode結構(不論有沒有打開),該結構主要記錄物理信息,主要數據結構如下:

  842584-20151124234423374-695954594.jpg

  例子程序如下:

  842584-20151124234426156-1655717071.jpg

v int (*release) (struct inode *, struct file *);關閉設備,響應close系統調用

Release方法要做的就是關閉設備。

下面是示例代碼:

    842584-20151124234428437-1070634024.jpg

v loff_t (*llseek) (struct file *, loff_t, int)重定位讀寫指針,響應lseek系統調用

文件當前讀寫指針重定位:

示例代碼:

842584-20151124234431234-1636668594.jpg

 

 

v ssize_t (*read) (struct file *, char __user *, size_t, loff_t *)從設備讀取數據,響應read系統調用

參數意義如下:

842584-20151124234435077-2145930117.jpg

 

 

Read設備方法通常完成兩件事情:

1. 從設備中讀取數據(屬於硬件訪問類操作)。

2. 將讀取到的數據返回給應用程序。

 

示例代碼:

842584-20151124234439781-731598921.jpg

 

 

842584-20151124234442421-908682780.jpg

 

 

用一張圖說明read函數的工作流程:

842584-20151124234445187-583745974.jpg

 

 

v ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *)向設備寫入數據,響應write系統調用

Write設備方法通常完成兩件事:

1. 從應用程序提供的地址中取出數據,

2. 將數據寫入設備(屬於硬件訪問類操作)。

 

驅動註銷:

從內核中卸載驅動程序的時候,需要使用cdev_del函數來完成字符設備的註銷。

示例代碼:

842584-20151124234446749-518331198.jpg





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章