核心提供了三個函式來註冊一組字元裝置編號,這三個函式分別是register_chrdev_region()、alloc_chrdev_region()和register_chrdev()。
在linux2.6核心以前註冊字元裝置的函式介面是register_chrdev,登出字元裝置介面函式是unregister_chrdev.
register_chrdev()---老版本字元裝置註冊函式
static inline int register_chrdev(unsigned int major, const char *name, const struct file_opertations * fops)
引數
說明major
表示裝置編號。major=0,則表示採用系統動態分配的主裝置號;不為0,則表示靜態註冊
name
表示裝置名字
fops
在核心內部與驅動裝置掛鉤
返回值:
major值為0,正常註冊後,返回分配的主裝置號。如果分配失敗,返回 ebusy 的負值(-ebusy)。major值若大於linux/major.h(2.4核心)中宣告的最大值(#define max_chrdev255),則返回einval 的負值(-einval)。
指定major值後,若該裝置號已被占用,返回ebusy的負值(-ebusy)。若正常註冊,則返回0值。
unregister_chrdev()--- 老版本字元裝置登出函式
功能:登出裝置
原型:
#include int unregister_chrdev (unsigned int major, const char *name)
說明:
登出裝置驅動程式的核心函式
major主裝置號
name裝置檔案
返回值:
major值若大於linux/major.h(2.4核心)中宣告的最大值 (#define max_chrdev255),返回 einval的負值(-einval)。指定了major的值後,若將要登出的major值並不是註冊的裝置驅動程式,返回einval的負值(-einval)。正常登出則返回0值。
新介面註冊字元裝置驅動需要兩步:
step1:註冊/分配主次裝置號
step2:註冊字元驅動裝置
int register_chrdev_region(dev_t first, unsigned int count, char *name);
引數說明:
引數說明
first
要分配的裝置編號範圍的初始值,這組連續裝置號的起始裝置號,相當於register_chrdefv()中主裝置號
count
連續編號範圍,是這組裝置號的大小(也就是次裝置號個數)
name
編號相關的裝置名稱,(proc/devices);本組裝置的驅動名稱
int alloc_chrdev_region(dev_t *dev,unisgned baseminor,unsigned count,const char*name)
引數說明: 引數
說明dev
系統分配所得的裝置號。可以用major和minor將主次裝置號列印檢視
baseminor
次裝置號的基準,從第幾個裝置號開始分配
count
次裝置號的個數
name
驅動的名字
返回值:分配成功,返回裝置號的第乙個引數;分配錯誤,返回小於零的引數
cdev結構體
cdev是乙個結構體,裡面的成員來共同幫助我們註冊驅動到核心中,表達字元裝置的,將這個struct cdev結構體進行填充,主要填充的內容就是
struct cdev ;
cdev結構體中ops變數讓file_operations結構體變數成為cdev的成員,這個結構體會被cdev_add函式向核心註冊cdev結構體。
cdev結構體,可以用很多函式來操作他。
如:
cdev_alloc:讓核心為這個結構體分配記憶體的
cdev_init:將struct cdev型別的結構體變數和file_operations結構體進行繫結的
cdev_add:向核心裡面新增乙個驅動,註冊驅動
cdev_del:從核心中登出掉乙個驅動。登出驅動
裝置號
(1)dev_t型別(包括了主裝置號和次裝置號 不同的核心中定義不一樣有的是16位次裝置號和16位主裝置號構成 有的是20為次裝置號12位主裝置號 )
(2)mkdev、major、minor三個巨集
mkdev: 是用來將主裝置號和次裝置號,轉換成乙個主次裝置號的。(裝置號)
major: 從裝置號裡面提取出來主裝置號的。
minor巨集:從裝置號中提取出來次裝置號的。
關於裝置檔案的建立
剛開始寫linux裝置驅動程式的時候,很多時候都是利用mknod命令手動建立裝置節點,實際上linux核心為我們提供了一組函式,可以用來在模組載入的時候自動在/dev目錄下建立相應裝置節點,並在解除安裝模組時刪除該節點,當然前提條件是使用者空間移植了udev。
核心中定義了struct class結構體,顧名思義,乙個struct class結構體型別變數對應乙個類, 核心同時提供了class_create(…)函式,可以用它來建立乙個類,這個類存放於sysfs下面,一旦建立好了這個類,再呼叫 device_create(…)函式來在/dev目錄下建立相應的裝置節點。這樣,載入模組的時候,使用者空間中的udev會自動響應 device_create(…)函式,去/sysfs下尋找對應的類從而建立裝置節點。
注意,在2.6較早的核心版本中,device_create(…)函式名稱不同,是class_device_create(…),所以在新的核心中編譯以前的模組程式有時會報錯,就是因為函式名稱不同,而且裡面的引數設定也有一些變化。
struct class和device_create(…) 以及device_create(…)都定義在/include/linux/device.h中,使用的時候一定要包含這個標頭檔案,否則編譯器會報錯。
class_create()
struct class *class_create(struct module *owner, const char *name);
owner 指向擁有這個struct類的模組的指標
name 指向該類名稱的字串指標
device_create()
struct device *device_create(struct class *class, struct device *parent, dev_t devt, const char *fmt, ...)
第乙個引數指定所要建立的裝置所從屬的類
第二個引數是這個裝置的父裝置,如果沒有就指定為null
第三個引數是裝置號
第四個引數是裝置名稱
第五個引數是從裝置號
驅動 linux裝置驅動 字元裝置驅動開發
preface 前面對linux裝置驅動的相應知識點進行了總結,現在進入實踐階段!linux 裝置驅動入門篇 linux 裝置驅動掃盲篇 fedora下的字元裝置驅動開發 開發乙個基本的字元裝置驅動 在linux核心驅動中,字元裝置是最基本的裝置驅動。字元裝置包括了裝置最基本的操作,如開啟裝置 關閉...
Linux裝置驅動之《字元裝置驅動》
linux裝置中最大的特點就是裝置操作猶如檔案操作一般,在應用層看來,硬體裝置只是乙個裝置檔案。應用程式可以像操作檔案一樣對硬體裝置進行操作,如open close read write 等。下面是乙個字元裝置驅動程式的簡單實現test.c 模組分析 1.初始化裝置驅動的結構體 struct fil...
Linux裝置驅動之字元裝置驅動
一 linux裝置的分類 linux系統將裝置分成三種基本型別,每個模組通常實現為其中某一類 字元模組 塊模組或網路模組。這三種型別有 字元裝置 字元裝置是個能夠像位元組流 類似檔案 一樣被訪問的裝置,由字元裝置驅動程式來實現這種特性。字元裝置可以通過檔案系統節點來訪問,比如 dev tty1等。這...