您的位置:首页 > 其它

platform平台总线工作原理详解

2017-05-12 22:12 399 查看
一、platform平台总线的简介

(1)相对于USB、PCI、I2C、SPI等物理总线来说,platform总线是一种虚拟、抽象出来的总线,实际中并不存在这样的总线。

(2)cpu与外部通信的两种方式,地址总线式链接(32的cpu就有0-4G直接集成在cpu内部,以地址指针方式直接访问,没有具体的总线链接就用虚拟的platform平台总线来控制内部的外设)和专用接口式(iic,pci,usb等这些外部总线链接的)链接平台总线对应地址总线式链接设备,也就是soc内部集成的各种内部外设

(3)思考:为什么要有平台总线?进一步思考:为什么要有总线的概念?

因为大多数设备都是集成在soc内部,和cpu直接连接,将其直接扩展到内部地址空间,因此他们本身就不该就有总线的概念,本身就不属于总线的链接方式,但是如果一部分设备设计得有总线,一部分没总线就太乱了,所以除了iic,pci,spi等的设备就归类到平台总线来便于管理

二、platform平台总线下管理的2员大将

(1)platform工作体系都定义在drivers/base/platform.c中

(2)两个结构体:platform_device和platform_driver

(3)两个接口函数:platform_device_register和platform_driver_register

1、platform_device

struct platform_device {
const char  * name;         // 平台总线下设备的名字
int     id;
struct device   dev;        // 所有设备通用的属性部分
u32     num_resources;      // 设备使用到的resource的个数
struct resource * resource; // 设备使用到的资源数组的首地址

const struct platform_device_id *id_entry;  // 设备ID表

/* arch specific additions */
struct pdev_archdata    archdata;           // 自留地,用来提供扩展性的
};


*对平台总线下可利用的设备资源结构体进行分析struct resource resource

struct resource { // 资源结构体

resource_size_t start; // 资源的起始值,如果是地址,那么是物理地址,不是虚拟地址

resource_size_t end; // 资源的结束值,如果是地址,那么是物理地址,不是虚拟地址

const char *name; // 资源名

unsigned long flags; // 资源的标示,用来识别不同的资源

struct resource *parent, *sibling, *child; // 资源指针,可以构成链表

};

struct platform_driver {
int (*probe)(struct platform_device *);     // 驱动探测函数
int (*remove)(struct
4000
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;  // 设备ID表
};


三、平台总线本身的初始化函数platform_bus_init

int __init platform_bus_init(void)
{
int error;
early_platform_cleanup();   //  进行一些早期的平台清理
error = device_register(&platform_bus); //  注册设备 (在/sys/devices/目录下建立 platform目录对应的设备对象  /sys/devices/platform/)
if (error)
return error;
error =  bus_register(&platform_bus_type);  //  总线注册
if (error)
device_unregister(&platform_bus);
return error;
}


四、platform平台总线工作原理

1、平台总线体系的工作流程

*(1)第一步:系统启动时在bus系统中注册platform

(2)第二步:内核移植的人负责提供platform_device

(3)第三步:写驱动的人负责提供platform_driver

(4)第四步:platform的match函数发现driver和device匹配后,调用driver的probe函数来完成驱动的初始化和安装,然后设备就工作起来了*

2、代码分析:platform本身注册

(1)每种总线(不光是platform,usb、i2c那些也是)都会带一个match方法,match方法用来对总线下的device和driver进行匹配。理论上每种总线的匹配算法是不同的,但是实际上一般都是看name的。

(2)platform_match函数就是平台总线的匹配方法。该函数的工作方法是:如果有id_table就说明驱动可能支持多个设备,所以这时候要去对比id_table中所有的name,只要找到一个相同的就匹配上了不再找了,如果找完id_table都还没找到就说明每匹配上;如果没有id_table或者每匹配上,那就直接对比device和driver的name,如果匹配上就匹配上了,如果还没匹配上那就匹配失败

3、以leds-s3c24xx.c为例来分析platform设备和驱动的注册过程

(1)platform_driver_register

(2)platform_device_register

platdata怎么玩

(1)platdata其实就是设备注册时提供的设备有关的一些数据(譬如设备对应的gpio、使用到的中断号、设备名称····)

(2)这些数据在设备和驱动match之后,会由设备方转给驱动方。驱动拿到这些数据后,通过这些数据得知设备的具体信息,然后来操作设备。

(3)这样做的好处是:驱动源码中不携带数据,只负责算法(对硬件的操作方法)。现代驱动设计理念就是算法和数据分离,这样最大程度保持驱动的独立性和适应性。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: