总线(bus)、设备(device)、驱动(driver)三者构成了设备驱动的模型

来源:互联网 发布:淘宝网圾踞一代皮鞋 编辑:程序博客网 时间:2024/05/17 06:37

一个设备只能绑定一个驱动,但是一个驱动可以适合多个设备。

总线(bus)、设备(device)、驱动(driver)三者构成了设备驱动的模型,三者有着紧密的联系,那么他们到底是如何联系起来完成一个外围硬件设备的控呢?

1、首先看看他们各自的结构体

1)、bus的结构体bus_type.

struct bus_type {
const char  * name;
struct subsystem subsys;//代表自身
struct kset  drivers;   //当前总线的设备驱动集合
struct kset  devices; //所有设备集合
struct klist  klist_devices;
struct klist  klist_drivers;
struct bus_attribute * bus_attrs;//总线属性
struct device_attribute * dev_attrs;//设备属性
struct driver_attribute * drv_attrs;
int  (*match)(struct device * dev, struct device_driver * drv);//设备驱动匹配函数
int  (*uevent)(struct device *dev, char **envp,   
      int num_envp, char *buffer, int buffer_size);//热拔插事件
int  (*probe)(struct device * dev);
int  (*remove)(struct device * dev);
void  (*shutdown)(struct device * dev);
int  (*suspend)(struct device * dev, pm_message_t state);
int  (*resume)(struct device * dev);
};

2、device的结构体

struct device {
struct device  * parent; //父设备,一般一个bus也对应一个设备。
struct kobject kobj;//代表自身
char bus_id[BUS_ID_SIZE]; 
struct bus_type * bus;  /* 所属的总线 */
struct device_driver *driver; /* 匹配的驱动*/
void  *driver_data; /* data private to the driver 指向驱动 */
void  *platform_data; /* Platform specific data,由驱动定义并使用*/
///更多字段忽略了
};

3、driver的结构体

struct device_driver {
const char  * name;
struct bus_type  * bus;//所属总线
struct completion unloaded;
struct kobject  kobj;//代表自身
struct klist  klist_devices;//设备列表
struct klist_node knode_bus;
struct module  * owner;
int (*probe) (struct device * dev);
int (*remove) (struct device * dev);
void (*shutdown) (struct device * dev);
int (*suspend) (struct device * dev, pm_message_t state);
int (*resume) (struct device * dev);
};

现在将基于以上三个结构体来说明bus、device、driver是如何联系起来的

要非常注意到bus结构体中的struct kset  drivers与struct klist  klist_devices,struct kset  devices与struct klist  klist_drivers这两组结构体,这两组结构体代表挂载到总线的所有设备和驱动,分别被归类到各自的链表中。那么所有的设备和驱动都注册汇总到了这个bus结构体中,从何bus 和 device、driver都建立了联系。

struct device中有两个成员struct bus_type * bus和struct device_driver *driver ,其中前者指向了其所属的总线,后者指向了其对应的驱动,注意该驱动是单个对象,也就是说这个设备只能绑定这个驱动,即一个设备只能绑定一个驱动。这样device和bus、driver都建立了联系。

struct device_driver中有成员structbus_type*bus和structklistklist_devices, 其中前者只想了其所属的总线,后者指向了其能匹配的设备链表,注意该驱动能匹配的设备是一个链表,也就是一系列的设备,即一个驱动能被多个设备所绑定。这样driver和bus、device建立的联系。

通过以上三个结构体的关系,让bus、device、driver联系在一起。

在系统实际运行过程中的关系建立过程如下:系统启动过程中,会检测硬件系统连接了那些设备,每检测到一个设备就建立一个struct device对象,并加入到 struct kset  drivers与struct klist  klist_devices这组设备链表中;如果没注册一个驱动,就建立一个struct device_driver设备驱动驱动对象,并注册到struct kset  devices与struct klist  klist_drivers驱动链表中。这样,通过总线bus可以找到每一个设备和每一个驱动。

另外,对于设备和驱动建立联系要分两种情况讨论:1)、系统启动之前硬件设备插好在系统上,那么系统启动的时候就检测到这个硬件设备,然后建立一个struct device对象,加入bus结构体的device链表中,在每注册一个驱动的时候就去device结构体中检测每一个device是否有没有被绑定驱动的,这一步主要是检测struct device结构体中的structdevice_driver 指针仍为空,若为空则检测是否能否支持该设备,若发现可以支持该设备就调用device_bind_driver函数来绑定该设备,那么,该设备就有了驱动。换句话说,把structdevice 中的structdevice_driver driver 指向这个驱动,而struct device_driver driver 把struct device 加入他的那structklist klist_devices链表中来。那么,设备和驱动就联系上了。如果设备没有匹配上驱动,则就是没有驱动程序的设备,用户和系统是调用不了这个设备的。2)、热拔插硬件设备情况的话,硬件设备是在任何时间都可能出现,一旦 一个热拔插设备插入系统,那么系统必须马上建立一个struct device对象给这个设备,并且加入device链表中,然后这个设备会到bus的驱动链表中寻找符合自己的驱动;同样的道理,一个新的驱动在被安装的时候,系统马上为其建立一个struct device_driver对象,并加入到driver链表中,然后这个驱动会到设备链表中寻找能支持的设备。这个就是驱动和设备建立关系的过程,挺有意思。

0 0
原创粉丝点击