Linux设备驱动---Kobject

尽管采用C语言实现,但Linux设计实现中很多地方都体现着面向对象的思想。Kobject可以看做是Linux设备对象的基类,单独的Kobject没有太多的意义,它只有嵌入到对象结构体中才流光四射。它的一般用法如下:

struct my_obj

{

        struct kobject;

         ……./* 其他自定义结构体成员*/

};

Kobject的一个重要作用是对象生命周期管理。只有在对象引用计数为0后,对象才能被删除。尽管很多情况下我们我们不会直接操作Kobject(Linux已经替我们做了☺),清楚那些调用将导致引用计数变化对理解驱动还是很有帮助的,所谓知其然,知其所以然。总结如下:

增加引用计数:

kobject_init

kobject_get

 

减少引用计数:

kobject_put

另外Kobject以链表的形式由Kset进行管理

kobject_add  将Kobject添加到链表中

kobject_del   将Kobject从链表中删除

 

一个简单的驱动例子:

#include <linux/kernel.h>

#include <linux/module.h>

#include <linux/init.h>

#include <linux/string.h>

MODULE_LICENSE(“Dual BSD/GPL”);

struct my_kobject

{

        int val;

        struct kobject kobj;  //注意这里要用变量而不是指针,以便采用

                                            //container_of根据kobj的指针找到my_kobject

                                            //的地址

};

/*======================================================*/

void my_ktype_release(struct kobject *kobj)

{

        printk(“===my_ktype_release===\n”);

} 

ssize_t my_ktype_show(struct kobject * kobj, 

                                           struct attribute *attr,  char  *buf)

{

        ssize_t count = 0;

        printk(“===my_ktype_show===\n”);

        if(0==strcmp(attr->name,”name”))

        {

                printk(“%s\n”,kobj->name);

                count = sprintf(buf,”%s==>file\n”,kobj->name);

        }

        else

        {

                printk(“should not go here\n”);

        }

        return count;

}

ssize_t my_ktype_store(struct kobeject *kobj, 

                                           struct attribute *attr,  const char  *buff, size_t len)

{

        /*当有多个kobject调用store函数 时,在这里重新获取指针,而不是

        采用定义的全局变量的意义才能体现出来*/

        struct my_kobject *my_kobj_test; 

 

        my_kobj_test = container_of(kobj,struct my_kobject,kobj);

        printk(“===my_ktype_store===\n”);

        if(0==strcmp(attr->name,”name”))

        {

                 sscanf(buf,”%d”,&my_kobj_test->val) ;     

        }

        else

        {

                printk(“should not go here\n”);

        }

        return len;

}

/*

struct sysfs_ops 

ssize_t (*show)(structkobejct *,  struct attribute *,  char  *); 

ssize_t (*store)(structkobejct *,  struct attribute *,  char  *, ssize_t); 

}

*/

struct sysfs_ops my_sysfs_ops =

{

        .show = my_ktype_show,

        .store = my_ktype_store,

};

/*====================================================*/

struct attribute my_attr_element =

{

        .name = “name”,

        .mode = 0644,

};

/*

struct attribute{ 

char*name;//属性文件名

structmodule *owner; 

mode_tmode; 

*/

struct attribute *my_attr[] =

{

        &my_attr_element,

        NULL,

};

/*====================================================*/

/*

struct kobj_type { 

void (*release)(struct kobject *kobj); 

const struct sysfs_ops *sysfs_ops; 

struct attribute **default_attrs; 

const struct kobj_ns_type_operations *(*child_ns_type)(struct kobject *kobj); 

const void *(*namespace)(struct kobject *kobj); 

};

*/

struct kobj_type my_ktype =

{

        .release = my_ktype_release,

        .sysfs_ops = &my_sysfs_ops,

        .default_attrs = my_attr,

};

struct my_kobject my_kobj;  //也可以采用动态创建的方式,那样的话需

                                                   //要在kobj_type的release函数中free掉

static int __init my_kobj_init(void)

{

        printk(“===my_kobj_init===\n”);

        /*extern int __must_check kobject_init_and_add           

          (struct kobject *kobj,struct kobj_type *ktype,

          struct kobject *parent,const char *fmt, ...);*/

        kobject_init_and_add(&my_kobj.kobj,&my_ktype,

                                               NULL,”kobject_test”);

 

        return 0;

}

 

 

static void __exit my_kobj_exit(void)

{

        printk(“===my_kobj_exit===\n”);

        /*void kobject_del(struct kobject *kobj); */

        kobject_del(&my_kobj.kobj);

       /*void kobject_put(struct kobject *kobj);*/

        kobject_put(&my_kobj.kobj);

}

module_init(my_kobj_init);

module_exit(my_kobj_exit);

参考文献:

[1] http://blog.csdn.net/jianchi88/article/details/6997615 

[2] http://blog.chinaunix.net/uid-25550211-id-1748359.html

[3] <<LDD>>

posted @ 2012-05-25 16:54  sky-zhang  阅读(372)  评论(0编辑  收藏  举报