IMX257设备驱动模型之Kset

发布时间:2024-08-15  

一、kset介绍

1. kset结构体

Struct kset{

Struct list_head list; //连接所包含的kobject对象的链表首部

Spinlock_t list_lock; //维护list链表的自旋锁

Struct kobject kobj; //内嵌的kobject结构体,说明kset本身也是一个目录

Struct kset_uevent_ops *uevent_ops; //热插拔事件

}

 

从上面的结构体可以得知:

kset 包含kobject 和 一个kset_uevent_ops 热插拔事件结构体

2. 热插拔事件结构体 kset_uevent_ops

热插拔事件意思就是当kset目录下有任何变动,包括目录的移动,增加目录或者属性文件等操作。

当系统配置发生变化时,如添加kset到系统或移动kobject,一个通知会从内核空间发送到用户空间,这就是热插拔事件。热插拔事件会导致用户空间中的处理程序(如udev,mdev)被调用,这些处理程序会通过加载驱动程序,创建设备节点等来响应热插拔事件。

结构体定义为:

struct kset_uevnt_ops{

int (*filter)(struct kset *kset,struct kobject *kobj);

const char *(*name)(struct kset *kset, struct kobject *kobj );

int (*uevent)(struct kset *kset,struct kobject *kobj,struct kobj_uevent *env);

}

功能:

filter 过滤事件,决定是否产生事件,如果返回0,将不产生事件。

name向用户空间传递一个合适的字符串

uevent通过环境变量传递任何热插拔脚本需要的信息,他会在(udev或mdev)调用之前,提供添加环境变量的机会。

 

3. kset操作函数

void kset_init(struct kset *kset);

int kset_add(struct kset *kset);

int kset_register(struct kset *kset);

void kset_unregister(struct kset *kset);

 

二、程序分析

 

1. 定义kset结构体

 

2. 定义热插拔事件结构体

函数实现:

 

3. 在init初始化函数中

如图所示,

第45行: kobject_set_name 是设定kset中的kobject的名字为kset_p

第46行: 关联kset与热插拔时间处理函数

第47行: 注册kset, 此时会在sys目录下创建一个名字为kobject的名字的文件夹

第50行: 设置kset_p的父目录(父kset)为kset_p(注意这一行)

 

4. 在exit函数中,卸载kset

 

5.总体流程分析

1.kset_test_init初始化kset

2.kobject_set_name(&kset_p.kobj,'kset_p');

3.创建一个struct kset kset_p,目录名字是kset_p

4.注册kset_register(&kset_p);

5.添加一个目录kset_p

6.kobject_set_name(&kset_c.kobj,'kset_c');

7.创建一个struct kset kset_c,目录名字是kset_c

8.kset_c.kobj.kset = &kset_p; kset_c的父目录是kset_p,也就是讲kset_p下有一个目录kset_c

9.注册kset_register(&kset_c);

10.添加一个目录kset_c

11.当在kset_p下增加一个kset_c目录,发生热插拔事件,调用uevent_ops

12.kset_filter被调用,返回0,不传递事件,返回1,传递

13.kset_name打印名字

14.kset_uevent打印相关的信息

 

6.编译测试

 

 

如图所示:

在 sys/目录下 ,产生一个 kset_p 的目录,子目录下还有一个kset_c

然后再看打印信息,可以发现分别调用调用了热插拔时间的三个函数。

注意 ACTION后面 为add,意思就是添加了一个kset目录

目录的路径为DEVPATH = /kset_p/kset_c

 

我们再观察卸载驱动时的变化

可以发现,前面ACTION = remove 意思是移除一个kset目录

 

7.总结

kset和kobject的不同之处就是kset下面可以再次包含kset目录,kobject下只能包含属性文件,

创建kset目录时,首先第一步是定义kset结构体,第二步是实现热插拔的结构体及其相应的函数与,第三步就是在初始化函数中对kset的kobject命名,关联热插拔事件,最后就是注册kset,第四步是当我们不用kset时自然就是卸载kset了。很简单吧。

搞定这个了,下一步我们就开始 总线-设备-驱动模型 之旅了,


附上驱动程序:


 1 #include

 2 #include

 3 #include

 4 #include

 5 #include

 6 #include

 7 #include

 8 #include

 9 

10 //定义两个kset结构体

11 struct kset kset_p;

12 struct kset kset_c;

13 

14 static int kset_filter(struct kset *kset,struct kobject *kobj){

15     printk('Filter: kobj %s. n',kobj->name);

16     return 1;

17 }

18 

19 const char *kset_name(struct kset *kset, struct kobject *kobj){

20     static char buf[20];

21     printk('Name: kobj %s. n',kobj->name);

22     return buf;

23 }

24 

25 static int kset_uevent(struct kset *kset, struct kobject *kobj,struct kobj_uevent_env *env){

26     int i = 0;

27     printk('uevent : kobj %s. n',kobj->name);

28 

29     while(i < env->envp_idx){    //打印相关的信息

30         printk('%s .n',env->envp[i]);

31         i++;

32     }

33     return 0;

34 }

35 

36 //定义kset发生热插拔(目录下有任何变动)时,调用的函数

37 struct kset_uevent_ops uevent_ops = {

38     .filter = kset_filter,

39     .name = kset_name,

40     .uevent = kset_uevent,

41 };

42 

43 static int kset_test1_init(void){

44     printk('<0>kset test init. n');

45     kobject_set_name(&kset_p.kobj,'kset_p');

46     kset_p.uevent_ops = &uevent_ops;    //关联热插拔事件处理函数

47     kset_register(&kset_p);                //注册

48 

49     kobject_set_name(&kset_c.kobj,'kset_c');

50     kset_c.kobj.kset = &kset_p;            //执行kset_c的父目录为kset_p

51     kset_register(&kset_c);                //注册

52 

53     return 0;

54 }

55 

56 static int kset_test1_exit(void){

57     printk('<0>kset test exit. n');

58     kset_unregister(&kset_p);         //kset卸载

59     kset_unregister(&kset_c);

60     return 0;

61 }

62 

63 module_init(kset_test1_init);

64 module_exit(kset_test1_exit);

65 

66 MODULE_AUTHOR('Lover雪儿');

67 MODULE_LICENSE('Dual BSD/GPL');


文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>