linux platform 虚拟总线

转载 2013年12月04日 11:05:40
     

从Linux2.6起,引入了一套新的驱动管理和注册机制:Platform_device和Platform_driver。Linux中大部分的设备驱动,都可以使用这套机制,设备用platform_device表示,驱动用platform_driver进行注册。 Linux platformdriver机制和传统的device_driver机制相比,一个十分明显的优势在于platform机制将本身的资源注册进内核,由内核统一管理,在驱动程序中使用这些资源时通过platform_device提供的标准接口进行申请并使用。这样提高了驱动和资源管理的独立性,并且拥有较好的可移植性和安全性。

 

和传统的驱动一样,platform机制也分为三个步骤:  

1 总线注册阶段:

内核启动初始化时的main.c文件中的

                kernel_init()

                   -->do_basic_setup()

                        -->driver_init()

                              -->platform_bus_init()

                                   -->bus_register(&platform_bus_type),注册了一条platform总线(虚拟总线)。

 

2 添加设备时

设备注册的时候(对于展讯8830 设备的在kernel/arch/arm/mach-sc/Board_sp8830ec.c中的sc8830_init_machine()中有platform_add_devices(devices,ARRAY_SIZE(devices)))注册的。其中devices是platform_device类型的数组。

               Platform_device_register()

                    -->platform_device_add()

                         -->device_add(),就这样把设备给挂到虚拟的总线上。

 

3 驱动注册时:

               Platform_driver_register()

                   -->driver_register()

                         -->bus_add_driver()

                               -->driver_attach()

                                      -->bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);

                    对在每个挂在虚拟的platformbus的设备作__driver_attach()-->driver_probe_device(),判断drvàbusàmatch()是否执行成功,此时通过指针执行platform_match-->strncmp(pdev->name ,drv->name ,BUS_ID_SIZE),如果相符就调用really_probe(实际就是执行相应设备的platform_driver->probe(platform_device)。)开始真正的探测,如果probe成功,则绑定设备到该驱动。

 

   从上面可以看出,platform机制最后还是调用了bus_register(), device_add() ,driver_register()这三个关键的函数。

下面看几个结构体:

struct platform_device          (/include/linux/Platform_device.h)

{

      const char   *name;

      int         id;

      structdevice    dev;

      u32       num_resources;

      struct resource * resource;

};

   Platform_device结构体描述了一个platform结构的设备,在其中包含了一般设备的结构体structdevice      dev;设备的资源结构体structresource    *resource;还有设备的名字constchar    *name。(注意,这个名字一定要和后面platform_driver.driveràname相同,原因会在后面说明。)

 

该结构体中最重要的就是resource结构,这也是之所以引入platform机制的原因。

struct resource                           (/include/linux/ioport.h)

{

      resource_size_t start;

      resource_size_t end;

      const char *name;

      unsigned long flags;

      struct resource *parent, *sibling, *child;

};

   其中flags位表示该资源的类型,start和end分别表示该资源的起始地址和结束地址

 

struct platform_driver                 (/include/linux/Platform_device.h)

{

      int (*probe)(struct platform_device *);

      int (*remove)(struct platform_device *);

      void (*shutdown)(struct platform_device *);

      int (*suspend)(struct platform_device *, pm_message_tstate);

      int (*suspend_late)(struct platform_device *, pm_message_tstate);

      int (*resume_early)(struct platform_device *);

      int (*resume)(struct platform_device *);

      struct device_driver driver;

};

Platform_driver结构体描述了一个platform结构的驱动。其中除了一些函数指针外,还有一个一般驱动的device_driver结构。

 

 

 

名字要一致的原因:

上面说的驱动在注册的时候会调用函数bus_for_each_dev(),对在每个挂在虚拟的platformbus的设备作__driver_attach()àdriver_probe_device(),在此函数中会对dev和drv做初步的匹配,调用的是drv->bus->match所指向的函数。platform_driver_register函数中drv->driver.bus=&platform_bus_type,所以drv->bus->match就为platform_bus_typeàmatch,为platform_match函数,该函数如下:

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

{

      struct platform_device *pdev = container_of(dev, structplatform_device, dev);

 

      return (strncmp(pdev->name,drv->name, BUS_ID_SIZE) ==0);

}

是比较dev和drv的name,相同则会进入really_probe()函数,从而进入自己写的probe函数做进一步的匹配。所以devàname和driveràdrvàname在初始化时一定要填一样的。

 

不同类型的驱动,其match函数是不一样的,这个platform的驱动,比较的是dev和drv的名字,还记得usb类驱动里的match吗?它比较的是ProductID和VendorID。


linux架构下platform总线详解

学习驱动一定要掌握驱动的模型,platform总线在内核中用的非常频繁,还有一个是Input输入子系统,platform总线的好处是,inux从2.6起就加入了一套新的驱动管理和注册的机制platfo...
  • qq_21792169
  • qq_21792169
  • 2015年09月26日 12:16
  • 4977

platform总线和普通总线,驱动模型间的一些关系和理解

(本原创文章发表于Sailor_forever 的个人blog,未经本人许可,不得用于商业用途。任何个人、媒体、其他网站不得私自抄袭;网络媒体转载请注明出处,增加原文链接,否则属于侵权行为。如 有任何...
  • wyz649296016
  • wyz649296016
  • 2016年08月11日 10:15
  • 1642

Linux Platform总线+SPI总线分析

本文以MPC8308(powerpc架构),HX软件包为依据,详细内容可参考源码 CPU: e300c3MPC8308 400MHz BOARD: Freescale MPC8308ERDB D...
  • fzs333
  • fzs333
  • 2015年07月09日 10:45
  • 1249

基于platform总线的驱动分析

在设备驱动模型中,总线负责将设备和驱动绑定。在系统每注册一个设备的时候,会寻找与之匹配的驱动;相反的,在系统每注册一个驱动的时候,会寻找与之匹配的设备,而匹配由总线完成。...
  • qq_28992301
  • qq_28992301
  • 2016年08月31日 15:23
  • 990

framebuffer设备,字符设备,platform总线间的联系

欢迎各位转载!!! 最近在看Linux设备的驱动程序编程,里面的类型的设备驱动类型把我搞糊涂了。首先书上说linux中有字符设备,块设备,网络设备三大类驱动。但是接着又扯出一大堆的的什么platf...
  • d_a_r_k
  • d_a_r_k
  • 2015年12月24日 16:36
  • 693

platform总线、设备与驱动

本文转自(摘选):platform总线、设备与驱动     在Linux 2.6的设备驱动模型中,关心总线、设备和驱动这3个实体,总线将设备和驱动绑定。在系统每注册一个设备的时候,会寻找   ...
  • u010264321
  • u010264321
  • 2013年10月19日 09:00
  • 902

Paltform总线与其它总线框架的关系探究

在学习驱动的过程中,学习过Platform、I2C、SPI、USB等总线架构,对于Platform总线的理解是在书藉(宋宝华的《Linux设备驱动详解》)上所述的“一个现实的Linux设备和驱动通常需...
  • firstlai
  • firstlai
  • 2016年02月06日 18:42
  • 734

linux中platform总线解析(一)(platform总线初始化)

platform初始化的函数调用: start_kernel-->rest_init-->kernel_init-->kernel_init_freeable-->do_base_setup--->...
  • u010383937
  • u010383937
  • 2017年11月17日 11:35
  • 41

linux设备驱动归纳总结(九):1.platform总线的设备和驱动

linux设备驱动归纳总结(九):1.platform总线的设备和驱动 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx...
  • jsn_ze
  • jsn_ze
  • 2016年02月26日 14:46
  • 512

【Linux基础系列之】platform虚拟总线

linux当中大多数的设备都是以paltform虚拟总线挂载上去的,这里以kernel/drivers/net/dm9000.c为例子分析一下,platform设备挂在过程; (1)device ...
  • tanli20090506
  • tanli20090506
  • 2015年03月04日 22:38
  • 326
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:linux platform 虚拟总线
举报原因:
原因补充:

(最多只允许输入30个字)