linux內核模塊編程(四)----字符設備驅動開發幾個關鍵函數分析

先給自己打個廣告,本人的微信公衆號正式上線了,搜索:張笑生的地盤,主要關注嵌入式軟件開發,足球等等,希望大家多多關注,有問題可以直接留言給我,一定盡心盡力回答大家的問題
在這裏插入圖片描述

一 why

前一篇博客《linux內核模塊編程(三)----字符驅動設備開發》,我們初步實現了一個linux內核字符設備驅動,主要是爲了大家參照該驅動程序源碼,學會如何進行字符設備驅動開發,不知道大家是否成功在自己的本地運行起來這個驅動。
今天這篇文章,我們來談談字符設備驅動開發的框架套路,幾個重要的概念和重要內核函數。

二 what

  1. 字符設備驅動框架
    首先我們看一下字符設備驅動的軟件框架,如下。字符設備驅動運行在kernel space,用戶空間通過常規的open,write,read函數調用驅動中對應的xxx_open,xxx_write,xxx_read函數以實現對某個硬件設備的控制
    在這裏插入圖片描述
1. 必須要有一個設備號,用於在衆多設備驅動中進行區分
2. 用戶必須知道設備驅動對應的設備節點(設備文件名)
3. 在linux中一切皆文件,因此對設備的操作被linux封裝成了文件操作,應用空間的open,wrie,read的時候,實際在內核驅動代碼中有對應的xx_open,xx_read,xx_write
  1. 字符設備驅動相關的內核函數
    2.1 申請設備號
// 創建設備號
int register_chrdev(unsigned int major, const char * name, const struct file_operations * fops)
參數1:主設備號
	設備號(32bit dev_t) = 主設備號(12bit) + 次設備號(20bit)
		主設備號 : 表示一類設備 --- 比如:手機上camera
		次設備號 : 表示一類設備中的某一個:前置camera,後置camera
		
		給定的方式有兩種:
			1. 動態--參數1直接填0
			2. 靜態--指定的一個整數,250
參數2:描述設備信息,可以自定義
	/proc/devices 列舉出所有的已經註冊的設備
參數3:文件操作對象 --- 提供open,wrie,read
返回值:正確返回0,錯誤返回負數

有創建就有註銷

static inline void unregister_chrdev(unsigned int major, const char *name)

2.2 創建設備節點
創建設備節點的時候,可以選擇手動創建,也可以選擇自動創建。手動創建一般適合在debug的情況,在一般的驅動中建議採用自動創建設備節點的方式

1. 手動創建---缺點: /dev/目錄中文件都是在內存中,斷電後 /dev/目錄中文件都會消失
	mknod /dev/設備名 類型 主設備號 次設備號
	比如: 
		mknod /dev/char0 c 240 0

2. 自動創建(通過 udev/mdev機制)
	class_create
		#define class_create(owner, name)		\
		({						\
			static struct lock_class_key __key;	\
			__class_create(owner, name, &__key);	\
		})
			struct class *__class_create(struct module *owner, const char *name,
		     struct lock_class_key *key)
		參數1: THIS_MODULE
		參數2:字符串名字,自定義
		返回一個struct class指針


	struct device *device_create(struct class *class, struct device *parent,
		     dev_t devt, void *drvdata, const char *fmt, ...)
		參數1: class_create返回的struct class指針
		參數2:表示父親,一般直接填 NULL
		參數3:表示設備號類型, MKDEV(major, 0)
		參數4:表示私有數據,一般也是直接填NULL
		參數56:可變參數,字符串,表示設備節點的名字
		返回一個struct device指針
  1. 總結
    字符設備驅動開發的一般步驟如下,再次強調一下是在linux內核4.15版本下的總結,可能有些函數接口不一樣
初始化註冊步驟
1. 申請字符設備的資源---申請設備號,通過register_chrdev()函數實現
2. 創建設備節點,通過class_create()device_create()兩個函數實現

當我們卸載某個字符設備驅動時,對應的註銷和註冊是成對出現的,但是記住遵循一個原則,先註冊的後註銷,後註冊的先註銷,步驟如下
1. 先調用device_destroy()---對應函數device_create()
2. 再調用class_destroy()---對應函數class_create()
3. 最後調用unregister_chrdev()---對應函數register_chrdev()

關於一個完整的字符設備驅動程序示例,還請參考《linux內核模塊編程(三)----字符驅動設備開發》,該博客中有示例源碼。後期有可能還是會參照這樣的思路來寫博文,先給出一個示例程序,編譯運行,然後再出一篇博文分析它,或者有可能在一片博文中先給出示例,然後再分析,這樣可能會造成一篇博文較長,不知道大家是否能看完。

三 to be continued

因爲字符設備驅動的目的,是方便用戶空間程序能夠驅動硬件設備工作的,所以下一篇博文會給出如何在用戶空間通過調用字符設備驅動,來控制我們的硬件。

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