平台总线的简介
平台总线是一种虚拟的总线,相应的设备则为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函数 拿到设备资源
********************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");