既然说到了bus device driver驱动模型那当然就要分析一下这三个对应的结构体
BUS结构体
<pre name="code" class="cpp">struct bus_type {
const char * name;
struct module * owner;
int (*match)(struct device * dev, struct device_driver * drv);//Bus提供的match函数,无论是device注册还是driver注册都会调用这个函数进行匹配
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 (*suspend_late)(struct device * dev, pm_message_t state);
int (*resume_early)(struct device * dev);
int (*resume)(struct device * dev);
unsigned int drivers_autoprobe:1;//为什么要用位域,不是说位域同台通用性很差么?
};
plantform_device结构体
struct platform_device {
const char * name;//这个名字是Bus结构体里面match函数用来将和driver比较的
u32 id;
struct device dev;//device注册过程使用的是这个结构体
u32 num_resources;//device包含的资源数目
struct resource * resource;<span style="font-family: Arial, Helvetica, sans-serif;">//device包含的资源这些完全与硬件相关</span>
};
plantform_device用到的
resource结构体
struct resource {
resource_size_t start;
resource_size_t end;
const char *name;
unsigned long flags;//系统依靠这个标志位来寻找对应的资源
struct resource *parent, *sibling, *child;
};
我们可以用下面的方法获取资源结构体中的资源
struct resource *res;
res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);//这里可以依据IORESOURCE_IRQ这个标志找到对应的资源数组
plantform_device提到的device结构体
struct device {
struct bus_type * bus; /* type of bus device is on */
struct device *parent;
struct device_driver *driver; /* which driver has allocated this device */
};
plantform_driver结构体
struct platform_driver {
int (*probe)(struct platform_device *);//device和driver被注册时都会调用这个函数
int (*remove)(struct platform_device *);
void (*shutdown)(struct platform_device *);
int (*suspend)(struct platform_device *, pm_message_t state);
int (*suspend_late)(struct platform_device *, pm_message_t state);
int (*resume_early)(struct platform_device *);
int (*resume)(struct platform_device *);
struct device_driver driver;//这个是driver注册时真正被使用的结构体
};
device_driver结构体
struct device_driver {
struct bus_type * bus;
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);
};
上面的两个重要结构体plantform_driver和plantform_device在注册的时候只是填充了device_driver和device结构体然后向内核注册的
下面分析plantform_driver在内核中的注册流程
platform_driver_register(&<span style="font-family: Arial, Helvetica, sans-serif;">platform_driver </span><span style="font-family: Arial, Helvetica, sans-serif;">);</span>
platform_driver_register(struct platform_driver *drv)
/*下面填充platform_driver结构体中的device_driver结构体*/
drv->driver.bus = &platform_bus_type;//这里面有match函数可以按照name来找到对应的device,由此可见bus里面的match是<span style="font-family: Arial, Helvetica, sans-serif;">platform_bus_type统一提供的</span>
if (drv->probe) //用platform_driver中的probe函数来填充device_driver结构体,后面会依次填充resume,remove等函数
drv->driver.probe = drv->probe(device *_dev);
driver_register(&drv->driver);//现在拿填充好的device_driver来注册,后面的工作就交给device_driver来做了
driver_register(struct device_driver * drv)
bus_add_driver(drv);
bus_add_driver(struct device_driver *drv)
driver_attach(drv);
bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);//遍历整个device链表
bus_for_each_dev(struct bus_type * bus, struct device * start, void * data, int (*fn)(struct device *, void *))
struct device * dev;
dev = next_device(&i)//把所有的device找出来依次调用fn函数
fn(dev, data);///也就是调用了__driver_attach函数
__driver_attach(struct device * dev, void * data)
driver_probe_device(drv, dev);
driver_probe_device(struct device_driver * drv, struct device * dev)
if (drv->bus->match && !drv->bus->match(dev, drv))//调用总线上的match函数,对比device和device_driver的名字
goto done//如果比较成功返回1,失败返回0,也就是说成功后会执行really_probe函数
really_probe(dev, drv);
really_probe(struct device *dev, struct device_driver *drv)
dev->driver = drv;//将device和device_driver放到device结构体中
driver_sysfs_add(dev)//在系统中将device和device_driver建立一个链接,属于内核文件系统部分?
drv->probe(dev);//这时就调用到了platform_driver定义的probe函数,哈哈
下面分析plantform_device在内核中的注册流程
platform_device_register(&led_dev);
platform_device_register(struct platform_device * pdev)
platform_device_add(pdev);
platform_device_add(struct platform_device *pdev)
strlcpy(pdev->dev.bus_id, pdev->name, BUS_ID_SIZE);//把name赋值给bus_id
device_add(&pdev->dev);
device_add(struct device *dev)
device_create_file(dev, &dev->uevent_attr);
device_create_file(dev, attr); //这些都是文件管理部分的细节,貌似会建立什么,不懂
sysfs_create_link(&dev->kobj, &dev->class->subsys.kobj,"subsystem");
bus_attach_device(dev);
device_attach(dev);
bus_for_each_drv(dev->bus, NULL, dev, __device_attach);
bus_for_each_drv(struct bus_type * bus, struct device_driver * start, void * data, int (*fn)(struct device_driver *, void *))
struct device_driver * drv;
drv = next_driver(&i)//取出每一个driver,然后调用fn
fn(drv, data);//其实也就是调用了下面这个函数
__device_attach(struct device_driver * drv, void * data)
struct device * dev = data;
driver_probe_device(drv, dev);
drv->bus->match(dev, drv)//调用总线上的match函数
really_probe(dev, drv);//适配成功后就调用这个函数
dev->driver = drv;//将device和device_driver放到device结构体中
driver_sysfs_add(dev)//在系统中将device和device_driver建立一个链接
drv->probe(dev);//这时就调用到了plantform_driver定义的probe函数,碰头