IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> 高通mm-camera_vendor -> 正文阅读

[系统运维]高通mm-camera_vendor

mm-camera 概述

1. 流程

高通将camera的所有功能划分为不同的模块,让模块自己来决定自己的事情(高内聚,低耦合),模块需要有统一的接口和格式。模块中有端口,通过端口把模块连接起来,又把模块挂在总线上。每一个端口的连接就是一个流,把这些流用pipeline来管理。

每次启动一个camera就创建一个sesion,由这个session来管理此camera的一切事物。对于每一个seeion,模块是共享的,它可以是camera的硬件资源也可以是其它资源(如一些软件算法等资源)

2.那么如何来定义这个模块的结构呢?

1.端口——端口属于模块,如果这个模块只有source端口,那么它就是一个src模块;如果只有sink端口就是sink模块,如果都有就是中间模块。没有端口的模块是不能连接到流中的,但他可以完成一些其他的功能,比如接收引擎的设置,报告事件到bus等。连接到流中的端口,也就是说流事件(set/get)主要通过端口来处理。而来自于引擎的(set/get)通过模块来处理,当然端口也可以把事件交给模块来处理。模块内部的端口可以通过模块来建立关系,也可以建立内部的连接,端口有关get/set process。

2.模块线程——每个模块可以有一个线程来处理模块的事情。一个线程对应一个队列,线程就是从队列中取出数据处理,然后应答回去。

3.总线回调——挡一个模块向总线注册时,总线向其提供一个回调函数,当模块有事件发生时,调用这个函数向bus发消息,然后总线把这个消息提交给管道,管道把这个消息顺着流发下去。

4.模块的get、set以及process。

3. 框架

pipeline 有两端,一端用于读,一端用于写.

camera 引擎对管道监控.

session 管理camera 引擎


media-controller

    |- mct——应该就是camera的引擎 里面包含了引擎、pipiline、bus、module、stream及event等定义及封装。

    |- modules ——  这里面就是划分好的一些模块代码,各模块大致功能如下 :

        |- sensor  ——  sensor 的驱动模块(src模块)

        |- iface     ——  ISP interface模块(inter模块)

        |- isp        —— 主要是ISP的处理,其内部又包含了众多的模块(inter模块)

        |- stats    —— 一些统计算法模块,如3A,ASD,AFD,IS,GRRO等数据统计的处理(sink模块)

        |- pproc   —— post process处理(inter模块)

        |- imglib   —— 主要是图片的一些后端处理,如HDR等(sink模块)

4.架构

在这里插入图片描述

mm-camera架构有2个版本
(1)最老的版本是有一个守护进程mm-qcamera-daemon的,
如msm8909平台,后来新版的架构改过,移除了这个守护进程,如msm8937(sdm429)平台。
(2) Android O 中,系统启动时,就会启动 CameraProvider 服务。它将 Camera HAL 从 cameraserver 进程中分离出来,做为一个独立进程 android.hardware.camera.provider@2.4-service 来控制 HAL。这两个进程之间经过 HIDL 机制进行通讯

4.1 media controller线程

MCT线程是camera新架构的引擎部分,负责对管道的监控,由此来完成一个camera设备的控制运转。

  1. 旧版本
    运行在daemon进程空间,由MSM_CAMERA_NEW_SESSION事件来开启,具体开启函数为server_process_hal_event—>mct_controller_new()。
    server_process_hal_event() -> mct_controller_new() //“vendor/qcom/proprietary/mm-camera/mm-camera2/server-imaging/server.c”

  2. 新版本
    mm_camera_module_open_session() //“hardware/qcom/camera/QCamera2/stack/mm-camera-interface/src/mm_camera_interface.c”
    shim_ops_tbl->mm_camera_shim_open_session = mct_shimlayer_start_session; //“vendor/qcom/proprietary/mm-camera/mm-camera2/media-controller/mct_shim_layer/mct_shim_layer.c”
    mct_shimlayer_start_session -> mct_controller_new()

mct_controller_new()
    1.mct_pipeline_new()
    ---->创建一个Pipeline及其bus,并完成pipeline函数的映射。
    2.mct_pipeline_start_session()
        ---->开启camera的所有模块并查询其能力
    3.pthread_create(..., mct_controller_thread_run, ...)
        ---->创建mct线程并开始执行
    4.pthread_create(..., mct_bus_handler_thread_run, ...)
        ---->创建bus处理线程

MCT整个引擎部分主要处理server及bus两类事情,对应前面提到的MCT及bus两个线程。MCT线程主要用来处理来自image server的消息,先pop MCT queue,查看是否有消息,如果有则执行mct_controller_proc_serv_msg_internal()函数来处理。

mct_controller_proc_serv_msg_internal函数用来处理来自image server的消息,并返回类型MCT_PROCESS_RET_SERVER_MSG。这里处理的消息类型主要有SERV_MSG_DS与SERV_MSG_HAL两种,分别在pipline中给出了相应的处理函数

参考: https://blog.csdn.net/u012839187/article/details/87306144

4.2 旧版本mm-qcamera-daemon

在这里插入图片描述
mm-qcamera-daemo进程是hal和kernel沟通的桥梁。
mm-qcamera-daemon处于hal与kernel之间,进行hal与kernel的通信,
例如:
应用在发出操作camera的执行命令之后,通过framwork、hal,之后通过ioctl调用到kernel中,kernel则发送消息到daemon中,daemon接到消息之后再发送消息到各个module中,各个module操作实际硬件完成相应操作。

code:“vendor/qcom/proprietary/mm-camera/mm-camera2/server-imaging/server.c”

1 、在Server.c中从mian()函数进入
(1) find server node name and open the node,找到server节点并且打开节点
(2) after open node, initialize modules,打开节点后初始化模块
2、在初始化模块中
(1) 调用server_process_module_sensor_init() 进入server_process.c中的boolean server_process_module_sensor_init(void)函数
(2) 根据modules_list[0]初始化list数组中的模块,初始化模块包含sensor,iface,isp,stats,pproc和imglib
static mct_module_init_name_t modules_list[] = {
 {"sensor", module_sensor_init,   module_sensor_deinit, NULL},
 {"iface",  module_iface_init,   module_iface_deinit, NULL},
 {"isp",    module_isp_init,      module_isp_deinit, NULL},
 {"stats",  stats_module_init,    stats_module_deinit, NULL},
 {"pproc",  pproc_module_init,    pproc_module_deinit, NULL},
 {"imglib", module_imglib_init, module_imglib_deinit, NULL},
};
3、Sensor模块初始化过程
(1) 调用module_sensor_init函数进入module_sensor.c中的mct_module_t *module_sensor_init(const char *name)函数
(2) Create MCT module for sensor,为sensor创建MCT Module
(3) Fill function table in MCT module,填充功能表
(4) Create sensor module control structure that consists of bundle information,创建sensor module control结构体:module_ctrl = malloc(sizeof(module_sensor_ctrl_t))
(5) module_sensor_probe_sensors,sensor识过程,在server_init.c中调用sensor_init_probe函数
    1 > 打开设备节点"/dev/video0"
    2 > Open sensor_init subdev,找到subdev并且打开
    3 > sensor识别过程
(6) module_sensor_find_other_subdev(module_ctrl),找到sensor外的其他子设备,为每一个自设备创建sensor_bundle,并填充设备信息到sensor_bundle
(7) Create ports based on CID info,为sensor_bundle创建端口
(8) intiialize the eeprom,初始化eeprom,module_sensor_init_eeprom
4、iface、isp、stats、pproc和imglib相继进行初始化操作
5、进入主循环来处理来自HAL及MCT的事件及消息,处理完之后的结果反馈给kernel

mm-qcamera-daemon守护进程具体参考:https://blog.csdn.net/huifeidedabian/article/details/77949419

4.3 新版本 android.hardware.camera.provider@2.4-service

在 Android O 中,系统启动时,就会启动 CameraProvider 服务。它将 Camera HAL 从 cameraserver 进程中分离出来,作为一个独立进程 android.hardware.camera.provider@2.4-service 来控制 HAL。
这两个进程之间通过 HIDL 机制进行通信。

这样的改动源自于 Android O 版本加入的 Treble 机制,它的主要功能(如下图所示)是将 service 与 HAL 隔离,以方便 HAL 部分进行独立升级。这其实和 APP 与 Framework 之间的 Binder 机制类似,通过引入一个进程间通信机制而针对不同层级进行解耦(从 Local call 变成了 Remote call)。

在这里插入图片描述

在这里插入图片描述

  1. camera provide 启动
    hardware/interfaces/camera/provider/2.4/default/android.hardware.camera.provider@2.4-service.rca
service vendor.camera-provider-2-4 /vendor/bin/hw/android.hardware.camera.provider@2.4-service
    interface android.hardware.camera.provider@2.4::ICameraProvider legacy/0
    class hal
    user cameraserver
    group audio camera input drmrpc
    ioprio rt 4
    capabilities SYS_NICE
    task_profiles CameraServiceCapacity HighPerformance
________________________________________    
service <name> <pathname> [ <argument> ]*
       <option>
       <option>
       ...
<option>服务的修饰符。它们影响init运行服务的方式和时间。
class hal:
    该服务属于类hal,在init启动hal类服务的时候,该服务也会被启动,hal类的启动点则在init.rc文件中       
user&&group:
    以system的用户和组的身份来运行该服务。

hardware/interfaces/camera/provider/2.4/default/service.cpp

int main()
{
    ALOGI("Camera provider Service is starting.");
    // The camera HAL may communicate to other vendor components via
    // /dev/vndbinder
    android::ProcessState::initWithDriver("/dev/vndbinder");
    return defaultPassthroughServiceImplementation<ICameraProvider>("legacy/0", /*maxThreads*/ 6);
}
* android::ProcessState::initWithDriver :camera HAL 经过 /dev/vndbinder 驱动可与其余模块的HAL进行通讯;
* defaultPassthroughServiceImplementation :建立默认为直通模式(passthrough)的 CameraProvider 服务;

具体参考:https://blog.csdn.net/qq_16775897/article/details/81240600
没有完全理解调用

5.vendor code 流程

hal 层掉用的mm-camera 的接口
*(void **)&mm_camera_shim_module_init =
        dlsym(qdaemon_lib, "mct_shimlayer_process_module_init");  //"hardware/qcom/camera/QCamera2/stack/mm-camera-interface/src/mm_camera_interface.c"
mct_shimlayer_process_module_init() //"vendor/qcom/proprietary/mm-camera/mm-camera2/media-controller/mct_shim_layer/mct_shim_layer.c"

现分析mm-camera 入口函数

mm-camera 代码结构,库 libmmcamera2_mct_shimlayer.so 入口函数 mct_shimlayer_process_module_init 
mct_shimlayer_process_module_init() //"vendor/qcom/proprietary/mm-camera/mm-camera2/media-controller/mct_shim_layer/mct_shim_layer.c"
    mct_util_init_imager_session() //"vendor/qcom/proprietary/mm-camera/mm-camera2/media-controller/mct/tools/mct_util.c"
        open(/dev/mediaX) --匹配到 msm_config 为止
        MEDIA_IOC_ENUM_ENTITIES //获取实列 entity 
        open(/dev/v4l2-subdevX)
        VIDIOC_MSM_SENSOR_CFG  //cfg.cfg.sensor_info.session_id =4 n680x imager_session_id =4
    get_config_node_name() //得到video device 的node_name
    mct_shimlayer_module_sensor_init() //会找到module_list 中的init_mod 
        static mct_module_init_name_t modules_list[] = {
        {"sensor", module_sensor_init,   module_sensor_deinit, NULL},
        {"iface",  module_iface_init,   module_iface_deinit, NULL},
        {"isp",    module_isp_init,      module_isp_deinit, NULL},
        {"stats",  stats_module_init,    stats_module_deinit, NULL},
        {"pproc",  pproc_module_init,    pproc_module_deinit, NULL},
        {"imglib", module_imglib_init, module_imglib_deinit, NULL},
        };
调用开始后会初始化各个模块,其中就包括sensor模块,sensor初始化入口函数即为module_sensor_init(...)。这个函数将创建sensor模块并返回其指针,另外将创建它的端口,填充一些功能函数等。
module_sensor_init() //"vendor/qcom/proprietary/mm-camera/mm-camera2/media-controller/modules/sensors/module/module_sensor.c"
    mct_module_create() //创建MCT module for sensor 之后填充set mode、query mode、start session、stop session及set session data五个接口函数。
    struct mct_module_t  // 填充mct_module_t 的结构体.
    struct module_sensor_ctrl_t //此结构体包含bundle信息,用来构建前面提到的模块树(方便添加、遍历等操作)
    s_module->numsinkports = 0; sensor模块是source模块,所以其numsinkports应该设置为0。 
    eebin_interface_init()
    eebin_interface_control() 
        eebin_get_bin_data()
            eebin_read() //读不到
    sensor_init_probe() \\"vendor/qcom/proprietary/mm-camera/mm-camera2/media-controller/modules/sensors/module/sensor_init.c"
        open(/dev/v4l-subdevX)
        sensor_init_eebin_probe() //没有实质意义
            eebin_interface_control() 
        sensor_init_xml_probe()
            /vendor/etc/camera/hon660-CT60-XXX
            sensor_probe()
                sensor_load_library()  //加载libmmcamera_X.so 
                    sensor_open_lib()函数指针调用到驱动的参数 ,信息存放在sensor_lib_params_t *sensor_lib_params; 
                translate_sensor_slave_info //填充struct msm_camera_sensor_slave_info (xml里的配置信息xmlConfig->configPtr,, driver.h 中的电源设置sensor_lib_params)
                VIDIOC_MSM_SENSOR_INIT_CFG -> msm_sensor_driver_cmd() //"kernel/msm-4.19/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_init.c"
                    msm_sensor_driver_probe() //将slave_info传递给kernel  "kernel/msm-4.19/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_init.c"
                        msm_sensor_get_power_settings() //上下电信息
                        msm_sensor_fill_eeprom_subdevid_by_name // 设置 eeprom_subdev_id 值等于 cell-index
                        msm_sensor_fill_actuator_subdevid_by_name // actuator_subdev_id
                        msm_sensor_power_up()  //"kernel/msm-4.19/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.c"
                            msm_camera_power_up() //供电
                                msm_camera_pinctrl_init() //从链表中找出 "cam_default" 和 "cam_suspend"                                
                                //pinctrl-names = "cam_default", "cam_suspend";默认就这么配置,前面代表clk,后面代表reset脚和standby脚,唤醒作用。
                                msm_camera_request_gpio_table()
                                    gpio_request_one() //设置gpio 对应名称goio_label , 设置输入输出 flag
                            msm_sensor_check_id() //检查id
                                msm_sensor_match_id() //匹配i2c 读取的id 与驱动中的匹配
                        msm_sensor_driver_create_v4l_subdev() //    
                            camera_init_v4l2() 
                                media_device_init() //初始化media_device 的链表
                                media_device_register() //
                                    media_devnode_register() /**
                                    * 1. 找到设备号 2.初始化media_devnode_fops 3. 添加一个媒体设备,在系统中生成/dev/mediaX节点
                                    * 4.表明已注册 */
                                    device_create_file(&devnode->dev, &dev_attr_model); //./platform/soc/ca00000.qcom,msm-cam/media0/model
                                media_entity_pads_init() //建立media_entity与media_pad之间的链接:
                                v4l2_device_register() //
                                strlcpy(pvdev->vdev->name, "msm-sensor", sizeof(pvdev->vdev->name)); // 
                          	   /**
                          	   /sys/class/video4linux/video3 # cat name
								msm-sensor

                          	   */
                                video_register_device() //
                                    __vilde_register_device()
                                        device_register()
                                        video_register_media_controller()
                                            media_device_register_entity(vdev->v4l2_dev->mdev, &vdev->entity);
                                            v4l2_subdev_init()    
                                            media_entity_pads_init()
                                            msm_sd_register()
                                                __msm_sd_register_subdev()
                                                    v4l2_device_register_subdev()
                                                        media_device_register_entity()
                                                    __video_register_device()
    module_sensor_find_other_subdev()
        LOG_IOCTL(dev_fd, MEDIA_IOC_DEVICE_INFO, &mdev_info, "dev_info"); //kernel/msm-4.4/drivers/media/media-device.c 查看media 子系统https://blog.csdn.net/h_8410435/article/details/125256578?spm=1001.2014.3001.5501
    module_sensors_subinit()  // 初始化senosr modules , 注意struct sensor_func_tbl_t
        static int32_t (*sub_module_init[SUB_MODULE_MAX])(sensor_func_tbl_t *) = {
        [SUB_MODULE_SENSOR]       = sensor_sub_module_init,     //vendor/qcom/proprietary/mm-camera/mm-camera2/media-controller/modules/sensors/module/module_sensor.c {sensor_open,sensor_process}
        [SUB_MODULE_CHROMATIX]    = chromatix_sub_module_init,    //
        [SUB_MODULE_ACTUATOR]     = actuator_sub_module_init,
        [SUB_MODULE_EEPROM]       = eeprom_sub_module_init,
        [SUB_MODULE_LED_FLASH]    = led_flash_sub_module_init,
        [SUB_MODULE_CSIPHY]       = csiphy_sub_module_init,
        [SUB_MODULE_CSIPHY_3D]    = csiphy_sub_module_init,
        [SUB_MODULE_CSID]         = csid_sub_module_init,
        [SUB_MODULE_CSID_3D]      = csid_sub_module_init,
        [SUB_MODULE_OIS]          = ois_sub_module_init,
        [SUB_MODULE_EXT]          = external_sub_module_init,
        [SUB_MODULE_IR_LED]       = ir_led_sub_module_init,
        [SUB_MODULE_IR_CUT]       = ir_cut_sub_module_init,
        [SUB_MODULE_LASER_LED]    = laser_led_sub_module_init
        };
    port_sensor_create() //创建port基于CID信息,port_sensor_create是port_sensor.c的函数
    module_sensor_init_eeprom() // 初始化eeprom
    module_sensor_init_chromatix() // 创建chromatix manger
                            
  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2022-06-18 23:34:08  更:2022-06-18 23:36:10 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 14:23:19-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码