Linux2.6设备模型(一)——对象和集合
来源:互联网 发布:mac虚拟机蓝屏 编辑:程序博客网 时间:2024/06/06 07:14
由于各种热插拔设备的大量使用以及设备之间复杂的依赖关系,Linux2.6内核提出了全新的设备模型,新设备模型的核心概念是内核对象及内核集合,并以此为契机,扩展出许多新的数据类型,如设备、总线等
新的设备模型仅用于设备的管理,与Linux传统的字符设备驱动等并不冲突。
1 对象与集合
在驱动程序的编写中一般不会直接用到对象和集合,但是对了解新的设备模型会有很大的帮助。
1.1引用计数
新设备模型的一个突出特点就是各种数据类型都支持引用计数。这样做的好处是:可以避免将其他模块正在使用的数据对象销毁的现象。
1.1.1引用计数类型
struct kref{
atomic_t refcount;/*用于计数的原子性变量*/
};
1.1.2引用计数的基本操作
1)设置引用计数的值
void kref_set(struct kref *kref,int num);
注解:kref指向要设置的引用计数变量,num为要设置的值。
2)初始化(默认设置为1)
void kref_init(struct kref *kref);
3)获取引用计数(+1)
void kref_get(struct kref *kref);
4)释放引用计数(-1)
int kref_put(struct kref *kref,void (*release) (struct kref *kref));
注解:release:当引用计数的值为0时,这个函数被调用
返回值:1表示引用计数的值降为0,0表示没有降为0.
1.2内核对象
内核对象是设备模型中最基本的数据类型,有名称,支持引用计数,可以有父子关系,可以属于某个内核集合。内核对象与sysfs文件系统中的目录一一对应,其父子关系对应着目录的层次关系,其属性随影这目录中的文件。
1.2.1内核对象数据类型
struct kobject{
const char *name;//内核对象的名称
struct list_head entry;//链表节点,用于把属于同一个集合的多个内核对象组成链表
struct kobject *parent;//指向父对象
struct kset *kset;//指向所属内核集合
struct kobj_type *ktype;//指向一个描述内核对象类型的结构体
struct kref kref;//引用计数
unisigned int uevent_suppress:1;//表示用户态事件是否被抑制
......
};
1.2.2内核对象的名称
1) 由于涉及到内存的动态分配和释放,不能直接给内核对象的name成员赋值。由于内核对象的名称在注册后将作为目录名,所以不要包含斜杠("/").
int kobject_set_name(struct kobject *kobj,const char *fmt ,...);
注解:kobj:指向要设置名称的内核对象
fmt:与后面的可变参数结合,构造内核对象的名称。
2)上面的函数不能用来设置已注册的内核对象的名称,此种情况下可用:
int kobject_rename(struct kobject *kobj,const char *name);
3)获取内核对象的名称
const char * kobject_name(const struct kobject *kobj);
1.2.3内核对象的初始化和注册
1)初始化函数
void kobject_init(struct kobject *kobj,struct kobj_type *ktype);
注解:
ktype:用于设置内核对象的类型
初始化后的内核对象可以向内核注册,注册的结果是在sysfs文件系统中出现一个以对象名称命名的目录,
2)注册接口函数
int kobject_add(struct kobject *kobj,struct kobject *parent,const char *fmt,...);
注解:
parent:指定内核对象的父对象,可以为NULL
注册时可以指定内核对象的父对象,对应的目录会建立在父对象的目录中,如果指定为NULL,则它的父对象会被设为其kset成员指向的内核集合中嵌套的内核对象,如果kset也指向NULL,则对应的目录会建立在sysfs系统得根目录下。
注册时还会增加对父对象的引用计数。
3)注销函数
void kobject_del(struct kobject *kobj);
1.2.4内核对象的引用计数
由于内核对象内嵌了一个引用计数成员,所以会很容易实现引用计数的相关操作。
1)内核对象的获取操作定义
struct kobject *kobkect_get(struct kobject *kobj)
{
if(kobj) kref_get(&kobj->kref);
return kobj;
}
2)内核对象的释放操作定义
void kobject_put(struct kobject *kobj)
{
if(kobj) kref_put(&kobj->kref,kobject_release);
}
注解:kobject_release是内核为对象内嵌的kref成员定义的释放函数。
1.3内核对象的类型
这里的类型指的是内核对象内嵌的(struct kobj_type*)型指针,这个指针指向的结构体所描述的是这个内核对象的类型。其定义为:
struct kobj_type{
void (*release) (struct kobject *kobj);//内核对象的释放函数
struct sysfs_ops *sysfs_ops;//sysfs文件操作
struct attribute **default_attrs;//内核对象的默认属性
};
注解:release会在函数kobject_release里被回调。
sysfs_ops和default_attrs成员组合起来用于实现内核对象的属性。
default_attrs指向的数组的最后一个元素必须是NULL。内核据此来判断默认的属性已描述完毕。
1.3.1内核对象的属性
default_attrs指向一个指针数组,这个数组中的每个指针指向一个用于描述对象属性的数据,该数据的类型定义为:
struct attribute{
const char *name//属性的名称
mode_t mode//属性的访问权限mode_t实则为unsigned short类型。
};
内核对象注册以后,每个属性将呈现为内核对象目录下的一个文件,文件名就是属性名,文件的访问权限就是属性的访问权限。
当应用程序读写属性所对应的文件时,内核将回调由成员sysfs_ops指向的操作,它的定义为:
struct sysfs_ops{
sszie_t (*show) (struct kobject *kobj,struct attribute *attr,char *buf);
sszie_t (*store) (struct kobject *kobj,struct attribute *attr,const char *buf,size_t size);
};
1.3.2动态创建属性
int sysfs_create_file(struct kobject *kobj,const attribute *attr);
注解:
attr:指向要创建的新属性(文件)
动态创建的属性可以被删除
void sysfs_remove_file(struct kobject *kobj,const struct attribute *attr);
注:本文主要参考何永琪先生主编的《嵌入式Linux系统实用开发》
- Linux2.6设备模型(一)——对象和集合
- linux2.6内核文件系统与设备模型
- LINUX2.6设备驱动模型详细解释
- linux2.6 总线设备驱动模型
- LINUX2.6输入子系统设备模型分析
- 详细介绍Linux2.6设备的驱动模型[转]
- linux2.6标准字符设备驱动模型(手动注册)
- linux2.6设备文件系统
- linux 设备模型(一)对象层
- Linux2.6.29设备模型分析-概述
- linux设备模型之内核集合、内核对象
- linux2.6 设备驱动编写
- Linux2.6块设备驱动程序
- 字符设备驱动linux2.6
- Linux2.6创建设备文件
- linux2.6设备驱动编写
- linux2.6设备驱动程序框架
- Zephyr Kernel 设备驱动和设备模型(一)
- Java中的equals()和==
- 设置一个层同时水平垂直居中
- Dubbo是什么
- jQuery.extend 函数详解
- ubuntu samba服务器配置(windows访问linux下文件夹,比VMware共享文件夹更高效)
- Linux2.6设备模型(一)——对象和集合
- Java小编
- 优化firefox和chrome的配置文件,提高运行速度
- const,指针,数组,指针常量,常量指针等归纳总结
- dubbo(provider,consumer)点到点直连配置
- 从字符串常量起说内存分配
- HDU 3879 Base Station(最小割---最大权闭合)
- 第182天
- 黑马程序员——变量丶关键字