字符设备(一)

来源:互联网 发布:淘宝直通车通投位置 编辑:程序博客网 时间:2024/06/05 20:58
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);
原创粉丝点击