1. camera provider
目录:hardware/interfaces/camera/
service.cpp->cameraprovider_2_4.cpp(HIDL_FETCH_ICameraProvider)->HIDL_FETCH_ICameraProvider->new CameraProvider
2. camx hal3
A. init:先调用mModule->init (CameraModule.cpp),通过ID 进入camxhal3entry.cpp入口,在init通过static_castHAL3Module::GetInstance()
静态方法实例化了HAL3Module对象,
在其构造方法里面通过HwEnvironment::GetInstance()静态方法又实例化了HwEnvironment对象,
在其构造方法中,实例化了SettingsManager
对象,然后又在它构造方法中通过OverrideSettingsFile
对象获取了位于/vendor/etc/camera/camoverridesettings.txt
文件中的平台相关的配置信息(通过这种Override机制方便平台厂商加入自定义配置),该配置文件中,可以加入平台特定的配置项,比如可以通过设置multiCameraEnable的值来表示当前平台是否支持多摄,或者通过设置overrideLogLevels设置项来配置CamX-CHI部分的Log输出等级等等。
camx/src/core/hal/camxhal3entry.cpp
CAMX_VISIBILITY_PUBLIC camera_module_t HAL_MODULE_INFO_SYM =
{
.common =
{
.tag = HARDWARE_MODULE_TAG,
.module_api_version = CAMERA_MODULE_API_VERSION_CURRENT,
.hal_api_version = HARDWARE_HAL_API_VERSION,
.id = CAMERA_HARDWARE_MODULE_ID,
.name = "QTI Camera HAL",
.author = "Qualcomm Technologies, Inc.",
.methods = &CamX::g_hwModuleMethods
},
.get_number_of_cameras = CamX::get_number_of_cameras,
.get_camera_info = CamX::get_camera_info,
.set_callbacks = CamX::set_callbacks,
.get_vendor_tag_ops = CamX::get_vendor_tag_ops,
.open_legacy = CamX::open_legacy,
.set_torch_mode = CamX::set_torch_mode,
.init = CamX::init
};
static camera3_device_ops_t g_camera3DeviceOps =
{
.initialize = CamX::initialize,
.configure_streams = CamX::configure_streams,
.construct_default_request_settings = CamX::construct_default_request_settings,
.process_capture_request = CamX::process_capture_request,
.dump = CamX::dump,
.flush = CamX::flush,
};
int init()
{
JumpTableHAL3* pHAL3 = static_cast(g_dispatchHAL3.GetJumpTable());
CAMX_ASSERT(pHAL3);
CAMX_ASSERT(pHAL3->init);
return pHAL3->init();
}
camx/src/core/hal/camxhal3.cpp
static int get_number_of_cameras(void)
{
CAMX_ENTRYEXIT_SCOPE(CamxLogGroupHAL, SCOPEEventHAL3GetNumberOfCameras);
return static_cast(HAL3Module::GetInstance()->GetNumCameras());
}
B. 同时在HwEnvironment
构造方法中会调用其Initialize方法,其中mode为CSLHwEnabled, 在该方法中实例化了CSLModeManager
对象,并通过CSLModeManager提供的接口,获取了所有底层支持的硬件设备信息,其中包括了Camera Request Manager、CAPS模块(该驱动模块主要用于CSL获取Camera平台驱动信息,以及IPE/BPS模块的电源控制)以及Sensor/IPE/Flash等硬件模块,还加载了chi-cdk的so库,并且通过调用CSLHwInternalProbeSensorHW
方法获取了当前设备安装的Sensor模组信息,并且将获取的信息暂存起来,等待后续阶段使用,总得来说在HwEnvironment初始化的过程中,通过探测方法获取了所有底层的硬件驱动模块,并将其信息存储下来供后续阶段使用。其中用到event事件的用法。
camx\src\core\camxhwenvironment.cpp
CamxResult HwEnvironment::Initialize()
{
result = CSLInitialize(¶ms); //open subdev等等设备
result = ProbeChiComponents(pExternalComponent, &m_numExternalComponent); //加载chi-cdk库
}
HwEnvironment* HwEnvironment::GetInstance()
{
static HwEnvironment s_HwEnvironmentSingleton;
if (InitCapsInitialize == s_HwEnvironmentSingleton.m_initCapsStatus)
{
s_HwEnvironmentSingleton.InitCaps();
}
return &s_HwEnvironmentSingleton;
}
VOID HwEnvironment::InitCaps()
{
EnumerateDevices();
ProbeImageSensorModules(); //读取com.qti.sensormodule.*.bin
EnumerateSensorDevices(); //CSLEnumerateDevices->CSLHwInternalProbeSensorHW,下发
//CAM_SENSOR_PROBE_CMD,match硬件是否成功;
InitializeSensorSubModules(); //check VIDIOC_SUBSCRIBE_EVENT(V4L_EVENT_CAM_REQ_MGR_SENSOR_LOCK) CAM_HANDLE_USER_POINTER
InitializeSensorStaticCaps();
result = m_staticEntryMethods.GetStaticCaps(&m_platformCaps[0]); //camxtitan17xcontext.cpp
}
VOID HwEnvironment::ProbeImageSensorModules()
{
result = ImageSensorModuleDataManager::Create(&pSensorManager, this); //获取驱动module数据
cam_map |= set_cam_map(pSensorName); // 比对驱动sensor_name 和hal定义是否一致。
result = pData->Probe(&detected, &deviceIndex); //ImageSensorModuleData::Probe
}
camx\src\csl\hw\camxcslhw.cpp
CamxResult CSLInitializeHW()
{
// 查找并获取/dev/videoX 设备,该节点对应着Kernel部分的Request Manager
CSLHwEnumerateAndAddCSLHwDevice(CSLInternalHwVideodevice, CAM_VNODE_DEVICE_TYPE);
// 查找并获取/dev/v4l-subdevX cpas设备
CSLHwEnumerateAndAddCSLHwDevice(CSLInternalHwVideoSubdevice, CAM_CPAS_DEVICE_TYPE);
// 查找并获取/dev/v4l-subdevX其它设备,诸如Sensor/IFE/IPE/Flash等
CSLHwEnumerateAndAddCSLHwDevice(CSLInternalHwVideoSubdeviceAll, 0);
// g_pCSLModeManager 为CSLModeManager
g_pCSLModeManager = CAMX_NEW CSLModeManager(pInitializeParams);
}
CamxResult CSLImageSensorProbeHW(
CSLMemHandle hPacket,
SIZE_T offset,
CSLImageSensorProbeResult* pProbeResult)
{
CamxResult result = CamxResultEFailed;
if ((NULL != pProbeResult) && (CSLInvalidHandle != hPacket))
{
if (TRUE == CSLHwInstanceGetRefCount())
{
INT32 deviceIndex;
result = CSLHwInternalProbeSensorHW(hPacket, offset, &deviceIndex);
if (CamxResultSuccess == result)
{
pProbeResult->detected = TRUE;
pProbeResult->deviceIndex = deviceIndex;
}
CSLHwInstancePutRefCount();
}
}
else
{
result = CamxResultEInvalidArg;
}
return result;
}
camx\src\core\camximagesensormoduledata.cpp
camximagesensormoduledata.cpp
CamxResult ImageSensorModuleData::Probe(
BOOL* pDetected,
INT32* pDeviceIndex){
result = CSLImageSensorProbe(pProbePacket->GetMemHandle(), pProbePacket->GetOffset(), &probeResult);
result = GetSensorDataObject()->LoadSensorLibrary(); //加载/vendor/lib64/camera/com.qti.sensor.*.so
}
camx\src\csl\hw\camxcslhwinternalsensor.cpp
CamxResult CSLHwInternalProbeSensorHW(
CSLMemHandle hPacket,
SIZE_T offset,
INT32* pDeviceIndex)
{
ioctlCmd.op_code = CAM_SENSOR_PROBE_CMD;
ioctlCmd.size = sizeof(ioctlCmd.handle);
ioctlCmd.handle_type = CAM_HANDLE_MEM_HANDLE;
ioctlCmd.reserved = 0;
ioctlCmd.handle = hPacket;
result = pLoophw->deviceOp.Ioctl(pLoophw, VIDIOC_CAM_CONTROL, &ioctlCmd);
result = CSLHwInternalDefaultSubscribeEvents(&g_CSLHwInstance.CSLHwSensorSlotDevices[hIndex],
V4L_EVENT_CAM_REQ_MGR_SENSOR_LOCK,
CAM_SENSOR_EVENT_TYPE); // 使用event handle
ioctlCmd.op_code = CAM_SENSOR_INTR_INIT;
ioctlCmd.size = sizeof(cam_sensor_gpio_intr_config);
ioctlCmd.handle_type = CAM_HANDLE_USER_POINTER;
ioctlCmd.reserved = 0;
ioctlCmd.handle = (uint64_t)pIntrInfo;
result = ioctl(deviceFd, VIDIOC_CAM_CONTROL, &ioctlCmd);
}
3. 之后通过调用HwEnvironment对象中的ProbeChiComponents
方法在/vendor/lib64/camera/components路径下找寻各个Node生成的So库,并获取Node提供的标准对外接口,这些Node不但包括CHI部分用户自定义的模块,还包括了CamX部分实现的硬件模块,并最后都将其都存入ExternalComponentInfo
对象中,等待后续阶段使用。 (camxhal3module.cpp ->camxchicomponent.cpp(Initialize)-> camxchicomponent.cpp(ProbeChiComponents));
从上图不难看出,在HAL3Module构造方法中会去通过dlopen方法加载com.qti.chi.override.so库,并通过dlsym映射出CHI部分的入口方法chi_hal_override_entry,并调用该方法将HAL3Module对像中的成员变量m_ChiAppCallbacks(CHIAppCallbacks)传入CHI中,其中包含了很多函数指针,这些函数指针分别对应着CHI部分的操作方法集中的方法,一旦进入到CHI中,就会将CHI本地的操作方法集合中的函数地址依次赋值给m_ChiAppCallbacks,这样CamX后续就可以通过这个成员变量调用到CHI中方法,从而保持了与CHI的通讯。
同样地,CHI中的ExtensionModule在初始化的时候,其构造方法中也会通过调用dlopen方法加载camera.qcom.so库,并将其入口方法ChiEntry通过dlsym映射出来,之后调用该方法,将g_chiContextOps(ChiContextOps,该结构体中定义了很多指针函数)作为参数传入CamX中,一旦进入CamX中,便会将本地的操作方法地址依次赋值给g_chiContextOps中的每一个函数指针,这样CHI之后就可以通过g_chiContextOps访问到CamX方法。
Camx 基本组件及其结构关系_yaoming168的博客-CSDN博客