cdev结构体及其相关函数
一、在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结构体及其相关函数的更多相关文章
- Linux中表示“时间”的结构体和相关函数
转载于:http://blog.chinaunix.net/uid-25909722-id-2827364.html Linux中表示“时间”的结构体和相关函数 2011-09-13 17: ...
- Linux字符设备驱动结构(一)--cdev结构体、设备号相关知识机械【转】
本文转载自:http://blog.csdn.net/zqixiao_09/article/details/50839042 一.字符设备基础知识 1.设备驱动分类 linux系统将设备分为3类:字符 ...
- cdev结构体
在内核源码include/linux/cdev.h里对cdev结构体的定义: struct cdev { struct kobject kobj; // 内嵌的kobject对象 struct mo ...
- ffmpeg AVPacket结构体及其相关函数
0. 简介 AVPacket结构体并不是很复杂, 但是在ffmpeg中用的非常多. 与其相关的函数也是比较多. AVPacket保存了解复用之后, 解码之前的数据, 和这些数据相关的一些附加信息. 对 ...
- ffmpeg AVFrame结构体及其相关函数
0. 简介 AVFrame中存储的是原始数据(例如视频的YUV, RGB, 音频的PCM), 此外还包含了一些相关的信息, 例如: 解码的时候存储了宏块类型表, QP表, 运动矢量等数据. 编码的时候 ...
- 字符设备驱动1:新的方式添加cdev + 在open函数中将文件私有数据指向设备结构体
本例中,驱动入口处,使用cdev_add添加驱动,这点也可与字符设备驱动0:一个简单但完整的字符设备驱动程序对比一下. 另外主要讲xx_open实现文件私有数据指向设备结构体. 引子: 偶然看到,在j ...
- Linux字符设备中的两个重要结构体(file、inode)
对于Linux系统中,一般字符设备和驱动之间的函数调用关系如下图所示 上图描述了用户空间应用程序通过系统调用来调用程序的过程.一般而言在驱动程序的设计中,会关系 struct file 和 struc ...
- inode结构体
inode分为内存中的inode和文件系统中的inode,为了避免混淆,我们称前者为VFS inode, 而后者以EXT2为代表,我们称为Ext2 inod.这里说明的是VFS inode. 重要成员 ...
- cdev成员结构体file_operations文件操作结构的分析
struct file_operations{ struct module *owner; // 指向拥有该结构的模块的指针,避免正在操作时被卸载,一般为初始化为THIS_MODULES loff_t ...
随机推荐
- python3 匿名函数,map/reduce/filter等函数结合应用
匿名函数就是不需要显式的指定函数 # 平方函数 def func1(x): return x**2 print(func1) # 平方函数匿名函数写法 func2=lambda x:x**2 prin ...
- swt 更新主UI线程
// 将msg送回对应的Applet public void write(String msg) { synchronized (msg) { try { m_out.writeUTF(msg); } ...
- 使用go写一个检测tcpudp状态的包
使用go写一个检测tcpudp状态的包 http://www.2cto.com/os/201501/367596.html
- Oracle基础 12 对象 objects 同义词/序列/试图/索引
--创建同义词create public synonym employees for hr.employees; --公共同义词需要 create public synonym 权限 表的所有用户授 ...
- python--celery
有些时候我们的一些任务比较耗时,比如我们写了一个网站,用户注册的时候需要发送邮件.但是发送邮件的过程比较耗时,用户必须要等到我们将邮件发送成功之后才会得到响应.那么有没有一种办法,当用户点击发送邮件的 ...
- C++类中引用成员和常量成员的初始化(初始化列表)
如果一个类是这样定义的: Class A { public: A(int pram1, int pram2, int pram3); privite: int a; int &b; const ...
- poj 1556(迪杰斯特拉+计算几何)
The Doors Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 7641 Accepted: 2987 Descrip ...
- 怎么将string list 转成有特殊字符分开字符串
https://stackoverflow.com/questions/4021851/join-string-list-elements-with-a-delimiter-in-one-step Y ...
- UTF-8编码中BOM的检测与删除[linux下命令]
Posted on 2011-05-14 所谓BOM,全称是Byte Order Mark,它是一个Unicode字符,通常出现在文本的开头,用来标识字节序(Big/Little Endian),除此 ...
- shipyard, swarm看到你,我才睡觉:)
windows下用boot2docker有点不爽,就是网卡识别不好. 还是用纯的virtualbox建centos7虚拟机来搞, 一下就OK. 但记得,要用Iptables来弄墙,去掉firewall ...