科创园

科创园地,分享技术知识,为科技助力发展,贡献一己之力。
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

Kobject与Kset实例分析

Posted on 2013-02-19 08:45  科创园  阅读(599)  评论(0编辑  收藏  举报

说明:关于代码中涉及的一些结构参考2.6内核;以及kobject原理参考

http://www.cnblogs.com/myblesh/articles/2367613.html

Kobject实例代码解读

View Code
 1 #include <linux/device.h>
 2 #include <linux/module.h>
 3 #include <linux/kernel.h>
 4 #include <linux/init.h>
 5 #include <linux/string.h>
 6 #include <linux/sysfs.h>
 7 #include <linux/stat.h>
 8  
 9 MODULE_AUTHOR("David Xie");
10 MODULE_LICENSE("Dual BSD/GPL");
11 
12 /*Kobject充当父类;作用:创建sys下的一个目录*/
13   
14 void obj_test_release(struct kobject *kobject);
15 ssize_t kobj_test_show(struct kobject *kobject, struct attribute *attr,char *buf);
16 ssize_t kobj_test_store(struct kobject *kobject,struct attribute *attr,const char *buf, size_t count);
17  
18 struct attribute test_attr = {
19         .name = "kobj_config",
20         .mode = S_IRWXUGO,  /*include <linux/stat.h>*/
21 };
22  
23 static struct attribute *def_attrs[] = {
24         &test_attr,  /*只有一个属性结构,若是多个,则再添加*/
25         NULL,
26 };
27  
28  
29 struct sysfs_ops obj_test_sysops =
30 {
31         .show = kobj_test_show,
32         .store = kobj_test_store,
33 };
34  /*Ktype作用是定义Kobject的一些属性以及相关的操作*/
35 struct kobj_type ktype = 
36 {
37         .release = obj_test_release,
38         .sysfs_ops=&obj_test_sysops,   /*sysfs_ops 结构体定义sysfs文件系统的相关操作:show与store*/
39         .default_attrs=def_attrs,
40 };
41  
42 void obj_test_release(struct kobject *kobject)
43 {
44         printk("eric_test: release .\n");
45 }
46 
47 /* Show:当用户读属性文件时,该函数被调用,该函数将属性值 
48    存入buffer中返回给用户态;*/
49 ssize_t kobj_test_show(struct kobject *kobject, struct attribute *attr,char *buf)
50 {
51         printk("have show.\n");
52         printk("attrname:%s.\n", attr->name);
53         sprintf(buf,"%s\n",attr->name);/*将要返回给用户看的信息存到buf中*/  
54         return strlen(attr->name)+2;
55 }
56  /* 当用户写属性文件时,该函数被调用,用于存储用户传 
57    入的属性值*/
58 ssize_t kobj_test_store(struct kobject *kobject,struct attribute *attr,const char *buf, size_t count)
59 {
60         printk("havestore\n");
61         printk("write: %s\n",buf);
62         return count;
63 }
64 
65 struct kobject kobj;/*定义一个全局结构体kobject*/
66 static int kobj_test_init(void)
67 {
68         printk("kboject test init.\n");
69         kobject_init_and_add(&kobj,&ktype,NULL,"kobject_test"); /*这里初始化并注册kobject kobj结构体*/
70         return 0;
71 }
72  
73 static void kobj_test_exit(void)
74 {
75         printk("kobject test exit.\n");
76         kobject_del(&kobj);
77 }
78  
79 module_init(kobj_test_init);
80 module_exit(kobj_test_exit);

Kset实例代码解读

View Code
 1 #include <linux/device.h>  
 2 #include <linux/module.h>  
 3 #include <linux/kernel.h>  
 4 #include <linux/init.h>  
 5 #include <linux/string.h>  
 6 #include <linux/sysfs.h>  
 7 #include <linux/stat.h>  
 8 #include <linux/kobject.h>  
 9    
10 MODULE_AUTHOR("David Xie");  
11 MODULE_LICENSE("Dual BSD/GPL");  
12 /*
13 Kset是相同类型的kobject的集合,在sysfs中体现成一个目录*/   
14 struct kset kset_p;  
15 struct kset kset_c; 
16  
17 /*
18 这三个函数的功能是什么? 
19 filter:决定是否将事件传递到用户空间。如果filter 
20 返回0,将不传递事件。(例:uevent_filter ) 
21 name:用于将字符串传递给用户空间的热插拔处理程序。 
22 uevent:将用户空间需要的参数添加到环境变量中。 
23 例:dev_uevent ) 
24 */
25 int kset_filter(struct kset *kset, struct kobject *kobj)  
26 {  
27         printk("Filter: kobj %s.\n",kobj->name);  
28         return 1; /*若返回0,则过来掉,即不传给用户空间*/ 
29 }  
30    
31 const char *kset_name(struct kset *kset, struct kobject *kobj)  
32 {  
33         static char buf[20];  
34         printk("Name: kobj %s.\n",kobj->name);  
35         sprintf(buf,"%s","kset_name");  
36         return buf;  
37 }  
38    
39 int kset_uevent(struct kset *kset, struct kobject *kobj,struct kobj_uevent_env *env)  
40 {  
41         int i = 0;  
42         printk("uevent: kobj %s.\n",kobj->name);  
43   
44         while( i < env->envp_idx){  
45                 printk("%s.\n",env->envp[i]);  
46                 i++;  
47         }  
48   
49         return 0;  
50 }  
51   
52 struct kset_uevent_ops uevent_ops =   
53 {  
54         .filter = kset_filter,  
55         .name   = kset_name,  
56         .uevent = kset_uevent,  
57 };  
58    
59 int kset_test_init()  
60 {  
61         printk("kset test init.\n");  
62         kobject_set_name(&kset_p.kobj,"kset_p");  
63         kset_p.uevent_ops = &uevent_ops;  
64         kset_register(&kset_p);  
65    
66         kobject_set_name(&kset_c.kobj,"kset_c");  
67         kset_c.kobj.kset = &kset_p;  /*这说明kobject是基类,只要是kset一定包含kobject*/
68         kset_register(&kset_c);  
69         return 0;  
70 }  
71    
72 int kset_test_exit()  
73 {  
74         printk("kset test exit.\n");  
75         kset_unregister(&kset_p);  
76         kset_unregister(&kset_c);  
77         return 0;  
78 }  
79    
80 module_init(kset_test_init);  
81 module_exit(kset_test_exit); 

注意:Kobject类似于C++中的基类,常被嵌入到其他类型(即容器)中,如bus、drivers、devices都是典型的容器;Kobject实现了基本的面向对象管理机制,是linux2.6设备模型的核心结构,与sysfs文件系统紧密相连。

 总结:

1、 Kset是相同类型的kobject的集合,在sysfs中体现成一个目录;

 struct kset {

          struct list_head list;

          spinlock_t list_lock;

          struct kobject kobj;

         const struct kset_uevent_ops *uevent_ops;

 };

2、Platform 驱动与传统的设备驱动模型相比,优势在于platform机制将设备本身的资源注册进内核,由内核统一管理,在驱动程序使用这些资源时使用统一的接口,这样提高了程序的可移植性。平台设备驱动程序与设备匹配时通过比较名字,在platform_match函数中代码有

 return (strcmp(pdev->name, drv->name) == 0);