字元裝置驅動學習(1)

2021-08-04 22:11:24 字數 3740 閱讀 1911

首先,以查詢方式的按鍵驅動開始字元裝置驅動的學習。一.寫出框架:對於驅動的學習,框架思想非常重要

1.1.file_operation:file_operation 結構是乙個字元驅動如何應用程式建立連線. 這個結構, 定義在 linux/fs.h中, 是乙個函式指標的集合. 每個開啟檔案與它自身的函式集合相關連( 通過包含乙個稱為 f_op 的成員, 它指向乙個 file_operations 結構). 這些操作大部分負責實現系統呼叫。

1.2.相關初始化,註冊函式、解除安裝函式

1、首先。要定義cdev結構體:核心在內部使用型別 struct cdev 的結構來代表字元裝置. 在核心呼叫你的裝置操作前, 你編寫分配並註冊乙個或幾個這些結構.

並定義主裝置號、以及dev_t型別的裝置號變數。dev_t型別裝置號通過mkdev巨集獲得。

2、對於裝置號可以根據主裝置號進行靜態申請裝置號(register_chrdev_region())和動態申請裝置號(alloc_chrdev_region()主裝置號為零時動態申請)

3、裝置號申請完成後,將cdev初始化並與file_operation關聯起來,在將我們定義的cdev這個結構體加入核心中cdev鍊錶(在核心裡,有cdev型別的元素的鍊錶,使用cdev與物理裝置及其驅動進行繫結,我們在使用者空間對裝置檔案操作,因為裝置檔案含有主次裝置號,就能找到cdev鍊錶中找到與這個裝置檔案相關的cdev結構體,進而可以使用與它繫結的file_operation中的驅動程式去操作物理裝置)。

4、解除安裝函式:登出字元裝置 cdev_del( &cdev );

登出裝置號 unregister_chrdev_region( dev_t num, 1 );因為裝置號有限,解除安裝驅動時需要登出裝置號。

5、對於以上的初始化、解除安裝函式現在系統還識別不了,需要告知作業系統

module_init(***_init);

module_exit(***_exit);

module_license(「dual bsd/gpl」);//開源協議

6、為了讓載入驅動模組是,系統自己建立裝置檔案,就需要給核心sysfs(乙個虛擬的檔案系統)提供資訊,udev機制,可以自動建立裝置結點,能自動建立的前提是根檔案系統有掛載sysfs虛擬檔案系統,利用mdev/udev機制,根據/sys中的系統資訊自動建立裝置節點。方法:建立乙個class,然後再class下建立乙個裝置class device (具體實現看**)。

二、硬體操作實現

#include 

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define key_driver1_major 0

/*宣告用到的結構體和變數*/

struct cdev key_driver1_cdev;

static

int key_driver1_major = key_driver1_major;

dev_t key_dev_num;//dev_t型別裝置號

static

struct

class *key_drv_class;

static

struct class_device *key_drv_class_dev;

/*用於位址對映*/

volatile

unsigned

long *gpfcon;

volatile

unsigned

long *gpfdat;

volatile

unsigned

long *gpgcon;

volatile

unsigned

long *gpgdat;

#define rgpfcon 0x56000050

#define rgpgcon 0x56000060

static

int key_driver1_open(struct inode *node, struct file *file)

static

int key_driver1_read (struct file * file, char __user * buf, size_t size, loff_t *ppos)

/*檔案操作結構體*/

static

const

struct file_operations key_driver1_fops =

;/*裝置驅動模組載入函式*/

int key_driver1_init(void)

if (result < 0)

return result;

/**進行cdev的初始化,將cdev與key_driver1_fops關聯

*/cdev_init(&key_driver1_cdev, &key_driver1_fops);

key_driver1_cdev.owner = this_module;

key_driver1_cdev.ops = &key_driver1_fops;

err = cdev_add(&key_driver1_cdev, key_dev_num, 1);

if (err)

printk(kern_notice "error %d ", err);

/** 為裝置建立類

* 載入驅動模組時在/sys/class 目錄下自動建立car_class 資料夾

*/key_drv_class = class_create(this_module, "key_driver1");

if(is_err(key_drv_class))

/*建立裝置檔案節點,避免需要手動建立*/

key_drv_class_dev = class_device_create(key_drv_class, null,key_dev_num, null, "key_driver1");

/*將gpio 的物理位址對映到核心空間,*/

gpfcon = (volatile

unsigned

long *)ioremap(rgpfcon, 16);

gpfdat = gpfcon + 1;

gpgcon = (volatile

unsigned

long *)ioremap(rgpgcon, 16);

gpgdat = gpgcon + 1;

return0;}

/*模組解除安裝函式*/

void key_driver1_exit(void)

module_author("maomao");

module_license("dual bsd/gpl");

module_init(key_driver1_init);

module_exit(key_driver1_exit);

字元裝置驅動 1

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

字元裝置驅動1

1 cdev 結構體linux2.6 核心使用 cdev 結構體描述字元裝置 struct cdev cdev 的定義在 其中dev t 定義了裝置號為32位 前12位為主裝置號,後 20位為次裝置號 可以使用如下巨集呼叫來獲得主 次裝置號 major dev t dev minor dev t d...

驅動開發 字元裝置1

函式的呼叫 open syscall define3 sys open char filename,inflag do sys open do file open path openat do tmpfile return fd finish open do dentry open open ino...