您的位置:首页 > 运维架构 > Linux

platform平台设备驱动

2013-09-09 22:32 435 查看
原创kylin_zeng:http://blog.csdn.net/kylin_fire_zeng

平台(platform)总线:

一、Platform总线是linux2.6内核加入的一种虚拟总线。platform机制的本身使用并不

复杂,且Platform 驱动与传统的设备驱动模型相比,优势在于platform机制将设备本身

的资源注册进内核,由内核统一管理,在驱动程序使用这些资源时使用统一的

接口,这样提高了程序的可移植性。由两部分组成:

 platform_device和platform_driver

 

二通过platform机制开发底层设备驱动的流程如图:

platform_device定义 ->platform_device注册 ->platform driver定义 -> platform_driver注册

1)platform_device平台设备 描述:

平台设备使用Struct Platform_device来描述:

struct platform_device

{

  const char *name; /*设备名*/

  int id;   /*设备编号,配合设备名使用*/

  struct device dev;

  u32 num_resources;

  struct resource *resource; /*设备资源*/

}

struct resource

{

  resource_size_t start; //资源的起始物理地址

  resource_size_t end;  //资源的结束物理地址

  const char *name; //资源的名称

  unsigned long flags;  //资源的类型,比如MEM,IO,IRQ类型

  struct resource *parent, *sibling, *child;//资源链表指针

}

获取资源:

struct resource *platform_get_resource(struct platform_device

 *dev, unsigned int type,  unsigned int num)

 参数:

 dev: 资源所属的设备

 type: 获取的资源类型

 num: 获取的资源数

例:

platform_get_resource(pdev, IORESOURCE_IRQ, 0)

获取中断号

 

2)平台设备申请:

Struct Platform_device的分配使用:

struct platform_device *platform_device_alloc(const char *name, int id)

参数:name: 设备名  id: 设备id,一般为-1

3)注册平台设备:

int platform_device_add(struct platform_device *pdev)

二、平台驱动

1)平台驱动使用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 (*suspend_late)(struct platform_device *, pm_message_t state);

  int (*resume_early)(struct platform_device *);

  int (*resume)(struct platform_device *);

  struct device_driver driver; //平台驱动中包含着设备驱动

}

2)平台驱动注册:(及如何去匹配设备和驱动是否对应,对应后怎么执行prope)

平台驱动注册使用函数:

int platform_driver_register(struct platform_driver *)

{

  drv->driver.bus=&platform_bus_type  //可以知道是哪个总线类型

  if(drv->probe)

  {

   drv->driver.probe=platform_drv_probe;

  }

.....

  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)

{

 ...

 if(drv->bus->p->drivers_autoprobe)

 {

  error=driver_attach(drv);

 }

 ...

}

int driver_attach(struct device_driver *drv)

{

  return bus_for_each_dev(drv->bus,null,drv,__driver_attach); //总线上的每一个设备都会执行这个

}

static __driver_attach(struct device *dev ,void *data)

{

 ...

 if(drv->bus->match && !drv->bus->match(dev,drv))

   return 0; //查找设备和驱动是否对应,不对应则直接返回

 ...

 if(!dev->driver)

 {

  driver_probe_device(drv,dev);  //如果对应则执行probe

 }

 ...

}

int driver_probe_device(struct device_driver *drv ,struct device *dev)

{

 ...

 ret=really_probe(dev,drv);

 ...

}

static int really_probe(struct device *dev ,struct device_driver *drv)

{

  ...

  ret=drv_probe(dev);//真正驱动中的probe

}

因此当注册一个驱动时,系统会遍历总线上的所有设备,看是否匹配。匹配了才执行prope,

平台总线还有一个match

struct bus_type platform_bus_type=

{

  .name="",

  .match=platform_match,

  ....

}

static int platform_match(struct device *dev ,struct device_driver *drv)

{

  ...

  return(Strcmp(pdev->name,drv->name)==0);//驱动和设备示匹配的,能过处理。

}

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  platform linux