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

发布者:轻松自在最新更新时间:2024-08-15 来源: elecfans 手机看文章 扫描二维码
随时随地手机看文章

接下来我们开始涉及设备驱动模型,从简入深,我们先写一个驱动,实现的功能就是在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');


引用地址:IMX257 设备驱动模型之Kobject(一)

上一篇:IMX257 设备驱动模型之sysfs文件系统知识点整合(二)
下一篇:IMX257 BEEP驱动程序实现

推荐阅读最新更新时间:2024-11-02 17:54

IMX257 输入子系统
一、输入子系统 1.输入子系统结构体定义 struct input_dev{ const char *name; 设备名 const char *phys; 设备在系统中路径 const char *uniq; struct input_id id; 用于匹配input hander参数 unsigned long propbit ; unsigned long evbit ; //设备所支持事件类型,主要有EV_SYNC,EV_KEY,EV_REL,EV_ABS等 unsigned long keybit ; //按键所对应的位图 unsigned long relbit ; //相对坐标对应位图 u
[单片机]
<font color='red'>IMX257</font> 输入子系统
IMX257 总线设备驱动模型编程之设备篇
一、程序分析 1. 包含总线 既然我们的设备在总线上,自然我们既要包含总线了 如图所示,使用外部声明将我们的总线的结构体包含进来 2. 定义设备结构体 父目录为 my_bus 3. 定义属性文件结构体 属性文件结构体可以有一下得到: //产生后面的 bus_attr_version 结构体 static DEVICE_ATTR(dev,S_IRUGO,mydev_show,NULL); 如图所示: 4. 在初始化函数中 如图所示: 在初始化函数中, 先初始化设备的名字,这个名字用于于驱动名字进行匹配 然后注册设备,让系统认识这个设备,在/sys/device/my_bus0 下面就会有my_dev这个设备 最
[单片机]
<font color='red'>IMX257</font> 总线<font color='red'>设备驱动</font><font color='red'>模型</font>编程之设备篇
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved