Linux Component概述和高通V4l2驱动模型

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/256999.html

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

相关文章

CentOS系统中设置反向代理服务器的步骤

在CentOS系统中设置反向代理服务器可以帮助你隐藏原始服务器的细节,并提高服务器的安全性。以下是在CentOS系统中设置反向代理服务器的步骤概述: 安装反向代理软件: 常见的反向代理软件包括Nginx和Apache。你可以选择其中之一来作为你的反向…

postgresql从入门到精通 - 第37讲:postgres物理备份和恢复概述

PostgreSQL从小白到专家,是从入门逐渐能力提升的一个系列教程,内容包括对PG基础的认知、包括安装使用、包括角色权限、包括维护管理、、等内容,希望对热爱PG、学习PG的同学们有帮助,欢迎持续关注CUUG PG技术大讲堂。 第37讲&#…

找到字符串中所有字母异位词

题目描述 2. 解题思路&#xff1a; 创建两个整型的哈希表&#xff0c;双指针控制一个里面只放p,一个里面只放长度是p长度中s&#xff0c;不断增加 减少去比对 bool isMath(int *a, int *b) {for (int i 0; i < 26; i) {if (a[i] ! b[i]) {return false;}}return true; } i…

Redission分布式锁原理初探

什么是分布式锁&#xff0c;为什么需要分布式锁 在多线程并发请求当中&#xff0c;为了保证我们的资源同一时刻只有一个线程进行操作&#xff08;如商品超卖问题、购票系统等&#xff09;&#xff0c;我们通常要添加锁机制&#xff0c;如ReentrantLock&#xff0c;也就是可重入…

Volumetric Lights 2 HDRP

高清晰度渲染管道,包括先进的新功能,如半透明阴影图和直接灯光投射加上许多改进。 插件是一个快速,灵活和伟大的前瞻性光散射解决方案的高清晰度渲染管道。只需点击几下,即可改善场景中的照明视觉效果。 兼容: 点光源 聚光灯 碟形灯 矩形灯 通过覆盖摄像机周围大面积区域的…

nacos服务的分级存储

举例说明 一个服务可以有多个实例&#xff0c;比如我们当前有4个实例&#xff0c;都叫做nacos-user-service服务 ip地址端口服务器所属地区集群192.168.xxx.xxx18080广东GD192.168.xxx.xxx18081广东GD192.168.xxx.xxx18082广西GX192.168.xxx.xxx18083广西GX所以我们可以将nacos…

十五届蓝桥杯分享会(一)

注&#xff1a;省赛4月&#xff0c;决赛6月 一、蓝桥杯整体介绍 1.十四届蓝桥杯软件电子赛参赛人数&#xff1a;C 8w&#xff0c;java/python 2w&#xff0c;web 4k&#xff0c;单片机 1.8w&#xff0c;嵌入式/EDA5k&#xff0c;物联网 300 1.1设计类参赛人数&#xff1a;平…

12月7日作业

使用QT模仿一个登陆界面&#xff08;模仿育碧Ubisoft登录界面&#xff09; #include "myqq.h"MyQQ::MyQQ(QWidget *parent): QMainWindow(parent) {this->resize(880,550); //设置窗口大小this->setFixedSize(880,550); //固定窗口大小this->setStyleShee…

时间序列预测实战(二十四)PyTorch实现RNN进行多元和单元预测(附代码+数据集+完整解析)

一、本文介绍 本篇文章给大家带来的是利用我个人编写的架构进行RNN时间序列卷积进行时间序列建模&#xff08;专门为了时间序列领域新人编写的架构&#xff0c;简单且不同于市面上大家用GPT写的代码&#xff09;&#xff0c;包括结果可视化、支持单元预测、多元预测、模型拟合…

MySQL实战45讲-第1-2讲-一条SQL查询语句是如何执行的? 一条SQL更新语句是如何执行的

大体来说&#xff0c;MySQL可以分为Server层和存储引擎层两部分 Server层&#xff1a;Server层包括连接器、查询缓存、分析器、优化器、执行器等。以及所有的内置函数&#xff08;如日期、时间、数学和加密函数等&#xff09;&#xff0c;所有跨存储引擎的功能都在这一层实现&a…

探索 HTML 语义化:让你的网页更有意义(下)

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

1、初识 llvm源码编译 及virtualbox和ubuntu环境搭建

很久没更新了&#xff0c;最近准备研究逆向和加固&#xff0c;于是跟着看雪hanbing老师学习彻底搞懂ollvm&#xff0c;终于把所有流程跑通了&#xff0c;中间遇到了太多的坑&#xff0c;所以必须记录一下&#xff0c;能避免自己和帮助他人最好。 环境搭建太重要了&#xff0c;…