字符设备(一)

1.cdev结构体
linux2.6中使用cdev结构体描述字符设备

struct cdev {
	struct kobject kobj;//内嵌的kobject对象
	struct module *owner;//所属模块
	const struct file_operations *ops;//文件操作结构体
	struct list_head list;
	dev_t dev;//设备号
	unsigned int count;
};
dev_t定义了设备号,为32位,高12位为主设备号,低20位为次设备号。
以下宏可以获得主次设备号

MAJOR(dev_t dev);
MINOR(dev_t dev);
通过主次设备号获得dev_t的宏
MKDEV(int major,int minor);
2.cdev的主要操作函数

内核提供了一些操作cdev的结构体

void cdev_init(struct cdev *,struct file_operations *);
struct cdev *cdev_alloc(void);
void cdev_put(struct cdev *p);
int cdev_add(struct cdev *,dev_t,unsigned);
void cdev_del(struct cdev *);

cdev_init()初始化cdev的成员,建立cdev和file_operation之间的连接

void cdev_init(struct cdev *cdev,struct file_operations *fops)
{
	memset(cdev,0,sizeof *cdev);//清除cdev中的缓存
	INIT_LIST_HEAD(&cdev->list);
	cdev->kobj.ktype=&ktype_cdev_default;
	kobject_init(&cdev->kobj);
	cdev->ops=fops;//将传入的文件操作结构体指针赋值给cdev的ops
}
cdev_alloc用于动态申请一个cdev内存

struct cdev *cdev_alloc(void)
{
	struct cdev *p=kmalloc(sizeof (struct cdev),GFP_KERNEL);//分配cdev的内存
	if(p)
	{
		memset(p,0,sizeof(struct cdev));
		p->kobj.type=&ktype_cdev_dynamic;
		INIT_LIST_HEAD(&p->list);
		kobject_init(&p->kobj);
	}
	return p;
}

cdev_add()向系统添加一个cdev,完成字符设备的注册,用于模块加载函数中。

cdev_del()向系统删除一个cdev,完成字符设备的注销,用于模块卸载函数中。
3.分配和释放设备号
在调用cdev_add()向系统注册字符设备之前,需要先向系统申请设备号。
静态分配:用于已知起始设备的设备号,需要先查询,避免冲突

int register_chrdev_region(dev_t from,unsigned count,const char *name);

from:要注册的第1个设备号

count:要注册的次设备号个数

name:设备名

动态分配:向系统动态申请未占用的设备号,可自动避免设备号冲突

int alloc_chrdev_region(dev_t *dev,unsigned baseminor,unsigned count,const char *name)

dev:分配到的设备号

baseminor:起始次设备号,不一定要从0开始

count:要注册的设备号个数

name:设备名

释放设备号之前,需要先调用cdev_del()函数注销字符设备

释放:
	void unregister_chrdev_region(dev_t from,unsigned count);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值