IMX257 设备驱动模型之Kobject(一)

发布时间:2024-08-15  

接下来我们开始涉及设备驱动模型,从简入深,我们先写一个驱动,实现的功能就是在sys目录下建立一个目录和一个属性文件,可读可写。

所以今天的任务就是把这个程序搞定,只要把这几个结构体了解,知道有这个结构体就够了,很晚了,剩下的我们交给明天吧。

一、结构体参数解释

1. kobject

kobject是设备驱动模型的基础。sysfs是基于kobject建立起来的。

struct kobject{

    const char *name; //显示在sysfs中的名称

    struct list_head entry;    //下一个kobject结构

    struct kobject *parent;    //指向父kobject结构体,如果存在

    struct kset   *kset;     //指向kset集合

    struct kobj_type  *ktype; //指向kobject类型描述符

    struct sysfs_dirent *sd; //对应sysfs的文件目录

    struct kref kref;         //kobject引用计数

    unsigned int state_initialized:1; //是否初始化

    unsigned int state_in_sysfs:1; //是否加入sysfs

    unsigned int state_add_uevent_sent:1; //是否支持热插

    unsigned int state_remove_uevent_sent:1; //是否支持热拔

}

 

2. kobj_type

每个kobject都会有一个属性kobj_type

struct kobj_type

{

  void (*release)(struct kobject *kobj); //释放kobject和其他占用资源的函数

  struct sysfs_ops *sysfs_ops;       //操作属性的方法

  struct attribute **default_attrs;     //属性数组

};

 

3. sysfs_ops

struct sysfs_ops{

  ssize_t (*show)(struct kobject *,struct attribute *,char *);  //读属性操作函数

  ssize_t (*store)(struct kobject *,struct attribute *,const char *,size_t); //写属性操作函数

};

 

4. 描述属性文件的结构

sysfs文件系统中,最重要的就是struct attribute结构,它被用来管理内核sysfs文件的接口(名字,属性,读写函数等)。内核sysfs提供了基本的attribute接口,不同的设备如bus、device在基本attribute的基础上定义了自己的读写函数,sysfs提供了对应的宏来简化属性的操作。请参考头文件中。

struct attribute {  
    const char        *name;
    struct module     *owner;
    mode_t            mode;
};

#define __ATTR(_name,_mode,_show,_store) {
    .attr = {.name = __stringify(_name), .mode = _mode },    
    .show    = _show,                    
    .store    = _store,                    
}

int __must_check sysfs_create_file(struct kobject *kobj, const struct attribute *attr);
int __must_check sysfs_create_dir(struct kobject *kobj);

 

5. 定义操作函数

我们看到,sysfs的struct attribute结构本身并不包含读写访问函数,驱动模型的各个部分都会扩展这个结构并定义自己的属性结构来引入各自的操作函数,如 class:(这个结构定义在头文件中)。

struct class_attribute {

struct attribute attr;

ssize_t (*show)(struct class *, char * buf);

ssize_t (*store)(struct class *, const char * buf, size_t count);

};

#define CLASS_ATTR(_name, _mode, _show, _store)

struct class_attribute class_attr_##_name = __ATTR(_name, _mode, _show, _store)

 

 

二、驱动程序详解

 

1. 定义相关结构体

首先从大的开始,我们先实现一个框架,我们也就先定义一个kobject结构体,接下来就是定义sysfs_ops和 kobj_type 这两个结构体。

在kobj_type中将 属性结构体 连接起来。

 

 

2. 定义属性结构体

框架搭建好了,我们接下来的任务就是前面我们所说的建立 属性文件夹和属性文件。

 

3.在init函数中,将kobject注册入内核

 

4.在exit函数中 删除我们注册的kobject

 

5.编译测试

 

附上驱动代码:


 1 #include

 2 #include

 3 #include

 4 #include

 5 #include

 6 #include

 7 #include

 8 

 9 //定义一个名为kobject_test,可以读写的属性

10 struct attribute test_attr = {

11     .name = 'kobject_test',        //属性名

12     .mode = S_IRWXUGO,            //属性为可读可写

13 };

14 //该kobject只有一个属性

15 static struct attribute *def_attrs[] = {

16     &test_attr,

17     NULL,    

18 };

19 

20 void kobject_test_release(struct kobject *kobject){

21     printk('kobject_test: kobject_test_release() . n');

22 }

23 //读属性的名字

24 ssize_t kobject_test_show(struct kobject *kobject, struct attribute *attr, char *buf){

25     printk('call kobject_test_show(). n');        /*调试信息*/

26     printk('attrname: %s.n',attr->name);    //打印属性名字

27     sprintf(buf,'%sn',attr->name);        //将名字方法buf中返回用户空间

28     return strlen(attr->name) + 2;

29 }

30 //写一属性的值

31 ssize_t kobject_test_store(struct kobject *kobject,struct attribute *attr, const char *buf, size_t count){

32     printk('call kobject_test_store(). n');    /*调试信息*/

33     printk('write: %s.n',buf);                    //打印属性名字

34     strcpy(attr->name, buf);                    //写一个属性

35     return count;

36 }

37 

38 struct sysfs_ops obj_test_sysops = {

39     .show = kobject_test_show,    //属性读函数

40     .store = kobject_test_store,    //属性写函数

41 };

42 

43 struct kobj_type ktype={

44     .release = kobject_test_release,    //释放函数

45     .sysfs_ops = &obj_test_sysops,        //属性的操作函数

46     .default_attrs = def_attrs,            //默认属性

47 };

48 

49 struct kobject kobj;        //要添加的kobject结构

50 static int kobject_test_init(void){

51     printk('kobject test_init(). n');

52     kobject_init_and_add(&kobj, &ktype, NULL, 'kobject_test');

53 

54     return 0;

55 }

56 

57 static int kobject_test_exit(void){

58     printk('kobject test_exit. n');

59     kobject_del(&kobj);        //删除kobject

60     return 0;

61 }

62 

63 module_init(kobject_test_init);

64 module_exit(kobject_test_exit);

65 

66 MODULE_AUTHOR('Lover雪儿');

67 MODULE_LICENSE('Dual BSD/GPL');


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

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

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

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

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

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

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

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