字符設備驅動代碼的編寫

字符設備驅動框架
linux/cdev.h

	cdev結構體:  操作方法集    設備號(主設備號+次設備號)    
	
	圍繞cdev結構體進行的一系列操作:
	    
	0.申請/註冊設備號    
	1.分配cdev結構體    
	2.初始化結構體    
	3.添加cdev到內核 

編寫驅動程序的三種方法

一:傳統方法,優點簡單缺點就是不易寬展,硬件更換了板子都要重新寫代碼重新比編譯,硬件的每次改動都要重新修改軟件版本增加工作量。
二: 總線設備驅動模型,將驅動分爲兩部分,device和driver兩部分掛在platform總線上,device負責指定資源,如管腳等。對於相同的硬件操作driver部分都是相同的,硬件只需要編寫相應的device代碼來指定硬件資源即可。這種方法稍微複雜,但是易擴展,冗餘代碼多且以代碼的形式出現。
三: 設備樹。仍然是分爲兩部分,一是xxx_driver.c跟總線設備驅動模型一樣,二是設備樹文件xxx.dts文件來指定文件,內核根據這個文件來構造xxx_device文件,運行時去讀取解析xxx.dts文件。優點是比傳統方法稍複雜,容易擴展,沒有冗餘代碼,不需要重新編譯內核或者驅動只需要提供不一樣的設備樹文件。

字符設備驅動代碼的編寫*

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/cdev.h>
#include <linux/fs.h>
#define BASEMINOR 0
#define COUNT     3
#define NAME      "cdev_demo"
dev_t devno = 0;
struct cdev *cdevp = NULL;
int demo_open(struct inode *inode, struct file *filp){
	printk(KERN_DEBUG "---%s---%s---%d---\n",__FILE__,__func__,__LINE__);	
	return 0;
	}
	int demo_release(struct inode *inode, struct file *filp){	
	printk(KERN_DEBUG "---%s---%s---%d---\n",__FILE__,__func__,__LINE__);	
	return 0;
	}
	struct file_operations fops = {	.owner    = THIS_MODULE,	.open     = demo_open,	.release  = demo_release,};
	int __init demo_init(void){	int ret = 0;	
	//0.申請設備號-內核分配主設備號,次設備好從0開始,共三個(0,1,2)	
	ret = alloc_chrdev_region(&devno,BASEMINOR,COUNT, NAME);	
	if(ret < 0)
	{		
	printk(KERN_ERR "alloc_chrdev_region failed...\n");		
	goto err0;	
	}	
	printk(KERN_INFO "---major:%d---\n",MAJOR(devno));	
	//1.分配cdev結構體	
	cdevp = cdev_alloc();	
	if(cdevp == NULL)
	{		
	printk(KERN_ERR "cdev_alloc failed...\n");		
	ret = -ENOMEM;		
	goto err1;			
	}	
	//2.初始化cdev結構體	
	cdev_init(cdevp, &fops);
	//3.將cdev結構體添加到內核中,由內核對驅動進行統一的管理	
	ret = cdev_add(cdevp, devno, COUNT);	
	if(ret < 0){		
	printk(KERN_ERR "cdev_add failed...\n");		
	goto err1;	
	}	
	printk(KERN_DEBUG "---%s---%s---%d---\n",__FILE__,__func__,__LINE__);	
	return 0;err1:	
	unregister_chrdev_region(devno, COUNT);err0:	
	return ret;}void __exit demo_exit(void){	
	cdev_del(cdevp);	
	unregister_chrdev_region(devno, COUNT);	
	printk(KERN_DEBUG "---%s---%s---%d---\n",__FILE__,__func__,__LINE__);
	}
	module_init(demo_init);module_exit(demo_exit);MODULE_LICENSE("GPL");
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章