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