platform平台设备驱动

原创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);//驱动和设备示匹配的,能过处理。
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值