1、Camera上电过程中,系统会初始化一系列的服务,其中 就有CameraServer的相关服务,系统通过FrameWorks层调用get_number_of_camera函数,调用到hal层上vendor/mediatek/proprietary/hardware/mtkcam./legacy/module_hal/devicemgr/CamDeviceManagerBash.cpp里的函数
int32_t
CamDeviceManagerBase::
getNumberOfDevices()
{
RWLock::AutoWLock _l(mRWLock);
//
if ( 0 != mi4DeviceNum )
{
#if MTK_CROSSMOUNT_SUPPORT
mi4DeviceNum = mEnumMap.size() + mExternalDeviceInfoMap.size() - 1;
MY_LOGD("#devices:%d #remote:%u mEnumMap:%u", mi4DeviceNum, mExternalDeviceInfoMap.size(), mEnumMap.size());
#else
MY_LOGD("#devices:%d", mi4DeviceNum);
#endif
}
else
{
Utils::CamProfile _profile(__FUNCTION__, "CamDeviceManagerBase");
mi4DeviceNum = enumDeviceLocked();
_profile.print("");
}
//
return mi4DeviceNum;
}
这里只是调用了enumDeviceLocked函数,并将它的返回值(camera的个数),返回到上层。enumDeviceLocked的实现如
int32_t
CamDeviceManagerImp::
enumDeviceLocked()
{
status_t status = OK;
int32_t i4DeviceNum = 0;
//
#if '1'==MTKCAM_HAVE_METADATA
NSMetadataProviderManager::clear();
#endif
#if OPTION__NEED_DEVMETAINFO
DevMetaInfo::clear();
#endif
mEnumMap.clear();
//------------------------------------------------------------------------------
#if '1'==MTKCAM_HAVE_SENSOR_HAL
//
IHalSensorList*const pHalSensorList = IHalSensorList::get();
size_t const sensorNum = pHalSensorList->searchSensors();
#if 0
SensorHal::createInstance()->searchSensor();;
#endif
重点关注pHalSensorList->searchSensors()的调用流程
MUINT
HalSensorList::
searchSensors()
{
Mutex::Autolock _l(mEnumSensorMutex);
//
MY_LOGD("searchSensors");
return enumerateSensor_Locked();
}
MUINT
HalSensorList::
enumerateSensor_Locked()
{
int ret_count = 0;
int ret = 0;
//
#warning "[WARN] Simulation for enumerateSensor_Locked()"
MUINT halSensorDev = SENSOR_DEV_NONE;
NSFeature::SensorInfoBase* pSensorInfo ;
SensorDrv *const pSensorDrv = SensorDrv::get();
SeninfDrv *const pSeninfDrv = SeninfDrv::createInstance();
if(!pSeninfDrv) {
MY_LOGE("pSeninfDrv == NULL");
return 0;
}
ret = pSeninfDrv->init();
if(ret < 0) {
MY_LOGE("pSeninfDrv->init() fail");
return 0;
}
pSeninfDrv->setMclk1(1, 1, 1, 0, 1, 0, 0);
pSeninfDrv->setMclk2(1, 1, 1, 0, 1, 0, 0);
//pSeninfDrv->setMclk3(1, 1, 1, 0, 1, 0, 0); /* No main2 */
int const iSensorsList = pSensorDrv->impSearchSensor(NULL);
//query sensorinfo
querySensorDrvInfo();
//fill in metadata
buildSensorMetadata();
接着比较重要的就是impSearchSensor的实现。
MINT32
ImgSensorDrv::impSearchSensor(pfExIdChk pExIdChkCbf)
{
MUINT32 SensorEnum = (MUINT32) DUAL_CAMERA_MAIN_SENSOR;
MUINT32 i,id[KDIMGSENSOR_MAX_INVOKE_DRIVERS] = {0,0};
MBOOL SensorConnect=TRUE;
UCHAR cBuf[64];
MINT32 err = SENSOR_NO_ERROR;
MINT32 err2 = SENSOR_NO_ERROR;
ACDK_SENSOR_INFO_STRUCT SensorInfo;
ACDK_SENSOR_CONFIG_STRUCT SensorConfigData;
ACDK_SENSOR_RESOLUTION_INFO_STRUCT SensorResolution;
MINT32 sensorDevs = SENSOR_NONE;
IMAGE_SENSOR_TYPE sensorType = IMAGE_SENSOR_TYPE_UNKNOWN;
IMGSENSOR_SOCKET_POSITION_ENUM socketPos = IMGSENSOR_SOCKET_POS_NONE;
//! If imp sensor search process already done before,
//! only need to return the sensorDevs, not need to
//! search again.
if (SENSOR_DOES_NOT_EXIST != m_mainSensorId) {
//been processed.
LOG_MSG("[impSearchSensor] Already processed \n");
if (BAD_SENSOR_INDEX != m_mainSensorIdx) {
sensorDevs |= SENSOR_MAIN;
}
if (BAD_SENSOR_INDEX != m_main2SensorIdx) {
sensorDevs |= SENSOR_MAIN_2;
}
if (BAD_SENSOR_INDEX != m_subSensorIdx) {
sensorDevs |= SENSOR_SUB;
}
#ifdef ATVCHIP_MTK_ENABLE
sensorDevs |= SENSOR_ATV;
#endif
return sensorDevs;
}
GetSensorInitFuncList(&m_pstSensorInitFunc);
LOG_MSG("SENSOR search start \n");
if (-1 != m_fdSensor) {
::close(m_fdSensor);
m_fdSensor = -1;
}
sprintf(cBuf,"/dev/%s",CAMERA_HW_DEVNAME);
m_fdSensor = ::open(cBuf, O_RDWR);
if (m_fdSensor < 0) {
LOG_ERR("[impSearchSensor]: error opening %s: %s \n", cBuf, strerror(errno));
return sensorDevs;
}
// search main/main_2/sub 3 sockets
// DUAL_CAMERA_MAIN_SENSOR = 1 DUAL_CAMERA_SUB_SENSOR = 2
#ifdef MTK_MAIN2_IMGSENSOR
for (SensorEnum = DUAL_CAMERA_MAIN_SENSOR; SensorEnum <= DUAL_CAMERA_MAIN_2_SENSOR; SensorEnum <<= 1) {
LOG_MSG("impSearchSensor search to main_2\n");
#else
#ifdef MTK_SUB_IMGSENSOR
for (SensorEnum = DUAL_CAMERA_MAIN_SENSOR; SensorEnum <= DUAL_CAMERA_SUB_SENSOR; SensorEnum <<= 1) {
LOG_MSG("impSearchSensor search to sub\n");
#else
for (SensorEnum = DUAL_CAMERA_MAIN_SENSOR; SensorEnum < DUAL_CAMERA_SUB_SENSOR; SensorEnum <<= 1) {
LOG_MSG("impSearchSensor search to main\n");
#endif
#endif
//
for (i = 0; i < MAX_NUM_OF_SUPPORT_SENSOR; i++) {
//end of driver list
if (m_pstSensorInitFunc[i].getCameraDefault == NULL) {
LOG_MSG("m_pstSensorInitFunc[i].getCameraDefault is NULL: %d \n", i);
break;
}
//set sensor driver
id[KDIMGSENSOR_INVOKE_DRIVER_0] = (SensorEnum << KDIMGSENSOR_DUAL_SHIFT) | i;
LOG_MSG("set sensor driver id =%x\n", id[KDIMGSENSOR_INVOKE_DRIVER_0]);
err = ioctl(m_fdSensor, KDIMGSENSORIOC_X_SET_DRIVER,&id[KDIMGSENSOR_INVOKE_DRIVER_0] );
if (err < 0) {
LOG_ERR("ERROR:KDCAMERAHWIOC_X_SET_DRIVER\n");
}
//err = open();
err = ioctl(m_fdSensor, KDIMGSENSORIOC_T_CHECK_IS_ALIVE);
if (err < 0) {
LOG_MSG("[impSearchSensor] Err-ctrlCode (%s) \n", strerror(errno));
}
//
sensorType = this->getCurrentSensorType((SENSOR_DEV_ENUM)SensorEnum);
//
socketPos = this->getSocketPosition((CAMERA_DUAL_CAMERA_SENSOR_ENUM)SensorEnum);
//check extra ID , from EEPROM maybe
在impSearchSensor的实现中,它最先调用的GetSensorInitFuncList(&m_pstSensorInitFunc);去挂载hal层的功能函数。
ImgSensorDrv::
ImgSensorDrv()
: SensorDrv()
, m_fdSensor(-1)
, m_mainSensorId(SENSOR_DOES_NOT_EXIST)
, m_main2SensorId(SENSOR_DOES_NOT_EXIST)
, m_subSensorId(SENSOR_DOES_NOT_EXIST)
, m_mainSensorIdx(BAD_SENSOR_INDEX)
, m_main2SensorIdx(BAD_SENSOR_INDEX)
, m_subSensorIdx(BAD_SENSOR_INDEX)
, m_pMainSensorInfo(NULL)
, m_pSubSensorInfo(NULL)
, m_pstSensorInitFunc(NULL)
, mUsers(0)
查看类的构造,找到类的成员
MSDK_SENSOR_INIT_FUNCTION_STRUCT* m_pstSensorInitFunc;
继续查找MSDK_SENSOR_INIT_FUNCTION_STRUCT*
#define YUV_INFO(_id, name, getCalData)\
{ \
_id, name, \
NSFeature::YUVSensorInfo<_id>::createInstance(name, #name), \
(NSFeature::SensorInfoBase*(*)()) \
NSFeature::YUVSensorInfo<_id>::getInstance, \
NSFeature::YUVSensorInfo<_id>::getDefaultData, \
getCalData, \
NSFeature::YUVSensorInfo<_id>::getNullFlickerPara \
}
#define RAW_INFO(_id, name, getCalData)\
{ \
_id, name, \
NSFeature::RAWSensorInfo<_id>::createInstance(name, #name), \
(NSFeature::SensorInfoBase*(*)()) \
NSFeature::RAWSensorInfo<_id>::getInstance, \
NSFeature::RAWSensorInfo<_id>::getDefaultData, \
getCalData, \
NSFeature::RAWSensorInfo<_id>::getFlickerPara \
}
//MSDK_SENSOR_INIT_FUNCTION_STRUCT SensorList[MAX_NUM_OF_SUPPORT_SENSOR] =
MSDK_SENSOR_INIT_FUNCTION_STRUCT SensorList[] =
{
#if defined(S5K5E2YA_MIPI_RAW) || defined(S5K5E2YA_MIPI_RAW_9013)
RAW_INFO(S5K5E2YA_SENSOR_ID, SENSOR_DRVNAME_S5K5E2YA_MIPI_RAW, NULL),
#endif
#if defined(ST55A_MIPI_RAW_9013)
RAW_INFO(ST55A_SENSOR_ID, SENSOR_DRVNAME_ST55A_MIPI_RAW, NULL),
#endif
#if defined(GC2755MIPI_RAW_9013)
RAW_INFO(GC2755_SENSOR_ID, SENSOR_DRVNAME_GC2755_MIPI_RAW,NULL),
#endif
UINT32 GetSensorInitFuncList(MSDK_SENSOR_INIT_FUNCTION_STRUCT **ppSensorList)
{
if (NULL == ppSensorList) {
ALOGE("ERROR: NULL pSensorList\n");
return MHAL_UNKNOWN_ERROR;
}
*ppSensorList = &SensorList[0];
return MHAL_NO_ERROR;
} // GetSensorInitFuncList()
至此hal层和mtkcam开始关联起来,以上全红的文字是实现上比较巧妙的地方,框架中提供了一个单例实例,并让各种Sensor单独去实现以下比较重要的2个接口。
typedef NSFeature::RAWSensorInfo SensorInfoSingleton_T;
namespace NSFeature {
template <>
UINT32
SensorInfoSingleton_T::
impGetDefaultData(CAMERA_DATA_TYPE_ENUM const CameraDataType, VOID*const pDataBuf, UINT32 const size) const
{
UINT32 dataSize[CAMERA_DATA_TYPE_NUM] = {sizeof(NVRAM_CAMERA_ISP_PARAM_STRUCT),
sizeof(NVRAM_CAMERA_3A_STRUCT),
sizeof(NVRAM_CAMERA_SHADING_STRUCT),
sizeof(NVRAM_LENS_PARA_STRUCT),
sizeof(AE_PLINETABLE_T),
0,
sizeof(CAMERA_TSF_TBL_STRUCT)};
if (CameraDataType > CAMERA_DATA_TSF_TABLE || NULL == pDataBuf || (size < dataSize[CameraDataType]))
{
return 1;
}
switch(CameraDataType)
{
case CAMERA_NVRAM_DATA_ISP:
memcpy(pDataBuf,&CAMERA_ISP_DEFAULT_VALUE,sizeof(NVRAM_CAMERA_ISP_PARAM_STRUCT));
break;
case CAMERA_NVRAM_DATA_3A:
memcpy(pDataBuf,&CAMERA_3A_NVRAM_DEFAULT_VALUE,sizeof(NVRAM_CAMERA_3A_STRUCT));
break;
case CAMERA_NVRAM_DATA_SHADING:
memcpy(pDataBuf,&CAMERA_SHADING_DEFAULT_VALUE,sizeof(NVRAM_CAMERA_SHADING_STRUCT));
break;
case CAMERA_DATA_AE_PLINETABLE:
memcpy(pDataBuf,&g_PlineTableMapping,sizeof(AE_PLINETABLE_T));
break;
case CAMERA_DATA_TSF_TABLE:
memcpy(pDataBuf,&CAMERA_TSF_DEFAULT_VALUE,sizeof(CAMERA_TSF_TBL_STRUCT));
break;
default:
typedef NSFeature::RAWSensorInfo SensorInfoSingleton_T;
namespace NSFeature {
template <>
UINT32
SensorInfoSingleton_T::
impGetFlickerPara(MINT32 sensorMode, MVOID*const pDataBuf) const
{
ALOGD("impGetFlickerPara+ mode=%d", sensorMode);
ALOGD("prv=%d, vdo=%d, cap=%d, zsd=%d",
(int)e_sensorModePreview, (int)e_sensorModeVideoPreview, (int)e_sensorModeCapture, (int)e_sensorModeZsd );
FLICKER_CUST_PARA* para;
para = (FLICKER_CUST_PARA*)pDataBuf;
if(sensorMode == e_sensorModePreview)
get_flicker_para_by_Preview(para);
else if(sensorMode == e_sensorModeVideo)
{
get_flicker_para_by_Video(para);
}
else if(sensorMode == e_sensorModeCapture)
{
get_flicker_para_by_Capture(para);
}
else if(sensorMode == e_sensorModeVideo1)
{
分析完了hal层的关联,接着我们分析kenel层中camear sensor driver的关联
err = ioctl(m_fdSensor, KDIMGSENSORIOC_X_SET_DRIVER,&id[KDIMGSENSOR_INVOKE_DRIVER_0] );
if (err < 0) {
LOG_ERR("ERROR:KDCAMERAHWIOC_X_SET_DRIVER\n");
}
//err = open();
err = ioctl(m_fdSensor, KDIMGSENSORIOC_T_CHECK_IS_ALIVE);
if (err < 0) {
LOG_MSG("[impSearchSensor] Err-ctrlCode (%s) \n", strerror(errno));
}
从代码上看,mtkcam是通过ioctl去设置加载对应的driver并执行上下电id检测。
#endif
case KDIMGSENSORIOC_X_SET_DRIVER:
i4RetValue = kdSetDriver((unsigned int *)pBuff);
break;
int kdSetDriver(unsigned int *pDrvIndex)
{
ACDK_KD_SENSOR_INIT_FUNCTION_STRUCT *pSensorList = NULL;
u32 drvIdx[KDIMGSENSOR_MAX_INVOKE_DRIVERS] = {0, 0};//这个数组的大小是2
u32 i;
/* set driver for MAIN or SUB sensor */PK_INF("pDrvIndex:0x%08x/0x%08x\n", pDrvIndex[KDIMGSENSOR_INVOKE_DRIVER_0], pDrvIndex[KDIMGSENSOR_INVOKE_DRIVER_1]);/* Camera information */gDrvIndex = pDrvIndex[KDIMGSENSOR_INVOKE_DRIVER_0];
//获取driver层imgsensor的功能函数列表if (0 != kdGetSensorInitFuncList(&pSensorList)) {PK_ERR("ERROR:kdGetSensorInitFuncList()\n");return -EIO;}
//KDIMGSENSOR_INVOKE_DRIVER_0 = 0, KDIMGSENSOR_MAX_INVOKE_DRIVERS = 2
所以这里会被执行2次for (i = KDIMGSENSOR_INVOKE_DRIVER_0; i < KDIMGSENSOR_MAX_INVOKE_DRIVERS; i++) {/* */spin_lock(&kdsensor_drv_lock);