kobject的使用

struct kobj_type 
{
    void (*release)(struct kobject *kobj);//在kobect_put()中会调用释放kobect对象
    struct sysfs_ops *sysfs_ops;          //对attribute进行操作
    struct attribute **default_attrs;     /*每个属性代表一个此目录下的文件  
                                            比如在/sys/下加入了cat 这个kobject
                                            那么会有/sys/cat/ 这个目录  那么这个kobect有属性 size color
                                            那就会存在 /sys/cat/size  /sys/cat/color 这两个文件 */
};

struct kobject
{
    const char    *name;          //表示kobject对象的名字,对应sysfs下的一个目录 
    struct list_head    entry;  //连接到kset 建立层次结构 是kobject中插入的head_list结构
    struct kobject        *parent;// 是指向当前kobject父对象的指针,体现在sys结构中就是包含当前kobject对象的目录对象
    struct kset        *kset;      //kset代表一个subsystem 其中容纳了一系列同类型的kobject
    struct kobj_type    *ktype; //该内核对象一组sysfs文件系统相关的操作函数和属性
    struct sysfs_dirent    *sd;    //该内核对象在sysfs文件系统中对应的目录项实例
    struct kref        kref;       //是对kobject的引用计数,当引用计数为0时,就回调之前注册的release方法释放该对象
    unsigned int state_initialized:1;//1表示已经初始化  0表示未被初始化
    unsigned int state_in_sysfs:1;   //表示在sysfs系统中是否建立一个入口点
    unsigned int state_add_uevent_sent:1;
    unsigned int state_remove_uevent_sent:1;
    unsigned int uevent_suppress:1;   // 1表示在该对象状态发生变化时 不让所属kset往用户空间发送uevent消息
};

int kobject_set_name(struct kobject *kobj, const char *fmt, ...)
fun:给内核对象kobject设置名字obj->name 将会在sysfs系统中显示
kobj:kobject内核对象
fmt:格式化字符串
返回值: 成功返回0  否则返回负数
头文件:#include <linux/kobject.h>

void kobject_init(struct kobject *kobj, struct kobj_type *ktype)
fun:初始化一个kobject内核对象,需要自己提供kobj_type结构
kobj: kobject内核对象
ktype:为不同类型的kobject提供属性,属性操作集合,和kobject销毁方法,此处的属性的显示在sysfs文件系统中即是在该kobject目录下的文件
头文件:#include <linux/kobject.h>

int kobject_add(struct kobject *kobj, struct kobject *parent,const char *fmt, ...)
fun:建立kobject间的层级关系,以及在sysfs文件系统中建立一个目录,调用此函数必须kobj先进行初始化
kobj:kobject内核对象
parent:指向父目录 若为空并且指向的kset为空 则将sysfs_root作为父目录 即在/sysfs 下创建目录
fmt:此处可以修改kobject内核对象的名字kobj->name
返回值:成功返回0 失败返回负数
头文件:#include <linux/kobject.h>

int kobject_init_and_add(struct kobject *kobj, struct kobj_type *ktype,
                         struct kobject *parent, const char *fmt, ...)

fun:相当于上面的kobject_init和kobject_add的联合使用,具体看上面两个函数的介绍
返回值: 成功返回0 失败返回负数
头文件:#include <linux/kobject.h>

struct kobject *kobject_create(void)
fun:创建一个kobject内核对象并进行初始化 此处初始化不需要自己提供kobj_type内核会使用dynamic_kobj_ktype,所以要使用自己的kobj_type,就不要使用此函数
    使用此函数必须使用kobject_put()来释放kobj内核对象    
返回值:kobject内核对象
头文件:#include <linux/kobject.h>

struct kobject *kobject_create_and_add(const char *name, struct kobject *parent)
fun:功能类似于kobject_create() 加上 kobject_add() 具体看上面描述
返回值:成功返回一个kobject内核对象
头文件:#include <linux/kobject.h>

int kobject_rename(struct kobject *kobj, const char *new_name)
fun:重新命名kobject对象的名字
kobj:kobject内核对象
new_name:新名字
返回值:成功返回0  失败返回负数
头文件:#include <linux/kobject.h>

struct kobject *kobject_get(struct kobject *kobj)
fun:增加kobj内核对象的引用计数kobj->kref  初始化值为1
返回值:传入的kobj对象
头文件:#include <linux/kobject.h>

void kobject_put(struct kobject *kobj)
fun:递减kobj内核对象的引用计数 当为0的时候调用在kobject_init()中传入的kobj_type{}结构中包含的kobj释放函数
头文件:#include <linux/kobject.h>

(1)举个栗子 使用*kobject_create_and_add()

#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/kobject.h>

struct kobject *g_obj = NULL;
struct kobject *g_parobj = NULL;

static int __init  test_init(void)
{    
    g_parobj  = kobject_create_and_add("cat2",NULL);
    if(NULL == g_parobj)
    {
        printk("create kobj error\n");
        return -1;
    }
    
    g_obj  = kobject_create_and_add("whitecat",g_parobj);
    if(NULL == g_obj)
    {
        if(g_parobj)
        {     
           kobject_del(g_parobj); 
           kobject_put(g_parobj);
        }
    }
    return 0;
}


static void __exit test_exit(void)
{
    if(g_obj)
    {
       kobject_del(g_obj); 
       kobject_put(g_obj);
    }
    if(g_parobj)
    {
       kobject_del(g_parobj); 
       kobject_put(g_parobj);
    }
    
    return;
}


module_init(test_init);
module_exit(test_exit);

MODULE_LICENSE("GPL");

(2)第二个栗子自己搭建kobj_type结构

#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/kobject.h>

struct kobject *g_obj = NULL;
struct attribute  attr1={
                 .name="color",
                 .mode = 0644
};

struct attribute  attr2={
                 .name="size",
                 .mode = 0644
};

//注意此处的最后一个要设置为NULL 在内核populate_dir()中可以看到对最后一个为NULL才会停止判断
struct attribute *pattr[3] = {&attr1,&attr2,NULL};

static void kobj_free(struct kobject *kobj)
{
    kfree(kobj);
}

static ssize_t obj_attr_show(struct kobject *kobj, struct attribute *attr,char *buf)
{
    printk("read filename[%s]\n",attr->name);
    return 0;
}

static ssize_t obj_attr_store(struct kobject *kobj, struct attribute *attr,
			        const char *buf, size_t count)
{
    printk("write filename[%s] buff[%s] \n",attr->name,buf);
	
	//这里一定要返回传入的字节数 表示接受成功 
    return count;
}


struct sysfs_ops kobj_attr_ops = {
	.show	= obj_attr_show,
	.store	= obj_attr_store,
};

static struct kobj_type test_type = {
	.release	= kobj_free,
 	.sysfs_ops	= &kobj_attr_ops,
        .default_attrs  =  pattr

};

static int __init  test_init(void)
{   
    g_obj  = kzalloc(sizeof(struct kobject), GFP_KERNEL); 
    if(NULL == g_obj)
    {
        printk("alloc obj error\n");
        return -1;
    }
    kobject_init(g_obj,&test_type);
    kobject_set_name(g_obj,"cat2");
    kobject_add(g_obj,NULL,NULL); 
  
    return 0;
}

static void __exit test_exit(void)
{
   if(g_obj)
   {
	   //在sysfs文件系统中将kobj删除 
       kobject_del(g_obj);
	   //释放kobj对象将条用test_type{}中的kobj_free()
       kobject_put(g_obj);
   }  
    return;
}

module_init(test_init);
module_exit(test_exit);
MODULE_LICENSE("GPL");

猜你喜欢

转载自blog.csdn.net/yldfree/article/details/84393321