字元裝置驅動1 乙個簡單的字元裝置驅動示例

2021-09-25 12:24:35 字數 3344 閱讀 3950

1.註冊主次裝置號:register_chrdev_region()和 alloc_chrdev_region()

2.註冊字元裝置驅動:cdev_init()初始化,cdev_add()新增,註冊裝置驅動,cdev_alloc()申請空間,cdev_del()登出驅動

3.建立驅動的裝置檔案:class_create()

#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /**********    巨集定義變數     ***********************************/

#define my_major 230 //代表自己分配的那個裝置號

#define max_minors 1 //次裝置號數量

#define device_name "module_test" //驅動的名字

/**************** 全域性變數 *********************************/

static struct cdev test_cdev; //驅動中重要的乙個結構體變數cdev

static dev_t mydev; //註冊裝置號相關的結構體

static struct class *test_class; //建立驅動裝置檔案相關的結構體變數

static int test_chrdev_open(struct inode *inode, struct file *file)

static ssize_t test_chrdev_write(struct file *file, char __user *buf, size_t count, loff_t *ppos)

static ssize_t test_chardev_reaed(struct file *file, char __user *buf, size_t size, loff_t *ppos)

/***** 驅動的硬體實現函式 ******/

static const struct file_operations test_fops =

;static int __init chrdev_init(void)

//第二步:註冊字元裝置驅動

cdev_init(&test_cdev, &test_fops);

if ((retval = cdev_add(&test_cdev, mydev, max_minors)) != 0)

//第三步:建立驅動的裝置檔案

test_class = class_create(this_module, "cryil_class");

if (is_err(test_class))

device_create(test_class,null,mydev,null,"test"); //test就是將來在/dev中建立的裝置檔名

return 0;

//錯誤處理函式:先**申請的空間,然後刪除驅動

error:

cdev_del(&test_cdev);

unregister_chrdev_region(mydev, max_minors);

return retval;

}static void __exit chardev_exit(void)

module_init(chrdev_init); //驅動的入口,insmod時會呼叫此函式

module_exit(chardev_exit); //驅動的出口,rmmod時會呼叫此函式

module_description("cryil test driver"); //模組的介紹資訊

module_author("cryil"); //模組的作者

module_license("gpl"); //模組的許可證,固定的。

主次裝置號的註冊方法:

1.register_chrdev_region()自己分配:register_chrdev_region(mydev,max_minors,device_name) 。內部是呼叫了__register_chrdev_region函式,不過自己指定了主裝置號

2.alloc_chrdev_region()使用系統分配的主次裝置號:result = alloc_chrdev_region(&mydev, 0, max_minors, device_name),同樣的實際上內部是呼叫了__register_chrdev_region函式,只不過將__register_chrdev_region函式的第乙個引數設定為0,且次裝置號只能從0開始分配。

3.但其實兩個函式其內部都是呼叫了 mkdev()函式,來指定主次裝置號的。

mkdev是將主裝置號和次裝置號轉換成dev_t型別(dev_t型別是unsigned int 型別,32位)它是定義在中的巨集    

形式:mkdev(int major,int minor)    major為主裝置號   minor為次裝置號巨集定義:#define mkdev(major,minor) (((major) << minorbits) | (minor)),成功執行返回dev_t型別的裝置編號,除此之外可以通過major()函式 和minor()函式 來獲得主裝置號和次裝置號。

test.c中未使用cdev_alloc()函式,直接定義乙個cdev結構體型別的變數,而使用cdev_alloc()函式的方法如下:

1.定義乙個dev_t結構體型別的指標: static dev_t *p

2.對結構體指標進行例項化,為其分配記憶體: p = cdev_alloc()

3.後面的cdev_init() cdev_add() 函式就可以直接使用。

優點:cdev結構體型別占用的空間過大,在這裡先定義乙個指標型別的變數,然後再需要使用時動態剛分配記憶體,減少棧的使用。

cdev結構體分析:

struct cdev ;
這是字元裝置驅動中最重要的乙個結構體,包含著絕大多數的資訊。其實註冊驅動的步驟就是填充這個結構體,然後在應用層操縱硬體完成具體的任務時,呼叫其中的函式指標完成具體的操作。

end。。。。。。

Linux裝置驅動之字元裝置 1 建立字元裝置

建立乙個字元裝置並在 dev目錄下建立節點的基本步驟 include include include include include include include include include include include include include include define hell...

簡單的乙個字元裝置驅動

include include include include include include include include include include include include 包含記憶體管理兩個核心函式 include memdev.h static int mem major me...

字元裝置驅動 1

字元裝置驅動 1 成於堅持,敗於止步 linux 字元裝置驅動結構 cdev 結構體 在 linux 2.6 核心中使用 cdev 結構體描述字元裝置,cdev 結構體的定義如 所示。1 struct cdev 2 cdev 結構體的 dev t 成員定義了裝置號,為 32 位,其中高 12 位為主...