/sysfs探索_store和show的接口

来源:互联网 发布:广东网络电视营业厅 编辑:程序博客网 时间:2024/06/08 19:51

http://blog.sina.com.cn/s/blog_78d30f6b0102uy3t.html

简单分析:
1 本样例主要测试kobject结构,kobject对应sysfs文件系统中的一个目录,该目录对应一个具体的事物。
2 首先通过example_kobj = kobject_create_and_add("kobject_example", kernel_kobj);将该结构加入  到/sys/kernel目录下[kernel_kobj为kernel子系统的kobject结构],形成层次结构,并且在父目录下建立该子目录 [kobject->sd指向该kobject所在的目录节点]。
3 通过retval = sysfs_create_group(example_kobj, &attr_group)将事物的3个特色属性与其对应的kobject绑定起来,将该文件操作接口和sysfs系统结合起来。使得可以通过 kobj_attribute中的show何store进行实际的内核读写操作,该函数实际上在父目录下新建3个文件,结构用sysfs_dirent表 示。且sysfs_dirent->s_attr.attr=相应属性结构,据此可获得读写该文件的方法。
4 每个struct attribute结构对应kobject目录下一个文件,文件的读写方法由kobj_attribute中的show和store指定,kobj_attribute是kobject属性导出的接口
 struct attribute{
           const char *name;
           struct module* owner;
           mode_t mode;
}
 struct kobj_attribute{
          struct attribute attr;
          ssize_t (*show)(struct kobject* kobj,struct kobj_attribute* attr,char* buf);
          ssize_t (*store)(struct kobject* kobj,struct kobj_attribute* attr,const char* buf,size_t count);
}
5当使用结束时,调用kobject_put(example_kobj)删除该kobject结构,及其对应的目录和文件。
扩展:实际上对于不同子系统有不同的属性和属性操作函数
比如:在genhd.h文件中,磁盘属性操作结构为,disk_attribute是磁盘属性导出的接口:
struct disk_attribute{
        struct attribute attr;
        ssize_t (* show)(struct gendisk*,char*);
        ssize_t (* store)(struct gendisk*,const char*,size_t);//新内核中该函数取消,磁盘属性只有只读操作
}
在device.h文件中,外设属性操作结构为,device_attribute是外设属性导出的接口:
struct device_attribute{
        struct attribute attr;
        ssize_t (* show)(struct device*dev,struct device_attribute*attr,char* buf);
        ssize_t (*store)(struct device *dev,struct device_attribute*attr,const char*buf,size_t count);
}
源代码如下:

#include
#include
#include
#include
#include

static int foo;
static int baz;
static int bar;


static ssize_t foo_show(struct kobject *kobj, struct kobj_attribute *attr,
   char *buf)
{
 return sprintf(buf, "%d\n", foo);
}

static ssize_t foo_store(struct kobject *kobj, struct kobj_attribute *attr,
    const char *buf, size_t count)
{
 sscanf(buf, "%du", &foo);
 return count;
}

static struct kobj_attribute foo_attribute =
 __ATTR(foo, 0666, foo_show, foo_store);


static ssize_t b_show(struct kobject *kobj, struct kobj_attribute *attr,
        char *buf)
{
 int var;

 if (strcmp(attr->attr.name, "baz") == 0)
  var = baz;
 else
  var = bar;
 return sprintf(buf, "%d\n", var);
}

static ssize_t b_store(struct kobject *kobj, struct kobj_attribute *attr,
         const char *buf, size_t count)
{
 int var;

 sscanf(buf, "%du", &var);
 if (strcmp(attr->attr.name, "baz") == 0)
  baz = var;
 else
  bar = var;
 return count;
}

static struct kobj_attribute baz_attribute =
 __ATTR(baz, 0666, b_show, b_store);
static struct kobj_attribute bar_attribute =
 __ATTR(bar, 0666, b_show, b_store);



static struct attribute *attrs[] = {
 &foo_attribute.attr,
 &baz_attribute.attr,
 &bar_attribute.attr,
 NULL, 
};


static struct attribute_group attr_group = {
 .attrs = attrs,
};

static struct kobject *example_kobj;

static int __init example_init(void)
{
 int retval;

 
 example_kobj = kobject_create_and_add("kobject_example", kernel_kobj);
 if (!example_kobj)
  return -ENOMEM;

 
 retval = sysfs_create_group(example_kobj, &attr_group);
 if (retval)
  kobject_put(example_kobj);

 return retval;
}

static void __exit example_exit(void)
{
 kobject_put(example_kobj);
}

module_init(example_init);
module_exit(example_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Greg Kroah-Hartman <<a href="mailto:greg@kroah.com">greg@kroah.com>");


0 0
原创粉丝点击