(二) - component框架

一,component概述

1.1 背景

linux内核中的驱动,需要有一定的加载顺序,用来解决驱动之间的依赖问题。虽然说linux内核有定传统的驱动优先级,用来定义驱动的先后顺序,但是不足以更加细分的加载。

有的驱动可以独立加载而不依赖于其他驱动,但是在一个比较庞大的驱动面前,细分驱动的加载就比较重要了,因为这些庞大的驱动,环环相扣,一环出了问题就影响整个驱动的顺利走完。

所以component架构构建功能系统就包括两方面的作用:

  • 保证系统安装了所有的组件;

  • 规定了系统各组件初始化的顺序;

1.2 介绍

component架构在linux内核中现在主要的应用是用来构建display-subsystem,一个显示子系统由显示控制器(vop)、接口控制器(mipi,lvds,hdmi等)、液晶背光,电源等多个独立的功能单元构成。而把这些功能单元构成一个系统,就需要这些功能单元间有一定的协同配合。

如在扫描设备树时,每一个设备节点依次被注册到系统中(一般将设备节点转换为platform_device,然后使用platform_device_register注册),而只有当所有显示子系统相关的设备节点都注册到系统中时,整个显示系统才能正常工作。

如果没有component架构的参与,在用platform_device_register函数注册每个设备节点时,其platform_driver驱动的probe函数中会执行了一系列的初始化工作,而此时系统相关的其它设备节点可能还没有注册到内核中,这样可能就会导致一些问题出现。

在component架构的参下,可以保证在显示子系统的所有功能单元都注册后,才按照一定顺序执行初始化操作。

二,component核心数据结构

component架构的实现位于drivers/base/component.c,其主要涉及到的数据结构有struct component、struct aggregate_device、struct component_match。

2.1 关系图

component架构上述结构可以用拼乐高积木的过程来理解:

  • 一个一个形态各异的积木就用struct component来表示;

  • struct aggregate_device就是要拼接成的东西(系统)(例如想拼成一辆车或一个房子);

  • struct component_match就是你手里的图纸;

根据图纸,就可以在一个个积木(component)中,找出需要的积木,然后拼成一个想要的作品(aggregate_device)。

如果对应到display-subsystem中的话,:

  • struct component对应的就是显示子系统的各个功能单元,每个component都会和一个platform_device关联起来;

  • struct aggregate_device对应的就是显示子系统;

为了更加形象的表示struct component、struct aggregate_device、struct component_match 之间的关系,我们绘制了如下关系框图:

刚开始component会将自己注册进入系统,并尝试唤醒aggregate_device来统筹(component也不了解自己是不是最后一个注册的,所有有义务唤醒aggregate_device).

最后aggregate_device把自己注册进入系统,根据aggregate_device自己定义的匹配方法找到所有的component,调用component的bind调函数.

2.2 struct component

struct component用来表示系统组件,定义在drivers/base/component.c;

struct component {
    struct list_head node;
    struct aggregate_device *adev;
    bool bound;

    const struct component_ops *ops;
    int subcomponent;
    struct device *dev;
};

其中:

  • node: 链表节点,用于将当前节点添加到全局链表component_list,链表component_list保存了注册到系统中的所有component;

  • adev:用于保存与该组件匹配的aggregate_device;

  • bound:表示组件已经执行了bind操作,当操作集ops中的bind函数被执行,该标志位设置为true;

  • ops:组件可执行的初始化操作;

  • dev:组件所属的device;

2.2.1 全局链表component_list

全局链表component_list定义如下:

static LIST_HEAD(component_list);
2.2.2 struct component_ops

struct component_ops定义在include/linux/component.h,用于表示component可执行的初始化操作;

/**
* struct component_ops - callbacks for component drivers
*
* Components are registered with component_add() and unregistered with
* component_del().
*/
struct component_ops {
    /**
     * @bind:
     *
     * Called through component_bind_all() when the aggregate driver is
     * ready to bind the overall driver.
     */
    int (*bind)(struct device *comp, struct device *master,
            void *master_data);
    /**
     * @unbind:
     *
     * Called through component_unbind_all() when the aggregate driver is
     * ready to bind the overall driver, or when component_bind_all() fails
     * part-ways through and needs to unbind some already bound components.
     */
    void (*unbind)(struct device *comp, struct device *master,
               void *master_data);
};

该结构体中包含两个回调函数:

  • bind:执行组件的绑定操作;当调用component_bind_all函数时,回调该函数;

  • unbind:执行组件的解绑操作;当调用component_unbind_all函数时,回调该函数;

2.3 struct aggregate_device

struct aggregate_device表示需要构建的系统,定义在drivers/base/component.c;

struct aggregate_device {
    struct list_head node;
    bool bound;

    const struct component_master_ops *ops;
    struct device *parent;
    struct component_match *match;
};

其中:

  • node:链表节点,用于将当前节点添加到全局链表aggregate_devices,链表aggregate_devices保存了注册到系统中的所有aggregate_device;

  • bound:表示系统已经执行了bind操作,当操作集ops中的bind函数被执行,该标志位设置为true;

  • ops:aggregate_device可执行的初始化操作;

  • parent:aggregate_device所属的device;

  • match:该aggregate_device用到的component_match,aggregate_device应用该match在component_list链表中找到适配于自己的component组件,并将所有匹配的component保存到该结构体的中;

2.3.1 全局链表aggregate_devices

全局链表aggregate_devices定义如下:

static LIST_HEAD(aggregate_devices);
2.3.2 struct component_master_ops

struct component_master_ops定义在include/linux/component.h,用于表示aggregate_device可执行的初始化操作;

/**
* struct component_master_ops - callback for the aggregate driver
*
* Aggregate drivers are registered with component_master_add_wi
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值