您的位置 首页 IOT

platform总线

platform总线实际上并不对应任何硬件上的总线,有时又称为伪总线。由于设备模型中的驱动和设备关联机制必须要有一条总线才能发挥作用,对于

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的各种操作函数中,实践上直接回调了platform驱动的各种操作,仅仅将参数的类型转换了下。由于platform总线自身没有probe和remove操作,所以当platform驱动注册时,若platform总线上现已注册了匹配的设备,就会调用驱动的probe办法。
platform设备一般先于platform驱动而加载,这样勘探操作就会只发生在模块的加载过程中,然后能够安全的放入初始化数据段,以节省内存。
注册和刊出platform驱动的接口函数如下:
int platform_driver_register(struct platform_driver *drv);
void platform_driver_unregister(struct platform_driver *drv);
在platform驱动的probe函数中,能够用下面这个函数获取设备的各种资源:
struct resource *platform_get_resource(struct platform_device *dev, unsigned int type, unsigned num);
*dev指向要获取资源的platform设备。
*type资源的类型
*num:资源的索引,表明要取得设备的资源数组中第几个此类型的资源,索引从0开端编号。
获取中止号的接口函数:
int platform_get_irq(struct platform_device *dev, unsigned int num);

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/yingyong/iot/235053.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部