虚拟总线:
由两部分组成:
platform_device和platform_driver
工作流程:
通过platform机制开发底层设备驱动的流程图:
定义 platform_device
|
注册 platform_device
|
定义 platform_driver
|
注册 platform_driver
platform设备:
struct platform_device{
const char *name; /*设备名*/
int id; /*设备编号*/
struct device dev;
u32 num_resources;
struct resource *resource; /*设备资源*/
}
platform device分配:
struct platform_device *platform_device_alloc(const char *name, int id);
参数:
name:设备名
id:设备id,一般为-1
platform device注册:
int platform_device_add(struct platform_device *pdev);
platform device资源:
struct resource{
resource_size_t start; /*资源的起始物理地址*/
resource_size_t end; /*资源的结束物理地址*/
const char *name; /*资源名称*/
unsigned long flags; /*资源类型,如:MEM,IO,IRQ类型*/
struct resource *parent, *sibling, *child; /*资源的链表指针*/
}
flags:IORESOURCE_MEM\IORESOURCE_IRQ
获取资源:
struct resource *platform_get_resource(struct platform_device *dev, unsigned int type, unsigned int num);
参数:
dev:资源所属的设备
type:获取的资源类型
num:获取的资源数
ex:
platform_get_resource(pdev, IORESOURCE_IRQ,0);获取中断号
platform驱动:
struct platform_driver来描述设备驱动
struct platform_driver {
int (*probe)(struct platform_device *);
int (*remove)(struct platform_device *);
void (*shutdown)(struct platform_device *);
int (*suspend)(struct platform_device *, pm_message_t state);
int (*resume)(struct platform_device *);
struct device_driver driver;
const struct platform_device_id *id_table;
};
注册驱动:
int platform_driver_register(struct platform_driver *);
原理分析:
int platform_driver_register(struct platform_driver *drv)
{
drv->driver.bus = &platform_bus_type;
/*指明总线类型,通过查询platform_bus_type中的match函数,就可以知道如何去匹配driver and device*/
if (drv->probe)
drv->driver.probe = platform_drv_probe;
if (drv->remove)
drv->driver.remove = platform_drv_remove;
if (drv->shutdown)
drv->driver.shutdown = platform_drv_shutdown;
return driver_register(&drv->driver);
}
int driver_register(struct device_driver *drv)
{
...
ret = bus_add_driver(drv);
...
}
int bus_add_driver(struct device_driver *drv)
{
...
error = driver_attach(drv);
/*对总线上面的每一个设备都会执行,调用bus match,找到设备以后调用prob函数*/
...
}
return drv->bus->match ? drv->bus->match(dev, drv) : 1
最终会去call到,platform driver bus 中的match函数,已经在flatform.c中实现。
static int platform_match(struct device *dev, struct device_driver *drv),这个函数会对device name 和driver name做memcmp。当它们的名字相同的时候,才会去调用platform driver的prob函数。
<file://D:\資料\学习资料\linux相关\演示代码\platform\device.c>
<file://D:\資料\学习资料\linux相关\演示代码\platform\driver.c>
platform只是一个平台,需要在prob中自己创建创建字符设备、块设备等文件。
作用:
利用模型,驱动能够找到设备的作用。platform驱动工作之后,prob里面创建的设备属于功能性驱动。