微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > platform总线

platform总线

时间:12-14 来源:互联网 点击:
platform总线实际上并不对应任何硬件上的总线,有时又称为伪总线。由于设备模型中的驱动和设备关联机制必须要有一条总线才能发挥作用,对于那些没有连接在实际总线上的设备,如果想使用这种机制,就需要将它连接在一条假想的总线上。platform总线就可以起到这个作用,通常,platform总线上的设备都是直接与CPU相连的底层设备。

使用platform总线的好处是可以将驱动与设备分离,驱动所需的平台相关数据则在定义设备时提供,使驱动具有更大的跨平台通用性。

platform总线的相关定义和声明在头文件中。

1.platform总线基本特征

struct bus_type platform_bus_type = {

.name = "platform",

.match = platform_match,

.uevent = platform_uevent,

......

}

匹配操作是platform_match,定义如下:

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

{

struct platform_device *pdev=to_platform_device(dev);

struct platform_driver *pdrv=to_platform_driver(drv);

if(pdrv->id_table)

return platform_match_id(pdrv->id_table,pdev)!=NULL;

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

}

其中调用的platform_match_id函数定义如下:

static const struct platform_device_id *platform_match_id(

struct platform_device_id *id, struct platform_device *pdev)

{

while(id->name[0]){

if(strcmp(pdev->name, id->name) == 0){ pdev->id_entry=id; return id; }

id++;

}

return NULL;

}

显然在匹配时,先将设备的名称与驱动的id_table成员数组中列举的名称逐一比较,若相同则匹配成功,否则再将设备的名字与驱动的名字比较,若相同则匹配成功。

platform总线的用户态事件钩子函数是platform_uevent,定义如下:

static int platform_uevent(struct device *dev, struct kobj_uevent_env *env){

struct platform_device *pdev = to_platform_device(dev);

add_uevent_var(env,"MODALIAS=%s%s", PLATFORM_MODULE_PREFIX, (pdev->id_entry) ? pdev->id_entry->name : pdev->name);

return 0;

}

也就是说,platform总线上的设备发送用户态事件时,会增加一个MODALIAS环境变量。

2.platform设备

struct platform_device{

const char *name;//设备名称

int id;//设备编号,-1表示只有一个

struct device dev;//内嵌的设备对象

u32 num_resources;//资源数组中的元素的个数

struct resource *resource;//指向描述资源的数组

struct platform_device_id *id_entry;//保存与驱动匹配后的ID

}

设备的名称最终会被设为name.id,其中id是设备的编号。如果id的赋值为-1,表示设备的个数只可能是1个,这时设备的名字为name.

num_resources和resource用于描述设备需要的全部资源,即端口号,IO内存、中断号等,内存将它们统称为资源。

struct resource{

resource_size_t start;//资源区域的起始值

resource_size_t end;//资源区域的结束值

const char *name;//申请资源的设备名称

unsigned long flags;//资源的标志

struct resource *parent,*sibling,*child;//树指针

}

每个struct resource类型的数据描述资源的一段区域,同一类型的所有资源以树的形式组织在一起。资源的标志包含了资源类型的说明,常用类型如下:

* IORESOURCE_IO :端口号资源

* IORESOURCE_MEM :IO内存资源

* IORESOURCE_IRQ :中断号资源

* IORESOURCE_DMA :DMA资源

平台相关的其他数据则放在platform设备的dev成员的platform_data指针所指向的内存中,。

下面是platform设备的注册和注销函数的原型:

int platform_device_register(struct platform_device *pdev);//注册

void platform_device_unregister(struct platform_device *pdev);//注销

注册platform设备时,首先向platform总线注册相应的设备,然后将设备的端口号和IO内存资源添加到系统的资源树种,注销platform设备则是相反的操作。

通常一个系统中的platform设备的个数和类型总是固定的,因此可以把它们的地址放在一个数组中,然后用下面的接口函数同时注册:

int platform_add_devices(struct platform_device **devs, int num);

3.platform驱动

struct platform_driver{

int (*probe)(struct platform_device *pdev)

int (*remove)(struct platform_device *pdev);

struct device_driver driver;//内嵌的驱动对象

struct platform_device_id *id_table;//用于匹配的ID数组

.......

}

在platform驱动的成员driver的各种操作函数中,实际

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top