20150225 IMX257 设备驱动模型之Kobject(三)
2015-02-25 12:02
417 查看
[b]20150225 IMX257 设备驱动模型之Kobject(三) [/b]
2012-02-25 李海沿
刚才我们整理了一大批乏味的知识点,但是相信大家已经大概的了解了sysfs 的原理了。
这里我们趁热打铁,将前面我们那个似懂非懂的kobject程序一步拿下。
我们这个程序的目的是,在sys目录下面创建一个kboject_test目录和一个名为kobject_test的属性文件,我们可以使用cat去读取其文件名。
前面虽然解释了kobject程序的大概工作流程,这次我们再次详细的说明一下其工作流程,然后再附上今天注有详细解释的kobject驱动程序代码:
[b]一、工作流程: [/b]
[b]1. 定义kobject结构体 [/b]
kboject结构体定义如下:
既然定义了kobject结构体,但是这是一个空的结构体,并没有什么属性,所以自然我们就是定义它的属性结构体属性 kobj_type 类描述符
[b]2. 定义kobj_type结构体 [/b]
kobje结构体定义如下:
所以自然我们就要实现结构体中的 释放函数,操作属性方法,和属性数组
[b]2.1 release函数实现 属性释放方法 [/b]
这里我们release函数只是简单的打印一句话,实际项目中的release可能包含各种代码,视具体功能而定
[b]2.2 sysfs_ops结构体 属性操作方法 [/b]
如图所示,sys_ops中就是定义了对属性文件的读写操作调用的函数
其原型结构体如下:
[b]2.3 default_attrs属性数组 [/b]
在注释中已经讲得很详细了,它也可以理解为在sys的文件夹中的属性文件,结构体就对应属性文件
[b]2.3.1 test_attr属性结构体[/b]
同样在代码中已经解释的很详细了,可以这样理解,这个结构体中所有的属性就是在属性文件中的文件内容
其原型如下:
[b]3. 添加kobject进入内核 [/b]
到此为止,我们呢已经将kobject基本的属性、方法等都实现了,下面自然就是将它加入结构体,告诉操作系统啊,
我们此处init函数唯一的操作就是将它加入注册进入操作系统,让操作系统认识这个结构体。
[b]4. 从内核中删除操作系统 [/b]
有添加自然就会有删除
如图所示,简简单单的几个字却要这么多话来为它解释。
具体工作流程这里就不赘述了
[b]二、带详细注释的源代码 [/b]
2012-02-25 李海沿
刚才我们整理了一大批乏味的知识点,但是相信大家已经大概的了解了sysfs 的原理了。
这里我们趁热打铁,将前面我们那个似懂非懂的kobject程序一步拿下。
我们这个程序的目的是,在sys目录下面创建一个kboject_test目录和一个名为kobject_test的属性文件,我们可以使用cat去读取其文件名。
前面虽然解释了kobject程序的大概工作流程,这次我们再次详细的说明一下其工作流程,然后再附上今天注有详细解释的kobject驱动程序代码:
[b]一、工作流程: [/b]
[b]1. 定义kobject结构体 [/b]
kboject结构体定义如下:
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; //是否支持热拔 } |
[b]2. 定义kobj_type结构体 [/b]
kobje结构体定义如下:
struct kobj_type { void (*release)(struct kobject *kobj); //释放kobject和其他占用资源的函数 struct sysfs_ops *sysfs_ops; //操作属性的方法 struct attribute **default_attrs; //属性数组 }; |
[b]2.1 release函数实现 属性释放方法 [/b]
这里我们release函数只是简单的打印一句话,实际项目中的release可能包含各种代码,视具体功能而定
[b]2.2 sysfs_ops结构体 属性操作方法 [/b]
如图所示,sys_ops中就是定义了对属性文件的读写操作调用的函数
其原型结构体如下:
struct sysfs_ops{ ssize_t (*show)(struct kobject *,struct attribute *,char *); //读属性操作函数 ssize_t (*store)(struct kobject *,struct attribute *,const char *,size_t); //写属性操作函数 }; |
在注释中已经讲得很详细了,它也可以理解为在sys的文件夹中的属性文件,结构体就对应属性文件
[b]2.3.1 test_attr属性结构体[/b]
同样在代码中已经解释的很详细了,可以这样理解,这个结构体中所有的属性就是在属性文件中的文件内容
其原型如下:
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); |
到此为止,我们呢已经将kobject基本的属性、方法等都实现了,下面自然就是将它加入结构体,告诉操作系统啊,
我们此处init函数唯一的操作就是将它加入注册进入操作系统,让操作系统认识这个结构体。
[b]4. 从内核中删除操作系统 [/b]
有添加自然就会有删除
如图所示,简简单单的几个字却要这么多话来为它解释。
具体工作流程这里就不赘述了
[b]二、带详细注释的源代码 [/b]
#include <linux/device.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/string.h> #include <linux/sysfs.h> #include <linux/stat.h> //定义一个名为kobject_test,可以读写的属性 //这个结构体就是定义我们 /sys/kobject_test/kobject_test属性文件的属性 //当我们使用cat去读时, //系统会调用kobject_test_show从而打印出属性文件的name属性 //并且我们可以通过echo "Lover雪儿" > kobject_test命令去写入时 //系统会调用kobject_test_store将.name这个属性修改为我们自定义的"Lover雪儿" //总结一下,它的功能就是 /sys/kobject_test/下面的属性文件 struct attribute test_attr = { .name = "kobject_test", //属性名 .mode = S_IRWXUGO, //属性为可读可写 }; //我们要使用kobject自然就要定义一个kobject属性 //其实这个结构体就是 会在 /sys/目录下建立一个文件夹 //文件夹的名字在init函数kobject_init_and_add中定义的那个名字 //总结一下,这个结构体的功能就是在sys目录下建立这个文件夹 //然后我们文件夹中有的属性文件,只要在它下面添加就行了 //该kobject只有一个属性就是前面定义的test_attr static struct attribute *def_attrs[] = { &test_attr, NULL, }; //当kobject的引用计数为0时,会自动调用此函数, //当我们在exit函数中调用kobject_del(&kobj);时 //在del中主要的操作就是在sysfs中删除kobj //然后将kboj从kset集合中删除 //然后将kobj的父目录设置为空 //最重要的是将父目录的引用计数设为0 , //系统检测到引用计数为0,就会调用此函数 void kobject_test_release(struct kobject *kobject){ printk("kobject_test: kobject_test_release() . \n"); } //读属性的名字 //在系统空间当我们使用cat命令对属性文件进行读取时, //系统就会自动调用此函数,将前面我们test_attr的.name属性打印出来 ssize_t kobject_test_show(struct kobject *kobject, struct attribute *attr, char *buf){ printk("call kobject_test_show(). \n"); /*调试信息*/ printk("attrname: %s.\n",attr->name); //打印属性名字 sprintf(buf,"%s\n",attr->name); //将名字方法buf中返回用户空间 return strlen(attr->name) + 2; } //写一属性的值 //和前面读属性函数差不多,这里就是把我们的test_attr的.name属性重新赋一个值 ssize_t kobject_test_store(struct kobject *kobject,struct attribute *attr, const char *buf, size_t count){ printk("call kobject_test_store(). \n"); /*调试信息*/ printk("write: %s.\n",buf); //打印属性名字 strcpy(attr->name, buf); //写一个属性 return count; } //前面我们实现了对属性文件读和写的方法, //但是操作系统如何才知道那两个函数时读写函数 //重点就在这里,和以前我们的字符函数file_operation差不多 //这里就是告诉系统,当发生读写操作时,分别调用什么函数 struct sysfs_ops obj_test_sysops = { .show = kobject_test_show, //属性读函数 .store = kobject_test_store, //属性写函数 }; //后面代码中我们使用struct kobject kobj; //但是kobj的属性只是一个空的结构体而已 //它又有哪些属性呢,答案就在这里,这里定义了kobject的默认属性 //.realease 当删除kobject时会调用的函数 //.sysfs_ops 当系统对属性文件进行读写是,会调用的函数,也就是前面我们的sysfs_ops这个结构体 //.default_atrs 默认的属性,就是定义我们/sys/kobject/目录下有哪些属性文件 struct kobj_type ktype={ .release = kobject_test_release, //释放函数 .sysfs_ops = &obj_test_sysops, //属性的操作函数 .default_attrs = def_attrs, //默认属性 }; //此处定义我们的kobject结构体 struct kobject kobj; //要添加的kobject结构 //初始化函数 static int kobject_test_init(void){ printk("kobject test_init(). \n"); //此处,就是将我们的kobject函数注册进入系统。 //arg1:既然要注册kobject,此处自然是我们前面定义的kboj这个机构提 //arg2:ktype前面我定义的属性,这里就是将我们的kobject和ktype联系起来 //arg3:此处就是定义kobj的父kobject结构体 //arg4:此处就是定义我们kobject的属性的目录名字 kobject_init_and_add(&kobj, &ktype, NULL, "kobject_test"); return 0; } static int kobject_test_exit(void){ printk("kobject test_exit. \n"); //前面说过了 //当我们在exit函数中调用kobject_del(&kobj);时 //在del中主要的操作就是在sysfs中删除kobj //然后将kboj从kset集合中删除 //然后将kobj的父目录设置为空 //最重要的是将父目录的引用计数设为0 , //系统检测到引用计数为0,就会调用前面的release函数 kobject_del(&kobj); //删除kobject return 0; } module_init(kobject_test_init); module_exit(kobject_test_exit); MODULE_AUTHOR("Lover雪儿"); MODULE_LICENSE("Dual BSD/GPL");
相关文章推荐
- 20150223 IMX257 设备驱动模型之Kobject(一)
- 20150225 IMX257 设备驱动模型之sysfs文件系统知识点整合(二)
- 20150225 IMX257 总线设备驱动模型编程之总线篇
- 20150226 IMX257 总线设备驱动模型编程之总线篇(二)
- 20150226 IMX257 总线设备驱动模型编程之设备篇
- 20150226 IMX257 总线设备驱动模型编程之驱动篇
- 20150226 IMX257 总线设备驱动模型编程之平台总线设备platform
- 嵌入式Linux驱动笔记(十六)------设备驱动模型(kobject、kset、ktype)
- 设备驱动基础0:设备模型之kobject,kset及其关系
- linux内核驱动设备模型五之kobject (设备驱动模型的基石)
- LINUX设备驱动之设备模型一--kobject
- 设备驱动模型的基石kobject
- 设备驱动基础0:设备模型之kobject,kset及其关系
- linux内核部件分析(五)——设备驱动模型的基石kobject
- 嵌入式 linux下kernel代码中设备驱动模型的基石kobject
- Linux内核部件分析 设备驱动模型的基石kobject
- Linux内核部件分析<5> 设备驱动模型的基石kobject
- Linux内核部件分析--设备驱动模型的基石kobject
- LINUX设备驱动之设备模型一--kobject
- Linux kernel驱动相关抽象概念及其实现 之“linux设备模型kobject,kset,ktype”