Linux Component概述和高通component的使用

1 Linux为什么要引入Component框架?

为了让subsystem按照一定顺序初始化设备才提出来的。
subsystem中由很多设备模块,内核加载这些模块的时间不确定。子系统内有些模块是需要依赖其它模块先初始化才能进行自己初始化工作(例如v4l2 subdev和v4l2 video device),这时就要用到component框架。

例如v4l2 subdev和v4l2 video device中,谁依赖谁先创建?
v4l2 video device依赖V4l2 subdev,它要等subdev创建后再创建,同时将subdev绑定到v4l2 video device上。

1.1 高通camera kmd中component的使用

入口:camera_init是入口。
submodule_table[i].component[j].init()
对submodule table中定义的每个component做init。
相关定义:

static const struct camera_submodule_component camera_base[] = {{&cam_req_mgr_init, &cam_req_mgr_exit},{&cam_sync_init, &cam_sync_exit},{&cam_smmu_init_module, &cam_smmu_exit_module},{&cam_cpas_dev_init_module, &cam_cpas_dev_exit_module},{&cam_cdm_intf_init_module, &cam_cdm_intf_exit_module},{&cam_hw_cdm_init_module, &cam_hw_cdm_exit_module},
};
static const struct camera_submodule_component camera_isp[] = {{&cam_ife_csid_init_module, &cam_ife_csid_exit_module},{&cam_ife_csid_lite_init_module, &cam_ife_csid_lite_exit_module},{&cam_vfe_init_module, &cam_vfe_exit_module},{&cam_sfe_init_module, &cam_sfe_exit_module},{&cam_isp_dev_init_module, &cam_isp_dev_exit_module},
};
...
static const struct camera_submodule submodule_table[] = {{.name = "Camera BASE",.num_component = ARRAY_SIZE(camera_base),.component = camera_base,},{.name = "Camera TFE",.num_component = ARRAY_SIZE(camera_tfe),.component = camera_tfe,},{.name = "Camera ISP",.num_component = ARRAY_SIZE(camera_isp),.component = camera_isp,},{.name = "Camera SENSOR",.num_component = ARRAY_SIZE(camera_sensor),.component = camera_sensor},...
};

1.2 重要数据结构

  • master
    表示要构建的系统
struct master {struct list_head node; //用于链接到全局masters中bool bound; //标记当前master是否bind了const struct component_master_ops *ops; //master设备的回调接口struct device *dev;struct component_match *match; //安装顺序保存了当前master的所有component匹配条件
};
  • Component
    表示系统组件
struct component {struct list_head node;//用于链接到全局的component_list中struct master *master;//保存本组件属于哪个master devicebool bound;//本component是否bind过const struct component_ops *ops;//本component的回调接口struct device *dev; //本组件属于哪个设备
};
  • component_match
    用来匹配系统需要的组件,并规定了组件的初始化顺序
struct component_match_array {void *data;//比较数据int (*compare)(struct device *, void *);//比较接口void (*release)(struct device *, void *);struct component *component;//当前比较匹配规则属于哪个componentbool duplicate;//标记是否做移除
};struct component_match {size_t alloc;//分配了多少个比较条件对象component_match_array size_t num;//保存了多少个component匹配条件struct component_match_array *compare;//匹配条件数组地址
};
  • 全局变量masters和component_list
    保存整个linux系统中所有主设备的数据结构。
    保存整个linux系统中所有添加到component框架里的component数据结构。
static LIST_HEAD(component_list);
static LIST_HEAD(masters);

1.3 CRM和其他component如何联系起来?

在高通KMD框架中,CRM属于主设备(master设备),其他cam_sync、cam_smmu、cam_cap、cam_tfe、cam_sensor等属于组件component。
他们是通过配置cam_component_platform_drivers时联系起来。

static struct platform_driver *const cam_component_platform_drivers[] = {
/* BASE */&cam_sync_driver,&cam_smmu_driver,&cam_cpas_driver,&cam_cdm_intf_driver,&cam_hw_cdm_driver,
#ifdef CONFIG_SPECTRA_TFE&cam_csid_ppi100_driver,&cam_tfe_driver,&cam_tfe_csid_driver,
#endif
#ifdef CONFIG_SPECTRA_ISP&cam_ife_csid_driver,&cam_ife_csid_lite_driver,&cam_vfe_driver,&cam_sfe_driver,&isp_driver,
#endif...
}

1.4 camera kmd中component如何bind

camera_submodule_component 的camera base数组中,会依次执行cam_req_mgr_init和cam_sync_init以及其他component的init函数实现。

1.4.1 crm init

cam_req_mgr_init就是crm的init,也是master设备的init。
它主要做了什么?

  • 向linux系统注册crm的platform_driver驱动
  • cam_req_mgr_probe

crm的platform_driver驱动中定义了probe函数,当驱动名称和设备名称匹配时,调用驱动的probe函数。

这里cam_req_mgr_probe主要做了两件事:
1)遍历cam_component_platform_drivers按顺序添加到match_list
2)添加match_list到master设备,并遍历是否所有的component都添加完成。
如果所有的component都添加完成,尝试初始化master_device。

尝试初始化master_device通过调用try_to_bring_up_aggregate_device(adev,NULL),它主要做两件事,一是查看是不是所有component_match列表里的component都已经添加到全局链表component_list中,二是如果所有component_match列表里的component都ready,就调用master设备的bind接口进行初始化。master的bind会顺序执行各component的bind()。
(通过调用component_bind_all())

1.4.2 cam_sync init

它主要做了什么?

  • 向linux系统注册cam_sync的platform_driver驱动
  • cam_sync_probe

cam_sync_probe做了什么?
为cam_sync创建一个component,并添加到component框架。
它会调用component_add()进行添加,进一步调用try_to_bring_up_masters(component),
try_to_bring_up_masters会遍历全局链表master_devices中所有的master设备,尝试bringup每一个遍历出来的aggregate device。

1.5 component_match数据结构关系图

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/264170.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【小白专用】Sql Server 连接Mysql 更新23.12.09

目标 已知mysql连接参数(地址和用户),期望通过Microsoft Sql Server Management Studio (以下简称MSSSMS)连接Mysql,在MSSSMS中直接查询或修改Mysql中的数据。 一般是选最新的版本下载。 选64位还是32位&a…

Linux的权限

Linux的权限 一、shell运行原理--外壳程序二、Linux权限(主体,重点)三、常见的权限问题目录权限umask粘滞位 一、shell运行原理–外壳程序 为什么我们不是直接访问的操作系统? 1.人不善于直接使用操作系统 2.如果让人直接访问操作…

[NAND Flash] 3.1 闪存的组成结构原理与使用挑战

依公知及经验整理&#xff0c;原创保护&#xff0c;禁止转载。 专栏 《深入理解NAND Flash》 <<<< 返回总目录 <<<< ​ 前言 日本东芝最初发明半导体存储芯片时&#xff0c;认为它就像拍照时的闪光一样迅速&#xff0c;因此命名为闪存(Flash)。如今&a…

【数值计算方法(黄明游)】函数插值与曲线拟合(二):三次 Hermite 插值【理论到程序】

​ 文章目录 一、近似表达方式1. 插值&#xff08;Interpolation&#xff09;2. 拟合&#xff08;Fitting&#xff09;3. 投影&#xff08;Projection&#xff09; 二、Lagrange插值1. 拉格朗日插值方法2. Lagrange插值公式a. 线性插值&#xff08;n1&#xff09;b. 抛物插值&…

电工--基本放大电路

电压放大倍数、输入电阻和输出电阻是放大电路的三个主要性能指标 共发射极基本交流放大电路 晶体管&#xff1a;电流放大作用。能量较小的输入信号通过晶体管的控制作用&#xff0c;去控制电源所共给的能量&#xff0c;以在输出端获得一个能量较大的信号 集电极电源电压&#…

Vue3:修改下拉框el-select的样式

问题 在Vue3项目中&#xff0c;使用了elemen-plus的下拉框&#xff0c;但是使用深度修改下拉框的样式&#xff08;比如下拉框的背景颜色&#xff09;一直不生效 解决 给下拉框框添加 popper-class属性&#xff0c;属性名根据需求取&#xff0c;比如这里取的是"selectSt…

Elasticsearch:向量数据库的真相

通过工作示例了解什么是向量数据库、它们如何实现 “相似性” 搜索以及它们可以在明显的 LLM 空间之外的哪些地方使用。除非你一直生活在岩石下&#xff0c;否则你可能听说过诸如生成式人工智能和大型语言模型&#xff08;LLM&#xff09;之类的术语。 除此之外&#xff0c;你很…

在IDEA中创建Maven项目时没有src文件、不自动配置文件

错误示例&#xff1a; 没有src文件&#xff0c;并且没有自动下载相关的配置文件 对我这中情况无效的解决办法&#xff1a; ①配置好下列图中圈出来的文件 ②在VM选项中输入&#xff1a;“-DarchetypeInternal” ③点击应用&#xff0c;再点击确定 ④还是不行 解决办法&#x…

Kafka Streams:深度探索实时流处理应用程序

Apache Kafka Streams 是一款强大的实时流处理库&#xff0c;为构建实时数据处理应用提供了灵活且高性能的解决方案。本文将深入探讨 Kafka Streams 的核心概念、详细原理&#xff0c;并提供更加丰富的示例代码&#xff0c;以帮助读者深入理解和应用这一流处理框架。 1. Kafka…

HarmonyOS鸿蒙应用开发——HTTP网络访问与封装

文章目录 基本使用封装参考 基本使用 鸿蒙应用发起HTTP请求的基本使用&#xff0c;如下&#xff1a; 导入http模块创建httpRequest对象发起http请求&#xff0c;并处理响应结果 第一、导入http模块&#xff1a; import http from ohos.net.http第二、创建httpRequest对象&a…

【C++ 程序设计入门基础】- 第3节-循环结构02

目录 while 语句 案例 while 循环 输入一个整数 n &#xff0c;输出 1~n 的所有整数。 查看运行结果&#xff1a; while 语句结构解析 do while 语句 案例 do while 循环 输入一个整数n&#xff0c;输出1&#xff5e;n的所有整数。 查看运行结果 while、do while的区别 …

C语言 内联函数 + 递归函数

函数分类 内联函数 1&#xff09;内联函数在编译时将函数的代码直接插入到调用它的地方&#xff0c;而不是通过函数调用的方式执行&#xff0c;从而减少了函数调用的开销&#xff0c;提高了代码的执行速度 2&#xff09;使用 inline 关键字来声明 3&#xff09;将函数声明为内联…