平台总线的简介

  平台总线是一种虚拟的总线,相应的设备则为platform_device,而驱动则为platform_driver。总线将设备和驱动绑定,在系统每注册一个设备的时候,会寻找与之匹配的驱动;相反的,在系统每注册一个驱动的时候,会寻找与之匹配的设备,而匹配由总线完成。

  我们可以把一个驱动程序抽出来分为两部分,一部分是硬件相关的dev,另一部分则是稳定的纯软件部分driver。而总线只是一种机制,把dev和driver这两部分建立“联系”的机制。

eg:

①dev部分

  a.把device放入bus的dev链表

  b.从bus的drv链表取出每一个drv,用bus的match函数判断drv是否支持dev

  c.如果支持,将调用drv的probe函数

 

②drv部分

  a.把driver放入bus的drv链表

  b.从bus的dev链表取出每一个dev,用bus的match函数判断dev是否支持drv

  c.如果支持,将调用drv的probe函数

 

  当内核需要调用probe函数时,它会调用driver->probe,在driver->probe中再调用platform_driver->probe

**********************************************************

!static 修饰的变量/函数本模块其他文件不能引用,其他模块(工程)使用时需要符号导出。

设备模型:即基于软件层面的驱动模型。
我们用总线来管理设备和驱动,两者用总线分开了,便于移植灵活!

 

基本驱动模型:
设备:struct device
      |
_____________________

 

总线bus:struct bus_type| //有匹配规则 //
_____________________
      |
驱动:struct device_driver ==>probe函数 拿到设备资源

 

模型总线modelbus开发python 简述platform总线模型机制_#include

********************1.struct bus_type *************************
  90 struct bus_type {
  91     const char      *name;  //总线类型名
  92     const char      *dev_name;
  93     struct device       *dev_root;
  94     struct bus_attribute    *bus_attrs;   //总线属性
  95     struct device_attribute *dev_attrs;//设备属性,为每个加入总线的设备建立属性链表
  96     struct driver_attribute *drv_attrs; //驱动属性,为每个加入总线的驱动建立属性链表
  97 
  98     int (*match)(struct device *dev, struct device_driver *drv);  //匹配函数
		/*当一个新设备或者驱动被添加到这个总线时,这个方法会被调用一次或多次,若指定的驱动程序能够处理指定的设备,则返回非零值。必须在总线层使用这个函数,因为那里存在正确的逻辑,核心内核不知道如何为每个总线类型匹配设备和驱动程序*/
  99     int (*uevent)(struct device *dev, struct kobj_uevent_env *env);
 100     int (*probe)(struct device *dev);
 101     int (*remove)(struct device *dev);  //设备移除调用操作
 102     void (*shutdown)(struct device *dev);
 103 
 104     int (*suspend)(struct device *dev, pm_message_t state);
 105     int (*resume)(struct device *dev);
 106 
 107     const struct dev_pm_ops *pm;
 108 
 109     struct iommu_ops *iommu_ops;
 110 
 111     struct subsys_private *p;//一个很重要的域,包含了device链表和drivers链表
 112 };************************2.struct device ****************************
 633 struct device {
 634     struct device       *parent;
 635 
 636     struct device_private   *p;
 637 
 638     struct kobject kobj;
 639     const char      *init_name; /* initial name of the device */   //设备名字 /sys/bus/devices   
		//注意:使用完也就是注册后被循环链表加入,内核自动置为NULL
 640     const struct device_type *type;
 641 
 642     struct mutex        mutex;  /* mutex to synchronize calls to
 643                      * its driver.
 644                      */
 645 
 646     struct bus_type *bus;       /* type of bus device is on */	  	//关联的总线名字
 647     struct device_driver *driver;   /* which driver has allocated this  device */  
										//对应驱动,不能初始化,匹配成功后总线自动将对应该驱动地址交给该大的设备
 649     void        *platform_data; /* Platform specific data, device        //给驱动传递硬件资源
 689     void    (*release)(struct device *dev);  //释放总线********************3.struct device_driver**************************
 215 struct device_driver {                                                                                       
 216     const char      *name;  //驱动程序的名字
 217     struct bus_type     *bus; //驱动程序所操作的总线类型
 218 
 219     struct module       *owner;
 220     const char      *mod_name;  /* used for built-in modules */
 221 
 222     bool suppress_bind_attrs;   /* disables bind/unbind via sysfs */
 223 
 224     const struct of_device_id   *of_match_table;
 225 
 226     int (*probe) (struct device *dev);//匹配成功后会自动调用该函数/查询一个特定设备是否存在及驱动是否可以使用它的函数
 227     int (*remove) (struct device *dev);  //将设备从系统中删除
 228     void (*shutdown) (struct device *dev);
 229     int (*suspend) (struct device *dev, pm_message_t state);
 230     int (*resume) (struct device *dev);
 231     const struct attribute_group **groups;
 232 
 233     const struct dev_pm_ops *pm;
 234 
 235     struct driver_private *p;
 236 }; 
1043 #define module_driver(__driver, __register, __unregister, ...) \ //注意其局限性
1044 static int __init __driver##_init(void) \
1045 { \
1046     return __register(&(__driver) , ##__VA_ARGS__); \
1047 } \
1048 module_init(__driver##_init); \
1049 static void __exit __driver##_exit(void) \
1050 { \
1051     __unregister(&(__driver) , ##__VA_ARGS__); \
1052 } \
1053 module_exit(__driver##_exit);
1054 
1055 #endif /* _DEVICE_H_ */          
 114 /* This is a #define to keep the compiler from merging different
 115  * instances of the __key variable */
 116 #define bus_register(subsys)            \        //调用bus_register函数注册总线 
 117 ({                      \
 118     static struct lock_class_key __key; \
 119     __bus_register(subsys, &__key); \
 120 }) 915 /**                    
 916  * __bus_register - register a driver-core subsystem
 917  * @bus: bus to register
 918  * @key: lockdep class key
 919  *
 920  * Once we have that, we register the bus with the kobject
 921  * infrastructure, then register the children subsystems it has:
 922  * the devices and drivers that belong to the subsystem.
 923  */ 
 924 int __bus_register(struct bus_type *bus, struct lock_class_key *key) 
 115 void bus_unregister(struct bus_type *bus);  //当必须从系统中删除一个总线时调用

 

1 #ifndef MYDEVICE_H_
2 #define MYDEVICE_H_
3 
4 struct hehedevice {
5     struct device dev;
6     char name[64];
7 };
8 
9 #endif

 

1 obj-m    := bus.o drv.o drv2.o dev0.o dev1.o dev2.o
2 
3 KERNEL    := /linux-3.5
4 
5 all:
6     make -C $(KERNEL) M=`pwd`
7 clean:
8     make -C $(KERNEL) M=`pwd` clean
9

drv.c

1 #include <linux/init.h>
 2 #include <linux/module.h>
 3 #include <linux/device.h>
 4 
 5 #include "mydevice.h"
 6 
 7 extern struct bus_type platform_hehe;//外部引用总线结构体对象
 8 
 9 static int hehe_probe (struct device *dev)//匹配成功后自动获取相应设备结构体地址
10 {
11     struct hehedevice *ptr = container_of(dev, struct hehedevice, dev);//获取设备大结构体地址
12 
13     printk("%s driver has been matched %s device ok la!\n",
14             dev->driver->name, ptr->name);//用驱动尽力去匹配设备
15 
16     return 0;
17 }
18 
19 static int hehe_remove (struct device *dev)//将设备从系统中移除
20 {
21     printk("%s driver has been removed!\n",
22             dev->driver->name);
23 
24     return 0;
25 }
26 
27 static struct device_driver driverhehe = {//定义驱动结构体
28     .name    =  "summer",        //驱动程序的名字
29     .bus    =  &platform_hehe,    //关联的总线名字
30     .probe    =  hehe_probe,        //匹配成功后自动调用该函数
31     .remove    =  hehe_remove,        //移除函数
32 };
33 
34 module_driver(driverhehe, driver_register, driver_unregister);////模块注册和移除 
35 
36 MODULE_LICENSE("GPL");
37 
38 MODULE_AUTHOR("millet9527");
39 MODULE_VERSION("millet plus 18");
40 MODULE_DESCRIPTION("example for driver module arch");

drv2.c

1 #include <linux/init.h>
 2 #include <linux/module.h>
 3 #include <linux/device.h>
 4 
 5 #include "mydevice.h"
 6 
 7 extern struct bus_type platform_hehe;
 8 
 9 static int hehe_probe (struct device *dev)
10 {
11     struct hehedevice *ptr = container_of(dev, struct hehedevice, dev);
12 
13     printk("%s driver has been matched %s device ok la!\n",
14             dev->driver->name, ptr->name);
15 
16     return 0;
17 }
18 
19 static int hehe_remove (struct device *dev)
20 {
21     printk("%s driver has been removed!\n",
22             dev->driver->name);
23 
24     return 0;
25 }
26 
27 static struct device_driver driverhehe2 = {
28     .name    =  "summer2",
29     .bus    =  &platform_hehe,
30     .probe    =  hehe_probe,
31     .remove    =  hehe_remove,
32 };
33 
34 module_driver(driverhehe2, driver_register, driver_unregister);
35 
36 MODULE_LICENSE("GPL");
37 
38 MODULE_AUTHOR("millet9527");
39 MODULE_VERSION("millet plus 18");
40 MODULE_DESCRIPTION("example for driver module arch");

dev0.c

1 #include <linux/init.h>
 2 #include <linux/module.h>
 3 #include <linux/device.h>
 4 
 5 #include "mydevice.h"
 6 
 7 extern struct bus_type platform_hehe;//外部引用总线结构体对象
 8 
 9 static void    hehe_release (struct device *dev)//释放
10 {
11     struct hehedevice *ptr = container_of(dev, struct hehedevice, dev);//获取该定义的设备大结构体地址
12 
13     printk("%s device is release!\n", ptr->name);
14 }
15 
16 
17 static struct hehedevice hehedevice0 = {//定义一个具体设备
18     .name    =    "summer0",//具体名字,一直存在
19     .dev    = {
20         .init_name = "summer0",        //要匹配的设备名字////注意:使用完也就是注册后被循环链表加入,内核自动置为NULL 
21         .bus       = &platform_hehe,//关联的总线名字
22         .release   = hehe_release,    //释放总线?
23     }    
24 };
25 
26 
27 static int __init demo_init(void)
28 {
29     return device_register(&hehedevice0.dev);//注册设备
30 }
31 
32 module_init(demo_init);
33 
34 
35 static void __exit demo_exit(void)
36 {
37     device_unregister(&hehedevice0.dev);//移除设备
38 }
39 
40 module_exit(demo_exit);
41 
42 MODULE_LICENSE("GPL");
43 
44 MODULE_AUTHOR("millet9527");
45 MODULE_VERSION("millet plus 18");
46 MODULE_DESCRIPTION("example for driver module arch");

dev1.c

1 #include <linux/init.h>
 2 #include <linux/module.h>
 3 #include <linux/device.h>
 4 
 5 #include "mydevice.h"
 6 
 7 extern struct bus_type platform_hehe; 
 8 
 9 static void    hehe_release (struct device *dev)
10 {
11     struct hehedevice *ptr = container_of(dev, struct hehedevice, dev);
12 
13     printk("%s device is release!\n", ptr->name);
14 }
15 
16 
17 static struct hehedevice hehedevice1 = {
18     .name    =    "summer1",
19     .dev    = {
20         .init_name = "summer1",
21         .bus       = &platform_hehe,
22         .release   = hehe_release,        
23     }    
24 };
25 
26 
27 static int __init demo_init(void)
28 {
29     return device_register(&hehedevice1.dev);
30 }
31 
32 module_init(demo_init);
33 
34 
35 static void __exit demo_exit(void)
36 {
37     device_unregister(&hehedevice1.dev);
38 }
39 
40 module_exit(demo_exit);
41 
42 MODULE_LICENSE("GPL");
43 
44 MODULE_AUTHOR("millet9527");
45 MODULE_VERSION("millet plus 18");
46 MODULE_DESCRIPTION("example for driver module arch");

dev2.c

1 #include <linux/init.h>
 2 #include <linux/module.h>
 3 #include <linux/device.h>
 4 
 5 #include "mydevice.h"
 6 
 7 extern struct bus_type platform_hehe; 
 8 
 9 static void    hehe_release (struct device *dev)
10 {
11     struct hehedevice *ptr = container_of(dev, struct hehedevice, dev);
12 
13     printk("%s device is release!\n", ptr->name);
14 }
15 
16 
17 static struct hehedevice hehedevice2 = {
18     .name    =    "summer2",
19     .dev    = {
20         .init_name = "summer2",
21         .bus       = &platform_hehe,
22         .release   = hehe_release,        
23     }    
24 };
25 
26 
27 static int __init demo_init(void)
28 {
29     return device_register(&hehedevice2.dev);
30 }
31 
32 module_init(demo_init);
33 
34 
35 static void __exit demo_exit(void)
36 {
37     device_unregister(&hehedevice2.dev);
38 }
39 
40 module_exit(demo_exit);
41 
42 MODULE_LICENSE("GPL");
43 
44 MODULE_AUTHOR("millet9527");
45 MODULE_VERSION("millet plus 18");
46 MODULE_DESCRIPTION("example for driver module arch");