2016年(2)
分类: LINUX
2016-06-23 14:53:07
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进行匹配),需要重点关注的是总线的匹配函数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中实现,一般这个函数在驱动的初始化过程调用。
通过这三步,就将平台总线,设备,驱动关联起来。