Linux设备驱动之platform

 根据     Linux      设备模型可知,一个现实的Linux设备和驱动通常都需要挂接在一种总线上,对于本身依附于PCI、     USB      等的设备而言,这自然不是问题,但是在嵌入式系统里面,SoC系统中集成的独立的外设控制器、挂接在 SoC 内存空间的外设等却不依附于此类总线。基于这一背景,Linux设计了一种虚拟的总线,称为platform总线,相应的设备称为platform_device,而驱动称为platform_driver。

设计目的

兼容设备模型

使得设备被挂接在一个总线上,因此,符合 Linux 2.6 的设备模型。其结果是,配套的sysfs结点、设备     电源管理   都成为可能。

BSP和驱动隔离

在BSP中定义platform设备和设备使用的资源、设备的具体配置信息。而在驱动中,只需要通过通用A     PI   去获取资源和数据,做到了板相关代码和驱动代码的分离,使得驱动具有更好的可扩展性和跨平台性。

软件架构

内核中Platform设备有关的实现位于include/linux/platform_device.h和drive     rs   /base/platform.c两个文件中,它的软件架构如下:

 Linux设备驱动之platform_设计制作_EDA/IC设计

由图片可知,Platform设备在内核中的实现主要包括三个部分:

Platform Bus,基于底层bus模块,抽象出一个虚拟的Platform bus,用于挂载Platform设备;

Platform Device,基于底层device模块,抽象出Platform Device,用于表示Platform设备;

Platform Driver,基于底层device_driver模块,抽象出Platform Driver,用于驱动Platform设备。

platform_device

注意,所谓的platform_device并不是与     字符   设备、块设备和网络设备并列的概念,而是Linux系统提供的一种附加手段,例如,在S3C2440处理器中,把内部集成的     I2C   、RTC、SPI、LCD、     看门狗   等控制器都归纳为platform_device,而它们本身就是字符设备。

/* defined in */struct platform_device { const char * name; / * 设备名 */ u32 id; /* 用于标识该设备的ID */ struct device dev; /* 真正的设备(Platform设备只是一个特殊的设备,因此其核心逻辑还是由底层的模块实现)*/ u32 num_resources; / * 设备所使用各类资源数量 */ struct resource * resource; / * 资源 */};/* defined in */struct resource { resource_size_t start; /* 资源起始 */ resource_size_t end; /* 结束 */ const char *name; unsigned long flags; /* 类型 */ struct resource *parent, *sibling, *child;};/* 设备驱动获取BSP定义的resource */struct resource *platform_get_resource(struct platform_device *, unsigned int flags, unsigned int num);#include int platform_device_regis     te   r(struct platform_device *); void platform_device_unregister(struct platform_device *);

    Ti   p: 和板级紧密相关的资源描述放在dev.paltform_data中。

paltform_driver

platform_driver这个结构体中包含probe()、remove()、shutdown()、suspend()、resume()函数,通常也需要由驱动实现:

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;};#include int platform_driver_register(struct platform_driver *); void platform_driver_unregister(struct platform_driver *);

platform_bus

系统中为platform总线定义了一个bus_type的实例platform_bus_type:

struct bus_type platform_bus_type = { .name = "platform", .dev_attrs = platform_dev_attrs, .match = platform_match, .uevent = platform_uevent, .pm = PLATFORM_PM_OPS_PTR,};EXPORT_SYMBOL_GPL(platform_bus_type);

这里要重点关注其 match()成员函数,正是此成员函数确定了 platform_device 和 platform_driver之间如何匹配:

sta  TI c int platform_match(struct device *dev, struct device_driver *drv){ struct platform_device *pdev; pdev = cont     ai   ner_of(dev, struct platform_device, dev); return (strncmp(pdev->name, drv->name, BUS_ID_SIZE) == 0);}

61
120
0
40

相关资讯

  1. 1、L3级自动驾驶落地前夜:BAT抢高精地图量产头炮4603
  2. 2、深度解析:互联网装修,正在等风来……4618
  3. 3、2016年互联网支付发展情况4647
  4. 4、贯穿用户生命周期的神器——“活动运营”2781
  5. 5、从20万飙升到400万间阅读量,仅仅隔着一个好标题1221
  6. 6、电商之下:我们重塑着它,也被它重塑着735
  7. 7、浅谈移动医疗APP的线下推广3183
  8. 8、5000字深度解析美团八大增长战略2095
  9. 9、从专员到资深:做一名60分的运营负责人3403
  10. 10、【人人晚报】112期:投资人变“小气”-中国科技公司怎么办?2884
全部评论(0)
我也有话说
0
收藏
点赞
顶部