20150223 IMX257 设备驱动模型之Kobject(一)
发布日期:2021-06-29 14:56:01 浏览次数:2 分类:技术文章

本文共 4256 字,大约阅读时间需要 14 分钟。

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

2015-02-23 李海沿

接下来我们开始涉及设备驱动模型,从简入深,我们先写一个驱动,实现的功能就是在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提供了对应的宏来简化属性的操作。请参考<linux/sysfs.h>头文件中。

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:(这个结构定义在<linux/device.h>头文件中)。

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,"%s\n",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); //删除kobject60 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");
View Code

 

转载地址:https://ciellee.blog.csdn.net/article/details/82599461 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:HTML5的FileAPI实现文件的读取及超大文件的上传
下一篇:FormData实现form表单的数据打包

发表评论

最新留言

初次前来,多多关照!
[***.217.46.12]2024年04月20日 06时49分04秒