Rockchip RK3399 - component框架

本文详细介绍了Rockchip RK3399组件框架,包括概述、核心数据结构和核心功能。该框架用于解决驱动加载顺序问题,保证系统组件的正确初始化。关键数据结构包括组件、系统和匹配对象,通过注册、启动等函数协调各部分工作,确保显示子系统的组件按序协同工作。
摘要由CSDN通过智能技术生成

我们在分析RK3399 DRM驱动过程中,涉及到了component框架内容,因此这里我们穿插一节内容,专门对component框架进行介绍。

一、component概述

1.1 背景

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

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

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

  • 保证系统安装了所有的组件;
  • 规定了系统各组件初始化的顺序;
1.2 介绍

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

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

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

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

二、component核心数据结构

component架构的实现位于drivers/base/component.c,其主要涉及到的数据结构有struct componentstruct aggregate_devicestruct 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 componentstruct aggregate_devicestruct component_match 之间的关系,我们绘制了如下关系框图:

刚开始component会将自己注册进入系统,并尝试唤醒aggregate_device来统筹(component也不了解自己是不是最后一个注册的,所有有义务唤醒aggregate_device).
最后aggregate_device把自己注册进入系统,根据aggregate_device自己定义的匹配方法找到所有的component,调用componentbind调函数.

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
  • opsaggregate_device可执行的初始化操作;
  • parentaggregate_device所属的device
  • match:该aggregate_device用到的component_matchaggregate_device应用该matchcomponent_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_with_match() and
 * unregistered with component_master_del().
 */
struct component_master_ops {
        /**
         * @bind:
         *
         * Called when all components or the aggregate driver, as specified in
         * the match list passed to component_master_add_with_match(), are
         * ready. Usually there are 3 steps to bind an aggregate driver:
         *
         * 1. Allocate a structure for the aggregate driver.
         *
         * 2. Bind all components to the aggregate driver by calling
         *    component_bind_all() with the aggregate driver structure as opaque
         *    pointer data.
         *
         * 3. Register the aggregate driver with the subsystem to publish its
         *    interfaces.
         *
         * Note that the lifetime of the aggregate driver does not align with
         * any of the underlying &s
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Graceful_scenery

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值