一、在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. bzoj 1001 平面图转对偶图 最短路求图最小割

    原题传送门http://www.lydsy.com/JudgeOnline/problem.php?id=1001 整理了下之前A的题 平面图可以转化成对偶图,然后(NlogN)的可以求出图的最小割( ...

  2. nginx启动脚本(class练习)

    说明:使用类的方式编写程序启动脚本(练习) 1 #!/usr/bin/env python import sys import os from subprocess import Popen,PIPE ...

  3. return 与 exit() 的区别

    return是一个关键字,返回函数值:exit()是一个函数: return是语言级的:exit()是操作系统提供的函数: return表示函数退出:exit()表示进程退出: 非主函数中调用retu ...

  4. url 拼接的一个模块furl

    from furl import furl getlongtexturl="https://weibo.com/p/aj/mblog/getlongtext" params={ & ...

  5. aiohttp/asyncio 小例子和解释

    #!/usr/bin/env python # encoding: utf-8 import aiohttp import asyncio import time # 通过async def定义的函数 ...

  6. WPF拖放功能实现

    写在前面:本文为即兴而作,因此难免有疏漏和词不达意的地方.在这里,非常期望您提供评论,分享您的想法和建议. 这是一篇介绍如何在WPF中实现拖放功能的短文. 首先要读者清楚的一件事情是:拖放主要分为拖放 ...

  7. PLSQL Developer 运用Profiler 分析存储过程性能

    最近应公司需要,需要编写ORACLE存储过程.本人新手,在完成存储过程的编写后,感觉需要对存储过程中各个语句的执行时间进行分析,以便 对整个存储过程进行优化. 由于用的是PLSQL Developer ...

  8. CDN缓存(转载)

    CDN缓存那些事(转载) 原文地址:http://bbs.qcloud.com/forum.php?mod=viewthread&tid=3775 注:原文全文复制,仅仅作为自己下次学习备份, ...

  9. Nmap——主机、端口扫描工具

    nmap 其基本功能有三个,一是探测一组主机是否在线:其次是扫描主机端口,嗅探所提供的网络服务:还可以推断主机所用的操作系统 . 这是百度给的介绍:http://baike.baidu.com/lin ...

  10. codeforces Round #441 A Trip For Meal【思路/模拟】

    A. Trip For Meal time limit per test 1 second memory limit per test 512 megabytes input standard inp ...