Chinaunix首页 | 论坛 | 博客
  • 博客访问: 13775
  • 博文数量: 2
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 20
  • 用 户 组: 普通用户
  • 注册时间: 2016-03-13 09:56
文章分类
文章存档

2016年(2)

我的朋友
最近访客

分类: LINUX

2016-06-23 14:53:07

一、总线设备驱动注册流程
    首先,我们以下面这个图片来大致了解下其流程,(图片是我找别人的);

在看这个流程之前,我们先看看linux内核中是如何描述总线、设备和驱动的;

    linux内核中分别用struct bus_type,struct device和struct device_driver来描述总线、设备和驱动。

总线:

50 struct bus_type {
 51     const char      *name;
 52     struct bus_attribute    *bus_attrs;
 53     struct device_attribute *dev_attrs;
 54     struct driver_attribute *drv_attrs;
 55
 56 <strong><span style="color:#ff0000;">int (*match)(struct device *dev, struct device_driver *drv);span>strong> 。。。
 68 };
设备:
406 struct device {  407 struct device       *parent; 408 409 struct device_private   *p; 410  411 struct kobject kobj;  412 const char *init_name; /* initial name of the device */ 413 struct device_type  *type; 414 415 struct mutex        mutex; /* mutex to synchronize calls to
416                      * its driver.
417                      */ 418 "color:#ff0000;"> 419 struct bus_type *bus; /* type of bus device is on */  420 struct device_driver *driver; /* which driver has allocated this
421                        device */ 。。。 456 457 void (*release)(struct device *dev);  458 };
驱动:
122 struct device_driver { 123 const char      *name; <strong><span style="color:#ff0000;"> 124     struct bus_type     *bus;span>strong> 125
126     struct module       *owner;
127     const char      *mod_name;  /* used for built-in modules */
128
129     bool suppress_bind_attrs;   /* disables bind/unbind via sysfs */
130
131 #if defined(CONFIG_OF)
132     const struct of_device_id   *of_match_table;
133 #endif
134 <strong><span style="color:#ff0000;"> 135     int (*probe) (struct device *dev);span>strong> 136     int (*remove) (struct device *dev);
。。。
 };

上述三个结构体中,我将下文需要使用的成员进行了标识,后面会讨论到。

对比上面的三个结构体,你会发现:总线中既定义了设备,也定义了驱动;设备中既有总线,也有驱动;驱动中既有总线也有设备相关的信息。那这三个的关系到底是什么呢?

三者的关系是:

内核要求每次出现一个设备,就要向总线汇报,会着说注册;每次出现一个驱动,也要向总线汇报,或者叫注册。比如系统初始化时,会扫描连接了 哪些设备,并为每一个设备建立一个struct device变量,并为每一个驱动程序准备一个struct device_driver结构的变量。把这些量变量加入相应的链表,形成一条设备链表和一条驱动量表。这样,总线就能通过总线找到每一个设备和每一个驱 动程序。

当一个struct device诞生,总线就会去driver链表找设备对应的驱动程序。如果找到就执行设备的驱动程序,否则就等待。反之亦然。

还有一个需要注意的地方:

usb_type结构体的match函数,它的两个参数一个是驱动,另一个则是设备。这个函数就是用来进行判断,总线上的驱动程序能不能处理设备的。至于这个函数什么时候调用,怎么调用,后面会有说。

从图中我们可以看出;驱动挂接到总线上时,与总线上的所有设备进行匹配(用bus_type.match进行匹配),
            如果匹配成功,则调用bus_type.probe或者driver.probe初始化该设备;挂接到总线上
            如果匹配失败,则只是将该驱动挂接到总线上。

需要重点关注的是总线的匹配函数match(),驱动的初始化函数probe()

1. platform_bus_type--总线先被kenrel注册。

2. 系统初始化过程中调用platform_add_devices或者platform_device_register,将平台设备(platform devices)注册到平台总线中(platform_bus_type)
3. 平台驱动(platform driver)与平台设备(platform device)的关联是在platform_driver_register或者driver_register中实现,一般这个函数在驱动的初始化过程调用。

通过这三步,就将平台总线,设备,驱动关联起来。





阅读(1666) | 评论(0) | 转发(0) |
0

上一篇:驱动基础(一)-- module_init,module_exit。

下一篇:没有了

给主人留下些什么吧!~~