一、在Linux2.6内核中一个字符设备用cdev结构来描述,其定义如下:

 struct cdev {
struct kobject kobj;
struct module *owner; //所属模块
const struct file_operations *ops; //文件操作结构,在写驱动时,其结构体内的大部分函数要被实现
struct list_head list;
dev_t dev; //设备号,int 类型,高12位为主设备号,低20位为次设备号
unsigned int count;
};

可以使用如下宏调用来获得主次设备号:
MAJOR(dev_t dev) 
MINOR(dev_t dev) 
MKDEV(int major,int minor) //通过主次设备号来生成dev_t

以上宏调用在内核源码中如此定义:

 #define MINORBITS       20
#define MINORMASK ((1U << MINORBITS) - 1) //(1<<20 -1) 此操作后,MINORMASK宏的低20位为1,高12位为0
#define MAJOR(dev) ((unsigned int) ((dev) >> MINORBITS))
#define MINOR(dev) ((unsigned int) ((dev) & MINORMASK))
#define MKDEV(ma,mi) (((ma) << MINORBITS) | (mi))

二、下面一组函数用来对cdev结构体进行操作:

 void cdev_init(struct cdev *, const struct file_operations *);//初始化,建立cdev和file_operation 之间的连接
struct cdev *cdev_alloc(void); //动态申请一个cdev内存
void cdev_put(struct cdev *p); //释放
int cdev_add(struct cdev *, dev_t, unsigned); //注册设备,通常发生在驱动模块的加载函数中
void cdev_del(struct cdev *);//注销设备,通常发生在驱动模块的卸载函数中

1)如果希望在运行时动态的获得一个独立的 cdev 结构,有两种方法可以分配并初始化 cedv 结构。

 struct cdev *my_cdev = cdev_alloc();
my_cdev->ops = &my_fops; struct cdev *cdev_alloc(void)
{
struct cdev *p = kzalloc(sizeof(struct cdev), GFP_KERNEL);
if (p) {
INIT_LIST_HEAD(&p->list);
kobject_init(&p->kobj, &ktype_cdev_dynamic);
}
return p;
}

2)有时可能希望就把 cdev 结构内嵌在自己的特定设备结构里,那么在分配好 cdev 结构后,就用 cdev_init() 函数对其初始化:

 void cdev_init(struct cdev *cdev, const struct file_operations *fops)
{
memset(cdev, , sizeof *cdev);
INIT_LIST_HEAD(&cdev->list);
kobject_init(&cdev->kobj, &ktype_cdev_default);
cdev->ops = fops;
}

3)注册与注销:像cdev 中的owner 要设置为 THIS_MOULE ,在注册时应该先调用:
int register_chrdev_region(dev_t from,unsigned count,const char *name)函数为其分配设备号,此函数可用:

int alloc_chrdev_region(dev_t *dev,unsigned baseminor,unsigned count,const char *name)函数代替,他们之间的区别在于:register_chrdev_region()用于已知设备号时,另一个用于动态申请,其优点在于不会造成设备号重复的冲突。 
在注销之后,应调用:void unregister_chrdev_region(dev_t from,unsigned count)函数释放原先申请的设备号。 
他们之间的顺序关系如下: 
register_chrdev_region()-->cdev_add()     //此过程在加载模块中 
cdev_del()-->unregister_chrdev_region()     //此过程在卸载模块中

参考原文:http://bbs.ednchina.com/BLOG_ARTICLE_1897586.HTM

cdev结构体及其相关函数的更多相关文章

  1. Linux中表示“时间”的结构体和相关函数

    转载于:http://blog.chinaunix.net/uid-25909722-id-2827364.html      Linux中表示“时间”的结构体和相关函数 2011-09-13 17: ...

  2. Linux字符设备驱动结构(一)--cdev结构体、设备号相关知识机械【转】

    本文转载自:http://blog.csdn.net/zqixiao_09/article/details/50839042 一.字符设备基础知识 1.设备驱动分类 linux系统将设备分为3类:字符 ...

  3. cdev结构体

    在内核源码include/linux/cdev.h里对cdev结构体的定义: struct cdev { struct kobject kobj; // 内嵌的kobject对象  struct mo ...

  4. ffmpeg AVPacket结构体及其相关函数

    0. 简介 AVPacket结构体并不是很复杂, 但是在ffmpeg中用的非常多. 与其相关的函数也是比较多. AVPacket保存了解复用之后, 解码之前的数据, 和这些数据相关的一些附加信息. 对 ...

  5. ffmpeg AVFrame结构体及其相关函数

    0. 简介 AVFrame中存储的是原始数据(例如视频的YUV, RGB, 音频的PCM), 此外还包含了一些相关的信息, 例如: 解码的时候存储了宏块类型表, QP表, 运动矢量等数据. 编码的时候 ...

  6. 字符设备驱动1:新的方式添加cdev + 在open函数中将文件私有数据指向设备结构体

    本例中,驱动入口处,使用cdev_add添加驱动,这点也可与字符设备驱动0:一个简单但完整的字符设备驱动程序对比一下. 另外主要讲xx_open实现文件私有数据指向设备结构体. 引子: 偶然看到,在j ...

  7. Linux字符设备中的两个重要结构体(file、inode)

    对于Linux系统中,一般字符设备和驱动之间的函数调用关系如下图所示 上图描述了用户空间应用程序通过系统调用来调用程序的过程.一般而言在驱动程序的设计中,会关系 struct file 和 struc ...

  8. inode结构体

    inode分为内存中的inode和文件系统中的inode,为了避免混淆,我们称前者为VFS inode, 而后者以EXT2为代表,我们称为Ext2 inod.这里说明的是VFS inode. 重要成员 ...

  9. cdev成员结构体file_operations文件操作结构的分析

    struct file_operations{ struct module *owner; // 指向拥有该结构的模块的指针,避免正在操作时被卸载,一般为初始化为THIS_MODULES loff_t ...

随机推荐

  1. exec,eval

    一.什么是Exec语句 假如我们一串字符串里面有Python代码,这个时候,普通情况是会把这串代码作为字符串来输出的,而不会执行这段代码.如果此时,我们想执行这串字符串里面的python代码,使用Ex ...

  2. UVALIVE 2954 Task Sequences

    竞赛图:图中的任意两点间有且仅有一条有向弧连接 求竞赛图中的哈密顿路的算法: 首先,由数学归纳法可证竞赛图在n>=2时必存在哈密顿路: (1)n=2时显然: (2)假设n=k时,结论成立,哈密顿 ...

  3. Linux指令详解useradd groupadd passwd chpasswd chage 密码修改

    Linux指令详解useradd groupadd passwd chpasswd chage 密码修改 http://speediness.blog.51cto.com/760841/1783661 ...

  4. [ 脚本 ] RHEL6.x 及Centos6.x 初始化脚本

    #!/bin/bash # check network echo "-------------check Network-------------" ping -c -t mirr ...

  5. 架设Hmailserver+webmail邮件服务器

    架设Hmailserver+webmail邮件服务器   在安裝Hmailserver前先安裝Apache.php.mysql,如果你想懶點直接到http://www.phpnow.org下載phpn ...

  6. Android动画之仿美团加载数据等待时,小人奔跑进度动画对话框(附顺丰快递员奔跑效果)

    Android动画之仿美团加载数据等待时,小人奔跑进度动画对话框(附顺丰快递员奔跑效果) 首句依然是那句老话,你懂得! finddreams :(http://blog.csdn.net/finddr ...

  7. xunsearch如何按照ID排序

    你ini再建一个字段id_tmp 类型type=numeric 重建索引的时候 数据源 加一个主键id的别名 id, id as id_tmp 排序的时候按照id_tmp排序

  8. 洛谷 P1577 切绳子【二分答案】

    题目描述 有N条绳子,它们的长度分别为Li.如果从它们中切割出K条长度相同的 绳子,这K条绳子每条最长能有多长?答案保留到小数点后2位. 输入输出格式 输入格式: 第一行两个整数N和K,接下来N行,描 ...

  9. Golang基础入门

    Go语言很容易上手 第一步,在你的计算机上安装Go语言环境 首先下载对应操作系统的安装包或者源文件 Windows和Mac OSX 都有安装包,可以选择直接双击安装,很简单 Ubuntu系统可以使用 ...

  10. POJ 1912 A highway and the seven dwarfs (凸包)

    [题目链接] http://poj.org/problem?id=1912 [题目大意] 给出一些点,表示一些屋子,这些屋子共同组成了村庄,现在要建一些高速公路 问是否经过了村庄. [题解] 这些屋子 ...