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

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 <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 //定义一个名为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);        //删除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");

时间: 2024-10-25 23:13:04

20150223 IMX257 设备驱动模型之Kobject(一)的相关文章

20150225 IMX257 设备驱动模型之Kobject(三)

20150225 IMX257 设备驱动模型之Kobject(三) 2012-02-25 李海沿 刚才我们整理了一大批乏味的知识点,但是相信大家已经大概的了解了sysfs 的原理了. 这里我们趁热打铁,将前面我们那个似懂非懂的kobject程序一步拿下. 我们这个程序的目的是,在sys目录下面创建一个kboject_test目录和一个名为kobject_test的属性文件,我们可以使用cat去读取其文件名. 前面虽然解释了kobject程序的大概工作流程,这次我们再次详细的说明一下其工作流程,然

20150225 IMX257 设备驱动模型之sysfs文件系统知识点整合(二)

20150225 IMX257 设备驱动模型之sysfs文件系统知识点整合(二) 2012-02-25 李海沿 前天我们实现了一个简单的sysfs的kobject的驱动程序,可是有没有发现很多东西都不懂,原因就是在我们对sysfs和kobject的工作原理不懂,虽然我一直不提倡整天接触那些乏味的知识点,也一直不喜欢谈论太多的知识点,但是有的时候,理论知识是实践的基础,有些基础的知识点还是不得不提,下面进入正题. 一.sysfs介绍 在linux2.6内核以后,引入了一个新的文件系统sysfs,它

20150225 IMX257 总线设备驱动模型编程之总线篇

20150225 IMX257 总线设备驱动模型编程之总线篇 2015-02-25 19:40 李海沿 从现在开始,我们开始来实现 总线-设备-驱动模型中的总线.. 我们这个程序的目标是在 sysfs文件系统的/sys/bus/ 目录下面建立一个文件夹. 一.总线介绍 1. 总线数据结构bus_type struct bus_type 结构体的定义如下: struct bus_type { const char *name; --总线名 struct bus_attribute *bus_att

20150226 IMX257 总线设备驱动模型编程之平台总线设备platform

20150226 IMX257 总线设备驱动模型编程之平台总线设备platform 2015-02-26 李海沿 前面我们实现了总线设备驱动模型,下面我们来了解一下平台总线,平台设备驱动 分为平台设备和平台驱动两种,和前面所说的设备驱动差不多 platform总线是一种虚拟的总线,相应的设备则为platform_device,而驱动则为platform_driver.Linux 2.6的设备驱动模型中,把I2C.RTC.LCD等都归纳为platform_device. 一.平台设备介绍 1. p

20150226 IMX257 总线设备驱动模型编程之设备篇

20150226 IMX257 总线设备驱动模型编程之设备篇 2015-02-26 李海沿 前面我们呢实现了总线-设备-驱动模型中的总线,自然,我们的目标就是在我们建立的总线下面创建一个设备. http://www.cnblogs.com/lihaiyan/p/4301072.html 一.程序分析 1. 包含总线 既然我们的设备在总线上,自然我们既要包含总线了 如图所示,使用外部声明将我们的总线的结构体包含进来 2. 定义设备结构体 父目录为 my_bus 3. 定义属性文件结构体 属性文件结

20150226 IMX257 总线设备驱动模型编程之驱动篇

20150226 IMX257 总线设备驱动模型编程之驱动篇 2015-02-26 11:42 李海沿 前面我们已经实现了 总线和设备 的驱动程序,接下来我们的任务就是 实现 驱动 了 地址:http://www.cnblogs.com/lihaiyan/p/4301079.html http://www.cnblogs.com/lihaiyan/p/4301072.html 在实现驱动程序之前,我们来想两个问题: 一.问题分析 1.什么时候驱动程序会在总线上找它可以处理的设备? 在driver

字符设备驱动模型

1.设备描述结构cdev驱动模型种类繁多,这就需要我从众多的模型中提取出他们的一些共性:a.驱动初始化a.1 分配设备描述结构a.2 初始化设备描述结构a.3 注册设备描述结构a.4 硬件初始化b.实现设备操作c.驱动注销 ------------------------------------------------------------------ 设备描述结构:在任何一种驱动模型中,设备都会用的内核中的一种结构来描述,我们的字符设备在内核中使用struct cdev 来来描述.struc

Linux内核部件分析 设备驱动模型之device

来源:Linux社区 -- http://www.linuxidc.com/Linux/2011-10/44627p6.htm 作者 : qb_2008 linux的设备驱动模型,是建立在sysfs和kobject之上的,由总线.设备.驱动.类所组成的关系结构.从本节开始,我们将对linux这一设备驱动模型进行深入分析. 头文件是include/linux/device.h,实现在drivers/base目录中.本节要分析的,是其中的设备,主要在core.c中. struct device {

字符设备驱动、平台设备驱动、设备驱动模型、sysfs的关系

Linux驱动开发的童鞋们来膜拜吧:-)  学习Linux设备驱动开发的过程中自然会遇到字符设备驱动.平台设备驱动.设备驱动模型和sysfs等相关概念和技术.对于初学者来说会非常困惑,甚至对Linux有一定基础的工程师而言,能够较好理解这些相关技术也相对不错了.要深刻理解其中的原理需要非常熟悉设备驱动相关的框架和模型代码.网络上有关这些技术的文章不少,但多是对其中的某一点进行阐述,很难找到对这些技术进行比较和关联的分析.对于开发者而言,能够熟悉某一点并分享出来已很难得,但对于专注传授技术和经验给