字符设备驱动代码的编写

字符设备驱动框架
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");
发布了19 篇原创文章 · 获赞 21 · 访问量 1258

猜你喜欢

转载自blog.csdn.net/lj19990824/article/details/104522882