MTK Camera上电流程分析
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_SUPPORTmi4DeviceNum = mEnumMap.size() + mExternalDeviceInfoMap.size() - 1;MY_LOGD("#devices:%d #remote:%u mEnumMap:%u", mi4DeviceNum, mExternalDeviceInfoMap.size(), mEnumMap.size());
#elseMY_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_METADATANSMetadataProviderManager::clear();
#endif
#if OPTION__NEED_DEVMETAINFODevMetaInfo::clear();
#endifmEnumMap.clear();
//------------------------------------------------------------------------------
#if '1'==MTKCAM_HAVE_SENSOR_HAL//IHalSensorList*const pHalSensorList = IHalSensorList::get();size_t const sensorNum = pHalSensorList->searchSensors();
#if 0SensorHal::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 sensorinfoquerySensorDrvInfo();//fill in metadatabuildSensorMetadata();
接着比较重要的就是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_ENABLEsensorDevs |= SENSOR_ATV;#endifreturn 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_IMGSENSORfor (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_IMGSENSORfor (SensorEnum = DUAL_CAMERA_MAIN_SENSOR; SensorEnum <= DUAL_CAMERA_SUB_SENSOR; SensorEnum <<= 1) {LOG_MSG("impSearchSensor search to sub\n");#elsefor (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 listif (m_pstSensorInitFunc[i].getCameraDefault == NULL) {LOG_MSG("m_pstSensorInitFunc[i].getCameraDefault is NULL: %d \n", i);break;}//set sensor driverid[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<SENSOR_ID> 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<SENSOR_ID> 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检测。
在kd_sensorlist.c里可以查看到相关的调用
#endifcase 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); //设置为FALSE g_bEnableDriver[i] = FALSE; //前后摄标志获取,1为后摄,2为前摄 g_invokeSocketIdx[i] = (CAMERA_DUAL_CAMERA_SENSOR_ENUM)((pDrvIndex[i] & KDIMGSENSOR_DUAL_MASK_MSB) >> KDIMGSENSOR_DUAL_SHIFT);spin_unlock(&kdsensor_drv_lock); //获取从上层传递下来的hal层的sensorlist里面排在第i顺序的imgsensor 的index drvIdx[i] = (pDrvIndex[i] & KDIMGSENSOR_DUAL_MASK_LSB);/* */ //判断数组里是否已经存在了driver if (DUAL_CAMERA_NONE_SENSOR == g_invokeSocketIdx[i]) {continue;}if (DUAL_CAMERA_SUB_SENSOR == g_invokeSocketIdx[i]) {spin_lock(&kdsensor_drv_lock);gI2CBusNum = SUPPORT_I2C_BUS_NUM2;spin_unlock(&kdsensor_drv_lock);/* PK_XLOG_INFO("kdSetDriver: switch I2C BUS2\n"); */} else {spin_lock(&kdsensor_drv_lock);gI2CBusNum = SUPPORT_I2C_BUS_NUM1;spin_unlock(&kdsensor_drv_lock);/* PK_XLOG_INFO("kdSetDriver: switch I2C BUS1\n"); */}#endifPK_INF("g_invokeSocketIdx[%d]=%d,drvIdx[%d]=%d\n", i, g_invokeSocketIdx[i], i, drvIdx[i]);/* PK_INF("[kdSetDriver]drvIdx[%d] = %d\n", i, drvIdx[i]); *//* */if (MAX_NUM_OF_SUPPORT_SENSOR > drvIdx[i]) {if (NULL == pSensorList[drvIdx[i]].SensorInit) {PK_ERR("ERROR:kdSetDriver()\n");return -EIO;} pSensorList[drvIdx[i]].SensorInit(&g_pInvokeSensorFunc[i]);if (NULL == g_pInvokeSensorFunc[i]) {PK_ERR("ERROR:NULL g_pSensorFunc[%d]\n", i);return -EIO;}/* */spin_lock(&kdsensor_drv_lock);g_bEnableDriver[i] = TRUE;spin_unlock(&kdsensor_drv_lock);/* get sensor name */memcpy((char *)g_invokeSensorNameStr[i], (char *)pSensorList[drvIdx[i]].drvname, sizeof(pSensorList[drvIdx[i]].drvname));/* return sensor ID *//* pDrvIndex[0] = (unsigned int)pSensorList[drvIdx].SensorId; */PK_INF("[%d][%d][%d][%s]\n", i, g_bEnableDriver[i], g_invokeSocketIdx[i], g_invokeSensorNameStr[i]);}}return 0;}
MTK Camera上电流程分析相关推荐
- Android 8.1/9.0 MTK Camera源码分析之录像快门声音控制流程
前面已经针对拍照快门声音控制流程进行了分析,接下来分析一下录像快门声音的控制流程. Android 8.1/9.0 MTK Camera源码分析之快门声音控制流程 这两篇文章其实都是相对于手机系统RO ...
- Android 8.1/9.0 MTK Camera源码分析之快门声音控制流程
Android 8.1/9.0 MTK Camera源码分析之快门声音控制 在Android 8.1上mtk camera有控制快门声音的接口,但是并没有了控制录像快门声音的接口.之所以会有这个现象, ...
- Android LCD整理二:mtk平台LCD流程分析(LK部分)
一.LK显示代码分析 1.platform_init代码分析 //framebuffer的大小 g_fb_size = mt_disp_get_vram_size(); //framebuffer的起 ...
- Android MTK Camera驱动代码分析
一.Camera调用过程: imgsensor起到承上启下的作用,在系统起来时会创建整个camera驱动运行的环境,其中主要的文件和函数如下框图所示,先设备挂载时会调用注册platform设 ...
- mtk平台闪光灯流程分析
驱动模块加载和卸载module_init(flashlight_init); module_exit(flashlight_exit);static int __init flashlight_ini ...
- MTK Camera 开机启动流程
一.MTK平台Camera框架 MTK平台的Camera的架构见下图, 这里主要介绍kernel部分和HAL层部分. 1.Kernel 部分主要有两块: 1.1.image sensordriver, ...
- android mtk camera startpreview,android8.1 mtk camera hal各种操作流程
最近一年,一直在做android上的视频编解码和录相.以及camera hal和系统框架这一块.随着做的慢慢的深入,越发觉得mtk的camera hal这一块,有其独到之处.偏偏网上相关的资料却是极少 ...
- Android MTK Camera博客分享
MTK Camera博客分享 MTK Camera OTP调用过程 MTK Camera Flashlight调用过程 MTK Camera 应用层到底层过程 MTK Camera HAL层分析 深入 ...
- 【Mtk Camera Hal到驱动的流程(1)】
Mtk Camera Hal到驱动的流程(1) (1)架构介绍 (A)Camera 的框架分为 Kernel 部分和 Hal 部分 Kernel部分: image sensor driver -- 负 ...
最新文章
- 吴恩达:数据集的规模和学习机制都很重要!
- 企业数据中心和互联网数据中心有何不同?
- Pycharm 社区版本Database Navigator 安装教程
- php未知参数,php – 使用未知数量的参数创建Laravel Eloquent Query
- hibernate批量查询_使用Hibernate批量获取
- mysql插入日期_初识MySQL
- 【UX/UI原型模板】中国地图元件库操作说明(省份+直辖市+自治区+行政特区详细地图)
- 这可能是世界第一座海上漂浮城市,浑身都是黑科技!
- 哈佛大学幸福课笔记一
- NCRE考试感想 三级信息安全(上)
- [iOS][转]iOS 架构模式 - 简述 MVC, MVP, MVVM 和 VIPER (译)
- StreamWiki: Enabling Viewers of Knowledge SharingLive Streams to Collaboratively Generate Archival
- 【阿里云短信服务SMS】使用阿里云发送短信
- linux之bc命令使用详解_【原创】linux命令bc使用详解
- 漏洞通告 | Atlassian Confluence存在远程代码执行漏洞,悬镜云鲨RASP天然免疫防护...
- 不同强度等级下混凝土的弹性模量、轴心抗压强度标准值fck、轴心抗拉强度标准值ftk、轴心抗压强度设计值fcd、轴心抗拉强度设计值ftd (规范值)
- 【产品经理】 产品进阶之路(二):如何为失明的人设计一款钟表
- Java计算任意多边形面积
- 【安全科普】揭秘IPS之网络攻击的“字典”
- APUE读书笔记-第十章-信号
热门文章
- 读书印记 - 《历代经济变革得失》
- 对于无线传感网的初步认识
- 【UE5 水体系统】
- 为什么现在算法工程师薪酬这么高?
- 《安富莱嵌入式周报》第248期:2022.01.10--2022.01.16
- 买笔记本电脑的13个重要的验机步骤
- 【HDOJ】1493 QQpet exploratory park
- iFIXIT认为 HTC One M8 是近年最难维修的手机之一
- iOS something is trying to start the receiver simultaneously from more than one thread
- php 获取手机设备id,H5获取手机设备信息、app版本信息、ip地址