当前位置: 首页 > news >正文

SM8650 qcxserver.c STRM_Initialize

 STRM_Initialize

  streammanager 初始化流程

目录

 STRM_Initialize

 Gptp::Init

 Config::Init

 SensorManager::Init 

 SensorPlatform::SensorPlatformInit

SensorManager::LoadSensorLib

 SensorManager::OpenSensorLib

 SensorManager::DetectAll

 SensorManager::DetectHandlerThread

 SensorManager::ProcessDetectEvent


 /*** STRM_Initialize** @brief Initialize stream manager* @param initialization parameters** @return CAMERA_SUCCESS if successful;*/CamStatus_e STRM_Initialize(const QCarCamInit_t* pInitParams){QCX_LOG(STREAM_MGR, HIGH, "API: %s", __FUNCTION__);CamStatus_e result = CAMERA_EFAILED;StreamManager* pStrmManager = NULL;if (NULL == pInitParams){QCX_LOG(STREAM_MGR, ERROR, "Null pointer passed.");result = CAMERA_EBADPARAM;}else{/* Create Stream manager instance. */pStrmManager = StreamManager::GetInstance();if (NULL == pStrmManager){QCX_LOG(STREAM_MGR, ERROR, "Stream Manager instance creation failed.");result = CAMERA_ENOMEMORY;}else{result = CAMERA_SUCCESS;}}if (CAMERA_SUCCESS == result){QCX_LOG(STREAM_MGR, HIGH, "%s called with init params (flags=%#x, apiVersion=%u)", __FUNCTION__, pInitParams->flags, pInitParams->flags);result = pStrmManager->Initialize(pInitParams);if (CAMERA_SUCCESS == result){QCX_LOG(STREAM_MGR, DEBUG, "Stream Manager initialization success.");}/* No need to destroy stream manager instance on failure. */}return result;}

//解析xml errInjen 配置进行debug log 输出 

初始化解串器配置/cameraconfigsa8650.c配置的信息

/**
* @brief
* Function used to initialize.
*
* @param pInitParams [in]
* pointer to init params
*
* @return
* Status as defined in CamStatus_e
*/
CamStatus_e StreamManager::Initialize(const QCarCamInit_t* pInitParams)
{CamStatus_e result = CAMERA_SUCCESS;CAM_TRACE_LOG(STREAM_MGR, "StreamManager::Initialize");/* Check API version */if (pInitParams->apiVersion >= QCARCAM_VERSION_MINIMUM_COMPATIBLE){QCX_LOG(STREAM_MGR, ERROR, "API version %#x is not supported",pInitParams->apiVersion);result = CAMERA_ENOTSUPPORTED;}else{/* Initialize GPTP** GPTP service might not be available at this time and hence this* call might fail.* TODO. Need to try initializing at a later time.** We are not checking the error code here, since it is not a fatal error,* and we already have the error prints from inside the method */Gptp::GetInstance()->Init();/* Initalize dynamic configuration *///解析xml errInjen 配置进行debug log 输出 //errInjen未配置在xml中Config::GetInstance()->Init();/* TODO: Need to move it to SI_Init *///初始化解串器配置/cameraconfigsa8650.c配置的信息result = SensorManager::GetInstance()->Init();if (CAMERA_SUCCESS != result){QCX_LOG(STREAM_MGR, ERROR, "Failed in sensor manager init");}else{result = SensorManager::GetInstance()->DetectAll();if (CAMERA_SUCCESS != result){QCX_LOG(STREAM_MGR, ERROR, "Failed in sensor detection");}else{QCX_LOG(STREAM_MGR, HIGH, "Sensor Manager Init and DetectAll successful");/* TODO: Need to add init call for CSL */result = CAMXHAL::GetInstance()->Init();if (CAMERA_SUCCESS != result){QCX_LOG(STREAM_MGR, ERROR, "CAMX HAL Init failed");}else{result = CAMXHAL::GetInstance()->InitializeMetatable(&g_QccMetadataTable, g_metadataTableElemCount);if (CAMERA_SUCCESS != result){m_QccMetadatatable_init = false;QCX_LOG(STREAM_MGR, ERROR, "Initalizing metadata cached table failed(result = %d)", result);}else{m_QccMetadatatable_init = true;QCX_LOG(STREAM_MGR, DEBUG, "Initalizing metadata cached table successed");}}}}/*Create the Lock for Global list of input Ids*/result = OSAL_CriticalSectionCreate(&m_OpenInputIdslock);if (CAMERA_SUCCESS != result){QCX_LOG(STREAM_MGR, ERROR, "OSAL_CriticalSectionCreate failed, result = %d", result);}}CAM_TRACE_LOG(STREAM_MGR, "StreamManager::Initialize : End");return result;
}
/*** @brief*   Get singleton instance of gptp.*/
Gptp* Gptp::GetInstance()
{static Gptp s_GptpSingleton;return &s_GptpSingleton;
}

 Gptp::Init

//获取GPTP_ENABLE_KEY的value

//GPTP_ENABLE_KEY未进行配置不会初始化gptpInit

/*** @brief*   Initialize GPTP.** @return*   Status as defined in CamStatus_e*/
CamStatus_e Gptp::Init(void)
{CamStatus_e result = CAMERA_EFAILED;CamStatus_e resultTemp = CAMERA_EFAILED;//获取GPTP_ENABLE_KEY的valueresultTemp = Config::GetInstance()->GetGptpEnableFromConfig(&mGptpEnable);if(CAMERA_SUCCESS != resultTemp){QCX_LOG(STREAM_MGR, ERROR, "Failed to read GPTP Enable from config. Disabling GPTP");mGptpEnable = GPTP_DISABLED;}//GPTP_ENABLE_KEY未进行配置不会初始化gptpInitif(GPTP_ENABLED == mGptpEnable){bool state;state = gptpInit();if (true != state){QCX_LOG(STREAM_MGR, ERROR, "gptp init failed");}else{QCX_LOG(STREAM_MGR, DEBUG, "gptp init success");result = CAMERA_SUCCESS;}}return result;
}

/*** @brief* Read GPTP enable value from config.** @param gptpEn [out]*   pointer to the gptp enable flag.** @return* Status as defined in CamStatus_e.*/
CamStatus_e Config::GetGptpEnableFromConfig(uint32_t *pGptpEn)
{CamStatus_e rc = CAMERA_EFAILED;rc = GetValFromConfigOverrideSetting(GPTP_ENABLE_KEY, pGptpEn);if (CAMERA_SUCCESS != rc){QCX_LOG(STREAM_MGR, HIGH, "GPTP Enable config read failed");}else{QCX_LOG(STREAM_MGR, LOW, "Config read success: GptpEn = %u", *pGptpEn);}return rc;
}

 

 ** @param key [in]*   key of the config.** @param value [out]*  pointer to value of the config.** @return* Status as defined in CamStatus_e.*/
CamStatus_e Config::GetValFromConfigOverrideSetting(uint32_t key, uint32_t *pValue)
{CamStatus_e rc = CAMERA_ENOTFOUND;const CameraConfigInfo_t* pCamConfig = nullptr;pCamConfig = PLM_GetCameraConfig();if (nullptr == pCamConfig){QCX_LOG(STREAM_MGR, ERROR, "Failed to query cameraconfig");}else{/* Search the config for request queue depth value. */for (uint32_t idx = 0; idx < CAM_CFG_MAX_NUM_SETTINGS_OVERRIDES; idx++){if (key == pCamConfig->settingsOverrides[idx].key){*pValue = pCamConfig->settingsOverrides[idx].value;rc = CAMERA_SUCCESS;break;}}}return rc;
}

 

/**************************************************************************************************
@briefGet camera config@returnError const pointer to CameraConfigInfo_t
**************************************************************************************************/
const CameraConfigInfo_t* PLM_GetCameraConfig(void)
{if (TRUE == g_PlatformCtxt.bInitialized){return g_PlatformCtxt.pCameraConfigInfo;}return NULL;
}
static int CameraConfigXMLParseFile(CameraConfigInfo_t *boardInfo)
{int rc = 0;xmlDocPtr pXmlDoc = NULL;xmlNodePtr pCur = NULL;const char* filename = CAMERA_CONFIG_XML_FILE;uint32_t settingsOverrideIdx = 0;CAM_MSG(HIGH, "CameraConfig xml file name:%s", filename);if(access(filename, F_OK)){CAM_MSG(HIGH, "CameraConfig file not available. Will use defaults");rc = -1;}if (!rc){pXmlDoc = xmlParseFile(filename);if (pXmlDoc == NULL){CAM_MSG(ERROR, "CameraConfig file not parsed successfully");rc = -1;}}if (!rc){pCur = xmlDocGetRootElement(pXmlDoc);if (pCur == NULL){CAM_MSG(ERROR, "Empty CameraConfig file");xmlFreeDoc(pXmlDoc);rc = -1;}}if (!rc){if (xmlStrcmp(pCur->name, (const xmlChar *) "CameraConfig")){CAM_MSG(ERROR, "Wrong CameraConfig file format, root node != CameraConfig");xmlFreeDoc(pXmlDoc);rc = -1;}else{pCur = pCur->xmlChildrenNode;}}//Parse the filewhile(pCur != NULL && !rc){if (!(xmlStrcmp(pCur->name, (const xmlChar *) "board"))){XML_GET_INT_ATTR(boardInfo->socId, pCur, "socId", 1, uint32_t);XML_GET_STRING_ATTR(boardInfo->boardName, pCur, "name", 1);xmlNodePtr pChild = pCur->xmlChildrenNode;while(pChild != NULL && !rc){if(!(xmlStrcmp(pChild->name, (const xmlChar *) "i2cDevs"))){//配置camera sensorlib i2c设备的个数XML_GET_INT_ATTR(boardInfo->numI2cDevices, pChild, "numI2cDevices", 1, uint32_t);if(CAM_CFG_MAX_NUM_I2C_DEVICES <= boardInfo->numI2cDevices){CAM_MSG(ERROR, "Number of I2cDevices exceeds max %d", CAM_CFG_MAX_NUM_I2C_DEVICES);rc = -1;break;}rc = CameraConfigXMLParseI2CDevs(pChild, boardInfo);}else if(!(xmlStrcmp(pChild->name, (const xmlChar *) "cameraLibs"))){XML_GET_INT_ATTR(boardInfo->numCameraLibs, pChild, "numCameraLibs", 1, uint32_t);if(CAM_CFG_MAX_NUM_SENSOR_LIBS <= boardInfo->numCameraLibs){CAM_MSG(ERROR, "Number of CameraLibs exceeds max %d", CAM_CFG_MAX_NUM_SENSOR_LIBS);rc = -1;break;}rc = CameraConfigXMLParseSensorLibs(pChild, boardInfo);}else if(!(xmlStrcmp(pChild->name, (const xmlChar *) "settingsOverrides"))){uint32_t key = 0;uint32_t value = 0;XML_GET_INT_ATTR(key, pChild, "key", 1, uint32_t);XML_GET_INT_ATTR(value, pChild, "value", 1, uint32_t);if (CAM_CFG_MAX_NUM_SETTINGS_OVERRIDES <= settingsOverrideIdx){CAM_MSG(ERROR, "Number of engine settings exceeds max %d", CAM_CFG_MAX_NUM_SETTINGS_OVERRIDES);rc = -1;break;}//获取xml中配置的settingsOverrridesboardInfo->settingsOverrides[settingsOverrideIdx].key = key;boardInfo->settingsOverrides[settingsOverrideIdx].value = value;settingsOverrideIdx++;}pChild = pChild->next;}}else if(!(xmlStrcmp(pCur->name, (const xmlChar *) "inputMapping"))){XML_GET_INT_ATTR(boardInfo->numInputs, pCur, "numInputs", 1, uint32_t);//获取xml的input信息rc = CameraConfigXMLParseInputMapping(pCur, boardInfo);}pCur = pCur->next;}xmlFreeDoc(pXmlDoc);return rc;
}
static int CameraConfigXMLParseInputMapping(xmlNodePtr pParent, CameraConfigInfo_t *boardInfo)
{int rc = 0;xmlNodePtr pCur = pParent->xmlChildrenNode;uint32_t srcIdx = 0;while (pCur != NULL && !rc){if (!(xmlStrcmp(pCur->name, (const xmlChar *) "inputMap"))){xmlNodePtr pChild;if(CAM_CFG_MAX_NUM_INPUT_MAPPING <= srcIdx){CAM_MSG(ERROR, "Number of input mapping exceeds max %d", CAM_CFG_MAX_NUM_INPUT_MAPPING);rc = -1;break;}XML_GET_INT_ATTR(boardInfo->inputs[srcIdx].qcarcamId, pCur, "qcarcamId", 1, uint32_t);XML_GET_STRING_ATTR(boardInfo->inputs[srcIdx].name, pCur, "name", 1);pChild = pCur->xmlChildrenNode;pChild = pChild->next;if(!(xmlStrcmp(pChild->name, (const xmlChar *) "inputSrc"))){XML_GET_INT_ATTR(boardInfo->inputs[srcIdx].sensorLibId, pChild, "sensorLibId", 1, uint32_t);XML_GET_INT_ATTR(boardInfo->inputs[srcIdx].devId, pChild, "devId", 1, uint32_t);XML_GET_INT_ATTR(boardInfo->inputs[srcIdx].subdevId, pChild, "subdevId", 1, uint32_t);}srcIdx++;}pCur = pCur->next;}return rc;
}

 Config::Init

/** Initialise config Class.** @return* Status as defined in CamStatus_e.*/
void Config::Init()
{/* TODO: Need to cleanup and implement proper init method.*       Need to initialise all the configs in the init method,*       which will be consumed by clients using getter methods.*       (Now error injection configs are only initalised here.**/if(CAMERA_SUCCESS != InitErrInjConfig()){QCX_LOG(STREAM_MGR, HIGH, "Error Injection Configs not found");}
}

 

* @brief* Read Error Injection configs from global configs and* update corresponding config class memeber.** @return* Status as defined in CamStatus_e.*/
CamStatus_e Config::InitErrInjConfig()
{CamStatus_e rc = CAMERA_ENOTFOUND;uint32_t errInj1 = 0;uint32_t errInj2 = 0;uint64_t config = 0;/* Read and update the error injection configs */m_errInjConfig.errInjEn = false;rc = GetValFromConfigOverrideSetting(ERR_INJ_VAL1_KEY, &errInj1);if (CAMERA_SUCCESS != rc){QCX_LOG(STREAM_MGR, HIGH, "Config not present for ERR_INJ_VAL1_KEY");}else{rc = GetValFromConfigOverrideSetting(ERR_INJ_VAL2_KEY, &errInj2);if (CAMERA_SUCCESS != rc){QCX_LOG(STREAM_MGR, HIGH, "Config not present for ERR_INJ_VAL2_KEY");}else{/* Pack the two 32 bit values to form 64bit value */config = ((uint64_t)errInj2 << 32) | errInj1;QCX_LOG(STREAM_MGR, DEBUG, "Config read success: ErrInj Val2 = %x,"" ErrInj Val1 = %x, config = %lx", errInj2, errInj1, config);/** The 64 bit Config value is divided as* [15:0]  : 16 bits -> Request Id* [31:16] : 16 bits -> Error Source* [47:32] : 16 bits -> Error Code* [59:48] : 12 bits -> Camera Id* [63:60] : 4 bits -> Error Id* */m_errInjConfig.requestId = (config & 0xFFFF);m_errInjConfig.errorSrc = ((config >> 16) & 0xFFFF);m_errInjConfig.errorCode = ((config >> 32) & 0xFFFF);m_errInjConfig.cameraId = ((config >> 48) & 0xFFF);m_errInjConfig.errorId = ((config >> 60) & 0xF);QCX_LOG(STREAM_MGR, DEBUG, " Request id = %x, Error Src = %x,"" Error Code = %x, Camera Id = %d, Error Id = %x",m_errInjConfig.requestId, m_errInjConfig.errorSrc,m_errInjConfig.errorCode, m_errInjConfig.cameraId,m_errInjConfig.errorId);if (ERROR_CAMERA_CODE_INVALID != m_errInjConfig.errorCode){QCX_LOG(STREAM_MGR, DEBUG, "Valid Error Code: Enabling Error injection");m_errInjConfig.errInjEn = true;rc = CAMERA_SUCCESS;}}}return rc;
}

 SensorManager::Init 

//注册m_SensorPlatformApi函数操作接口

//获取xml中的camera 对应的解串器的i2c num配置

//创建 pDetectHndlr->detectQ

//创建pDetectHndlr->signal 信号量

//创建SensorManager::DetectHandlerThread 处理detectQ中的数据

//初始化pSensorLib 获取boardInfo->cameraLib中的SensorLibConfig

//加载sensorlib

//匹配解串器型号配置 解串器地址mode

//配置devIdx解串器信息

//配置解串器的index rang 0-3

//配置解串器numdevices id

//配置input 信息

/*** @brief Initialize Sensor Manager* @return #CamStatus_e*/
CamStatus_e SensorManager::Init()
{CamStatus_e result{CAMERA_SUCCESS};m_pCameraConfigInfo = PLM_GetCameraConfig();if (nullptr == m_pCameraConfigInfo){QCX_LOG(SENSOR_MGR, ERROR, "Failed to query cameraconfig");return result;}//注册m_SensorPlatformApi函数操作接口m_SensorPlatformApi.I2CRead = &I2CRead;m_SensorPlatformApi.I2CWrite = &I2CWrite;m_SensorPlatformApi.I2CTransact = &I2CTransact;m_SensorPlatformApi.I2CWriteSync = &I2CWriteSync;m_SensorPlatformApi.ExecuteGpioAndPowerSequence = &ExecuteGpioAndPowerSequence;m_SensorPlatformApi.GPIOSetValue = &GPIOSetValue;m_SensorPlatformApi.GPIOGetValue = &GPIOGetValue;m_SensorPlatformApi.SetupGpioInterrupt = &SetupGpioInterrupt;m_SensorPlatformApi.StartCCIFrameSync = &StartCCIFrameSync;m_SensorPlatformApi.StopCCIFrameSync = &StopCCIFrameSync;//获取xml中的camera 对应的解串器的i2c num配置m_numSensorLibs = m_pCameraConfigInfo->numCameraLibs; char thread_name[64];const uint64_t nMaxElementSize = sizeof(QCXInputEventMsgType);m_detectHandlerIsExit = FALSE;result = QCXCameraCreateSignal(&m_detectSignalDone);if (result != CAMERA_SUCCESS){QCX_LOG(SENSOR_MGR, ERROR, "Could not create Signal");}result = OSAL_CriticalSectionCreate(&m_detectMutex);if (result != CAMERA_SUCCESS){QCX_LOG(SENSOR_MGR, ERROR, "Could not create Mutex");}for (int i = 0; i < MAX_DETECT_THREAD_IDX; i++){QCXInputDetectHandlerType* pDetectHndlr = &m_detectHandler[i];//创建 pDetectHndlr->detectQresult = QCXQueueCreate(nMa xElementSize, CAM_CFG_MAX_NUM_SENSOR_LIBS, FALSE, &pDetectHndlr->detectQ);if (result != CAMERA_SUCCESS){QCX_LOG(SENSOR_MGR, ERROR, "Could not create Queue");}//创建pDetectHndlr->signal 信号量result = QCXCameraCreateSignal(&pDetectHndlr->signal);if (CAMERA_SUCCESS != result){QCX_LOG(SENSOR_MGR, ERROR, "Could not create Signal");}UNUSED_VAL(snprintf(thread_name, sizeof(thread_name), "sensormgr_thrd%d", i));if (CAMERA_SUCCESS == result){ //创建SensorManager::DetectHandlerThread 处理detectQ中的数据result = OSAL_ThreadCreate(QCXThreadDefaultPriority, &SensorManager::DetectHandlerThread, pDetectHndlr,DETECT_STACK_SIZE, thread_name, &pDetectHndlr->threadId);if (result != CAMERA_SUCCESS){QCX_LOG(SENSOR_MGR, ERROR, "Could not create Thread");}}}for (uint32_t libIdx = 0U; libIdx < m_numSensorLibs; libIdx++){QcxSensorLib_t* const pSensorLib = &m_sensorLibs[libIdx];//初始化pSensorLib 获取boardInfo->cameraLib中的SensorLibConfigpSensorLib->pSensorLibConfig = &m_pCameraConfigInfo->cameraLib[libIdx];pSensorLib->pSensorPlatform = SensorPlatform::SensorPlatformInit(pSensorLib->pSensorLibConfig);if (nullptr == pSensorLib->pSensorPlatform){QCX_LOG(SENSOR_MGR, ERROR, "Could not load sensorplatform for lib %d",pSensorLib->pSensorLibConfig->sensorLibId);continue;}//加载sensorlibresult = LoadSensorLib(pSensorLib);if (CAMERA_SUCCESS != result){QCX_LOG(SENSOR_MGR, ERROR, "Could not load sensor lib %d",pSensorLib->pSensorLibConfig->sensorLibId);continue;}QCX_LOG(SENSOR_MGR, HIGH, "Open sensor lib %d ...",pSensorLib->pSensorLibConfig->sensorLibId);//匹配解串器型号配置 解串器地址moderesult = OpenSensorLib(pSensorLib);if (CAMERA_SUCCESS != result){ QCX_LOG(SENSOR_MGR, ERROR, "Could not open sensor lib %d",pSensorLib->pSensorLibConfig->sensorLibId);continue;}pSensorLib->m_nInputDevices = pSensorLib->pSensorLibConfig->numDevices;//配置devIdx解串器信息// Search list of sensor device drivers to determine which ones are// actually available for usefor (uint32_t devIdx = 0U; devIdx < pSensorLib->m_nInputDevices; devIdx++){QcxInputDevice_t* const pInputDev = &pSensorLib->m_InputDevices[devIdx];pInputDev->delaySuspendFlag = FALSE;//配置解串器的index rang 0-3pInputDev->sensorlibId = libIdx;//配置解串器numdevices idpInputDev->devId = devIdx;pInputDev->pDeviceConfig = &pSensorLib->pSensorLibConfig->devices[devIdx];}}//配置input 信息for (uint32_t inputmapIdx = 0U; inputmapIdx < m_pCameraConfigInfo->numInputs; inputmapIdx++){QcxInputMapping_t* const pInputMap = &m_InputMappingTable[inputmapIdx];pInputMap->pInfo = &m_pCameraConfigInfo->inputs[inputmapIdx];pInputMap->isAvailable = FALSE;m_nInputMapping++;}// return success to keep going with whatever sensor libraries were detectedreturn CAMERA_SUCCESS;
}
//解析xml 获取boardInfo->cameraLib中的SensorLibConfig
static int CameraConfigXMLParseSensorLibs(xmlNodePtr pParent, CameraConfigInfo_t *boardInfo)
{int rc = 0;uint32_t cameraLibIdx = 0;xmlNodePtr pCur = pParent->xmlChildrenNode;while(pCur != NULL && !rc){if(!(xmlStrcmp(pCur->name, (const xmlChar *) "cameraLib"))){xmlNodePtr pChild;if(cameraLibIdx >= boardInfo->numCameraLibs){CAM_MSG(HIGH, "Number of cameraLibs exceeds max");return rc;}XML_GET_INT_ATTR(boardInfo->cameraLib[cameraLibIdx].sensorLibId, pCur, "sensorLibId", 1, uint32_t);pChild = pCur->xmlChildrenNode;while(pChild != NULL && !rc){if(!(xmlStrcmp(pChild->name, (const xmlChar *) "driverInfo"))){XML_GET_STRING_ATTR(boardInfo->cameraLib[cameraLibIdx].driverInfo.strSensorLibraryName, pChild, "strSensorLibraryName", 1);XML_GET_STRING_ATTR(boardInfo->cameraLib[cameraLibIdx].driverInfo.strSensorLibGetInterfFcn, pChild, "strSensorLibGetInterfFcn", 1);}else if(!(xmlStrcmp(pChild->name, (const xmlChar *) "inputdevs"))){XML_GET_INT_ATTR(boardInfo->cameraLib[cameraLibIdx].numDevices, pChild, "numDevices", 1, uint32_t);uint32_t devId = 0;xmlNodePtr pSubChild = pChild->xmlChildrenNode;while(pSubChild != NULL && !rc){if(devId >= boardInfo->cameraLib[cameraLibIdx].numDevices){CAM_MSG(HIGH, "Number of cameraLibs exceeds max");break;}if(!(xmlStrcmp(pSubChild->name, (const xmlChar *) "inputdev"))){XML_GET_INT_ATTR(boardInfo->cameraLib[cameraLibIdx].devices[devId].deviceId, pSubChild, "deviceId", 1, uint8_t);XML_GET_INT_ATTR(boardInfo->cameraLib[cameraLibIdx].devices[devId].deviceType, pSubChild, "deviceType", 1, uint8_t);XML_GET_INT_ATTR(boardInfo->cameraLib[cameraLibIdx].devices[devId].deviceMode, pSubChild, "deviceMode", 1, uint8_t);XML_GET_INT_ATTR(boardInfo->cameraLib[cameraLibIdx].devices[devId].deviceI2cAddr, pSubChild, "deviceI2cAddr", 1, uint8_t);xmlNodePtr pSSubChild;pSSubChild = pSubChild->xmlChildrenNode;while(pSSubChild != NULL && !rc){if(!(xmlStrcmp(pSSubChild->name, (const xmlChar *) "subdevs"))){XML_GET_INT_ATTR(boardInfo->cameraLib[cameraLibIdx].devices[devId].numSubdevices, pSSubChild, "numSubdevices", 1, uint8_t);uint32_t SubDevIdx = 0;xmlNodePtr pSSubChild1 = pSSubChild->xmlChildrenNode;while(pSSubChild1 != NULL && !rc){if(SubDevIdx >= boardInfo->cameraLib[cameraLibIdx].devices[devId].numSubdevices){CAM_MSG(HIGH, "Number of cameraLibs exceeds max");break;}if(!(xmlStrcmp(pSSubChild1->name, (const xmlChar *) "subdev"))){XML_GET_INT_ATTR(boardInfo->cameraLib[cameraLibIdx].devices[devId].subdevices[SubDevIdx].subdevId, pSSubChild1, "subdevId", 1, uint8_t);XML_GET_INT_ATTR(boardInfo->cameraLib[cameraLibIdx].devices[devId].subdevices[SubDevIdx].type, pSSubChild1, "type", 1, uint8_t);XML_GET_INT_ATTR(boardInfo->cameraLib[cameraLibIdx].devices[devId].subdevices[SubDevIdx].serAlias, pSSubChild1, "serAlias", 1, uint8_t);XML_GET_INT_ATTR(boardInfo->cameraLib[cameraLibIdx].devices[devId].subdevices[SubDevIdx].snsrAlias, pSSubChild1, "snsrAlias", 1, uint8_t);XML_GET_INT_ATTR(boardInfo->cameraLib[cameraLibIdx].devices[devId].subdevices[SubDevIdx].snsrModeId, pSSubChild1, "snsrModeId", 1, uint8_t);XML_GET_INT_ATTR(boardInfo->cameraLib[cameraLibIdx].devices[devId].subdevices[SubDevIdx].fsyncMode, pSSubChild1, "fsyncMode", 1, uint8_t);XML_GET_INT_ATTR(boardInfo->cameraLib[cameraLibIdx].devices[devId].subdevices[SubDevIdx].fsyncFreq, pSSubChild1, "fsyncFreq", 1, uint8_t);XML_GET_INT_ATTR(boardInfo->cameraLib[cameraLibIdx].devices[devId].subdevices[SubDevIdx].colorSpace, pSSubChild1, "colorSpace", 1, uint8_t);SubDevIdx++;}else if(!xmlNodeIsText(pSSubChild1)){CAM_MSG(ERROR, "CameraConfig %s inside %s", pSSubChild1->name, pSSubChild->name);rc = -1;}pSSubChild1 = pSSubChild1->next;}}else if(!(xmlStrcmp(pSSubChild->name, (const xmlChar *) "csiconn"))){XML_GET_INT_ATTR(boardInfo->cameraLib[cameraLibIdx].devices[devId].numCsi, pSSubChild, "numCsi", 1, uint8_t);uint32_t csiIdx = 0;if(SENSORLIB_MAX_NUM_CSI <= boardInfo->cameraLib[cameraLibIdx].devices[devId].numCsi){CAM_MSG(ERROR, "Number of CSI exceeds max %d", SENSORLIB_MAX_NUM_CSI);rc =-1;break;}xmlNodePtr pSSubChild1 = pSSubChild->xmlChildrenNode;while(pSSubChild1 != NULL && !rc){if(csiIdx >= boardInfo->cameraLib[cameraLibIdx].devices[devId].numCsi){CAM_MSG(HIGH, "Number of cameraLibs exceeds max");break;}if(!(xmlStrcmp(pSSubChild1->name, (const xmlChar *) "csiInfo"))){XML_GET_INT_ATTR(boardInfo->cameraLib[cameraLibIdx].devices[devId].csiInfo[csiIdx].csiId, pSSubChild1, "csiId", 1, uint8_t);XML_GET_INT_ATTR(boardInfo->cameraLib[cameraLibIdx].devices[devId].csiInfo[csiIdx].numLanes, pSSubChild1, "numLanes", 1, uint8_t);XML_GET_INT_ATTR(boardInfo->cameraLib[cameraLibIdx].devices[devId].csiInfo[csiIdx].laneAssign, pSSubChild1, "laneAssign", 1, uint16_t);XML_GET_INT_ATTR(boardInfo->cameraLib[cameraLibIdx].devices[devId].csiInfo[csiIdx].ifeMap, pSSubChild1, "ifeMap", 1, uint32_t);XML_GET_INT_ATTR(boardInfo->cameraLib[cameraLibIdx].devices[devId].csiInfo[csiIdx].numIfeMap, pSSubChild1, "numIfeMap", 1, uint8_t);XML_GET_INT_ATTR(boardInfo->cameraLib[cameraLibIdx].devices[devId].csiInfo[csiIdx].forceHSmode, pSSubChild1, "forceHSmode", 1, uint8_t);csiIdx++;}else if(!xmlNodeIsText(pSSubChild1)){CAM_MSG(ERROR, "CameraConfig %s inside %s", pSSubChild1->name, pSSubChild->name);rc = -1;}pSSubChild1 = pSSubChild1->next;}}else if(!(xmlStrcmp(pSSubChild->name, (const xmlChar *) "i2cinfo"))){XML_GET_INT_ATTR(boardInfo->cameraLib[cameraLibIdx].devices[devId].numI2cPorts, pSSubChild, "numI2cPorts", 1, uint8_t);uint32_t I2cIdx = 0;if(SENSORLIB_MAX_NUM_I2C_PER_DEVICE <= boardInfo->cameraLib[cameraLibIdx].devices[devId].numI2cPorts){CAM_MSG(ERROR, "Number of I2c ports exceeds max %d", SENSORLIB_MAX_NUM_I2C_PER_DEVICE);rc =-1;break;}xmlNodePtr pSSubChild1 = pSSubChild->xmlChildrenNode;while(pSSubChild1 != NULL && !rc){if(I2cIdx >= boardInfo->cameraLib[cameraLibIdx].devices[devId].numI2cPorts){CAM_MSG(HIGH, "Number of cameraLibs exceeds max");break;}if(!(xmlStrcmp(pSSubChild1->name, (const xmlChar *) "i2cPort"))){boardInfo->cameraLib[cameraLibIdx].devices[devId].i2cPort[I2cIdx].i2ctype = CameraConfigXMLParseI2cType(pSSubChild1);XML_GET_INT_ATTR(boardInfo->cameraLib[cameraLibIdx].devices[devId].i2cPort[I2cIdx].deviceId, pSSubChild1, "deviceId", 1, uint32_t);XML_GET_INT_ATTR(boardInfo->cameraLib[cameraLibIdx].devices[devId].i2cPort[I2cIdx].portId, pSSubChild1, "portId", 1, uint32_t);I2cIdx++;}else if(!xmlNodeIsText(pSSubChild1)){CAM_MSG(ERROR, "CameraConfig %s inside %s", pSSubChild1->name, pSSubChild->name);rc = -1;}pSSubChild1 = pSSubChild1->next;}}else if(!(xmlStrcmp(pSSubChild->name, (const xmlChar *) "gpioinfo"))){XML_GET_INT_ATTR(boardInfo->cameraLib[cameraLibIdx].devices[devId].numGpio, pSSubChild, "numGpio", 1, uint8_t);uint32_t gpioIdx = 0;if(SENSORLIB_MAX_NUM_GPIO_PER_DEVICE <= boardInfo->cameraLib[cameraLibIdx].devices[devId].numGpio){CAM_MSG(ERROR, "Number of gpio exceeds max %d", SENSORLIB_MAX_NUM_GPIO_PER_DEVICE);rc =-1;break;}xmlNodePtr pSSubChild1 = pSSubChild->xmlChildrenNode;while(pSSubChild1 != NULL && !rc){if(gpioIdx >= boardInfo->cameraLib[cameraLibIdx].devices[devId].numGpio){CAM_MSG(HIGH, "Number of cameraLibs exceeds max");break;}if(!(xmlStrcmp(pSSubChild1->name, (const xmlChar *) "gpio"))){boardInfo->cameraLib[cameraLibIdx].devices[devId].gpioConfig[gpioIdx].gpioType = CameraConfigXMLParseGpioSignalType(pSSubChild1);if (CAMERA_GPIO_MAX <= boardInfo->cameraLib[cameraLibIdx].devices[devId].gpioConfig[gpioIdx].gpioType){CAM_MSG(ERROR, "Invalid GPIO type, exceeds %d", CAMERA_GPIO_MAX);rc = -1;break;}XML_GET_INT_ATTR(boardInfo->cameraLib[cameraLibIdx].devices[devId].gpioConfig[gpioIdx].num, pSSubChild1, "num", 1, uint32_t);XML_GET_INT_ATTR(boardInfo->cameraLib[cameraLibIdx].devices[devId].gpioConfig[gpioIdx].config, pSSubChild1, "config", 1, uint32_t);XML_GET_INT_ATTR(boardInfo->cameraLib[cameraLibIdx].devices[devId].gpioConfig[gpioIdx].configMask, pSSubChild1, "configMask", 1, uint32_t);gpioIdx++;}else if(!xmlNodeIsText(pSSubChild1)){CAM_MSG(ERROR, "CameraConfig %s inside %s", pSSubChild1->name, pSSubChild->name);rc = -1;}pSSubChild1 = pSSubChild1->next;}}else if(!(xmlStrcmp(pSSubChild->name, (const xmlChar *) "intrinfo"))){XML_GET_INT_ATTR(boardInfo->cameraLib[cameraLibIdx].devices[devId].numGpioIntr, pSSubChild, "numGpioIntr", 1, uint8_t);uint32_t gpioIntrIdx = 0;if(SENSORLIB_MAX_NUM_INTR_PER_DEVICE <= boardInfo->cameraLib[cameraLibIdx].devices[devId].numGpioIntr){CAM_MSG(ERROR, "Number of gpio intr exceeds max %d", SENSORLIB_MAX_NUM_INTR_PER_DEVICE);rc =-1;break;}xmlNodePtr pSSubChild1 = pSSubChild->xmlChildrenNode;while(pSSubChild1 != NULL && !rc){if(gpioIntrIdx >= boardInfo->cameraLib[cameraLibIdx].devices[devId].numGpioIntr){CAM_MSG(HIGH, "Number of cameraLibs exceeds max");break;}if(!(xmlStrcmp(pSSubChild1->name, (const xmlChar *) "intr"))){boardInfo->cameraLib[cameraLibIdx].devices[devId].gpioIntrConfig[gpioIntrIdx].intrType = CameraConfigXMLParseIntrType(pSSubChild1);if(CAMERA_GPIO_INTR_MAX <= boardInfo->cameraLib[cameraLibIdx].devices[devId].gpioIntrConfig[gpioIntrIdx].intrType){CAM_MSG(ERROR, "Invalid intr type, exceeds %d", CAMERA_GPIO_INTR_MAX);rc = -1;break;}XML_GET_INT_ATTR(boardInfo->cameraLib[cameraLibIdx].devices[devId].gpioIntrConfig[gpioIntrIdx].gpioPin, pSSubChild1, "gpioPin", 1, uint32_t);boardInfo->cameraLib[cameraLibIdx].devices[devId].gpioIntrConfig[gpioIntrIdx].triggerType = CameraConfigXMLParsetriggerType(pSSubChild1);boardInfo->cameraLib[cameraLibIdx].devices[devId].gpioIntrConfig[gpioIntrIdx].intrMode = CameraConfigXMLParseintrMode(pSSubChild1);gpioIntrIdx++;}else if(!xmlNodeIsText(pSSubChild1)){CAM_MSG(ERROR, "CameraConfig %s inside %s", pSSubChild1->name, pSSubChild->name);rc = -1;}pSSubChild1 = pSSubChild1->next;}}else if(!xmlNodeIsText(pSSubChild)){CAM_MSG(ERROR, "CameraConfig %s inside %s", pSSubChild->name, pSubChild->name);rc = -1;}pSSubChild = pSSubChild->next;}devId++;}else if(!xmlNodeIsText(pSubChild)){CAM_MSG(ERROR, "CameraConfig %s inside %s", pSubChild->name, pChild->name);rc = -1;}pSubChild = pSubChild->next;}}else if(!xmlNodeIsText(pChild)){CAM_MSG(ERROR, "CameraConfig %s inside %s", pChild->name, pCur->name);rc = -1;}pChild = pChild->next;}cameraLibIdx++;}else if(!xmlNodeIsText(pCur)){CAM_MSG(ERROR, "CameraConfig %s inside %s", pCur->name, pParent->name);rc = -1;}pCur = pCur->next;}return rc;
}

 SensorPlatform::SensorPlatformInit

/* ---------------------------------------------------------------------------*    FUNCTION        SensorPlatformInit*    DESCRIPTION     Initialize sensor platform with dev id*    DEPENDENCIES    None*    PARAMETERS*    RETURN VALUE    sensor platform ctxt ptr*    SIDE EFFECTS    None* ------------------------------------------------------------------------ */
SensorPlatform* SensorPlatform::SensorPlatformInit(const CameraConfigSensorLib_t* pDeviceConfig)
{SensorPlatformCommon* pCtxt = new SensorPlatformCommon(pDeviceConfig);if (pCtxt){CamStatus_e rc = pCtxt->Init();if (CAMERA_SUCCESS != rc){delete pCtxt;pCtxt = NULL;}}return pCtxt;
}
/* --------------------------------------------------------------------------
** Internal Functions
** ----------------------------------------------------------------------- */SensorPlatformCommon::SensorPlatformCommon(const CameraConfigSensorLib_t* pSensorLibConfig)
{m_pConfig = pSensorLibConfig;m_pHndl = NULL;m_sensorLibId = m_pConfig->sensorLibId;
#if 0m_i2cMutex = NULL;memset(m_aInterrupts, 0x0, sizeof(m_aInterrupts));
#endif
}

 //初始化SensorLibDeviceConfig_t中解串器GPIO的配置信息

/*** @brief Initialize SensorPlatform**/
CamStatus_e SensorPlatformCommon::Init()
{CamStatus_e rc = CAMERA_SUCCESS;QCX_LOG(SENSOR_MGR, HIGH, "SensorPlatform init camera id %d", m_sensorLibId);for (uint32_t devIdx = 0; devIdx < m_pConfig->numDevices && CAMERA_SUCCESS == rc; devIdx++){  //初始化SensorLibDeviceConfig_t中解串器GPIO的配置信息const SensorLibDeviceConfig_t* pDevice = &m_pConfig->devices[devIdx];for (uint32_t i = 0; i < pDevice->numGpio && CAMERA_SUCCESS == rc; i++){rc = PLM_GpioConfig(pDevice->gpioConfig[i].num, pDevice->gpioConfig[i].config, pDevice->gpioConfig[i].configMask);if (CAMERA_SUCCESS != rc){QCX_LOG(SENSOR_MGR, ERROR, "Failed to config GPIO %d to 0x%x",pDevice->gpioConfig[i].num, pDevice->gpioConfig[i].config);}else{QCX_LOG(SENSOR_MGR, HIGH, "Config GPIO %d to 0x%x",pDevice->gpioConfig[i].num, pDevice->gpioConfig[i].config);}}}return rc;
}

SensorManager::LoadSensorLib

//加载sensorlib驱动

//调用sensorlib 注册的SensorLibraryAPI_t sg_sensorLibApi 回调函数

/*** @brief Loads sensor library and its interface** @param pSensorLib   pointer to sensor lib struct** @return #CamStatus_e*/
CamStatus_e SensorManager::LoadSensorLib(QcxSensorLib_t* pSensorLib)
{CamStatus_e result = CAMERA_SUCCESS;/* Load sensor library, dlsym getinterface and acquire it */
#ifdef CAM_CFG_BUILD_STATIC_DEVICESpSensorLib->pfnGetSensorLibInterface = pSensorLib->pSensorLibConfig->driverInfo.pfnSensorLibGetInterf;pSensorLib->hLibrary = nullptr;
#else//加载sensorlib驱动if (nullptr == (pSensorLib->hLibrary = dlopen(pSensorLib->pSensorLibConfig->driverInfo.strSensorLibraryName, RTLD_NOW|RTLD_GLOBAL))){QCX_LOG(SENSOR_MGR, ERROR, "'%s' loading failed '%s'",pSensorLib->pSensorLibConfig->driverInfo.strSensorLibraryName,dlerror());result = CAMERA_EUNABLETOLOAD;}else if (NULL == (pSensorLib->pfnGetSensorLibInterface = reinterpret_cast<SensorLibGetInterface>(dlsym(pSensorLib->hLibrary, pSensorLib->pSensorLibConfig->driverInfo.strSensorLibGetInterfFcn)))){QCX_LOG(SENSOR_MGR, ERROR, "'%s' interface not found '%s'",pSensorLib->pSensorLibConfig->driverInfo.strSensorLibraryName,dlerror());result = CAMERA_EUNABLETOLOAD;}else{//CAMERA_SUCCESS case}
#endifif (CAMERA_SUCCESS == result){   //调用sensorlib 注册的SensorLibraryAPI_t sg_sensorLibApi 回调函数if (nullptr == (pSensorLib->pInterface = pSensorLib->pfnGetSensorLibInterface())){QCX_LOG(SENSOR_MGR, ERROR, "'%s' bad init interface",pSensorLib->pSensorLibConfig->driverInfo.strSensorLibraryName);result = CAMERA_EUNABLETOLOAD;}else if ((pSensorLib->pInterface->size != sizeof(SensorLibraryAPI_t))         ||(pSensorLib->pInterface->majorVersion != SENSOR_LIB_VERSION_MAJOR)  ||(pSensorLib->pInterface->minorVersion != SENSOR_LIB_VERSION_MINOR)  ||(nullptr == pSensorLib->pInterface->Open)                  ||(nullptr == pSensorLib->pInterface->Close)                 ||(nullptr == pSensorLib->pInterface->Ioctl)                 ||(nullptr == pSensorLib->pInterface->RegisterCallback)){QCX_LOG(SENSOR_MGR, ERROR, "'%s' bad interface",pSensorLib->pSensorLibConfig->driverInfo.strSensorLibraryName);QCX_LOG(SENSOR_MGR, ERROR, "%d %d %d %p %p %p %p",pSensorLib->pInterface->size,pSensorLib->pInterface->majorVersion,pSensorLib->pInterface->minorVersion,pSensorLib->pInterface->Open,pSensorLib->pInterface->Close,pSensorLib->pInterface->Ioctl,pSensorLib->pInterface->RegisterCallback);result = CAMERA_EUNABLETOLOAD;}else{//CAMERA_SUCCESS case}}return result;
}

 SensorManager::OpenSensorLib

//调用解串器open函数接口进行初始化

//发送对应的event信号触发SensorManager::DetectHandlerThread 进行detect 操作

/*** @brief opens instance of sensor library and registers callback** @param pSensorLib   pointer to sensor lib struct** @return #CamStatus_e*/
CamStatus_e SensorManager::OpenSensorLib(QcxSensorLib_t* const pSensorLib)
{CamStatus_e result = CAMERA_SUCCESS;SensorLibOpenParams_t openParam = {};openParam.sensorLibId = pSensorLib->pSensorLibConfig->sensorLibId;openParam.pPlatformFunc = &m_SensorPlatformApi;openParam.numDevices = pSensorLib->pSensorLibConfig->numDevices;openParam.pDevConfig = pSensorLib->pSensorLibConfig->devices;//调用解串器open函数接口进行初始化pSensorLib->hSensorLib = pSensorLib->pInterface->Open(&openParam);if (nullptr == pSensorLib->hSensorLib){QCX_LOG(SENSOR_MGR, ERROR, "Failed to open instance of sensorlibId %d", openParam.sensorLibId);result = CAMERA_EFAILED;}else{//register sensor lib handlepSensorLib->pSensorPlatform->SetSensorLibHandle(pSensorLib->hSensorLib);SensorRet_e ret = pSensorLib->pInterface->RegisterCallback(pSensorLib->hSensorLib, SensorLibEventCallback, this);if (SENSOR_RET_SUCCESS != ret){QCX_LOG(SENSOR_MGR, ERROR, "Failed to register callback of sensorlibId %d %d", openParam.sensorLibId, ret);result = CAMERA_EFAILED;pSensorLib->pInterface->Close(pSensorLib->hSensorLib);pSensorLib->hSensorLib = nullptr;}}return result;
}

 SensorManager::DetectAll

/*** @brief Detect all sensorlib devices and subdevices*** @return #CamStatus_e*/
CamStatus_e SensorManager::DetectAll(void)
{QCXInputEventMsgType sDetect[m_numSensorLibs] = {};QCX_LOG(SENSOR_MGR, WARN, "DetectAll %d", m_numSensorLibs);for (uint32_t sensorlibIdx = 0U; sensorlibIdx < m_numSensorLibs; sensorlibIdx++){sDetect[sensorlibIdx].eventId = INPUT_EVENT_DETECT;sDetect[sensorlibIdx].devIdx = sensorlibIdx;QCX_LOG(SENSOR_MGR, LOW, "threadID=%d", m_sensorLibs[sensorlibIdx].pSensorLibConfig->detectThrdId);uint32_t const detectThrdIdx = m_sensorLibs[sensorlibIdx].pSensorLibConfig->detectThrdId % MAX_DETECT_THREAD_IDX;//发送对应的event信号触发SensorManager::DetectHandlerThread 进行detect 操作QueueDetectEvent(&m_detectHandler[detectThrdIdx], &sDetect[sensorlibIdx]);}QCXCameraWaitOnSignal(m_detectSignalDone, CAM_SIGNAL_WAIT_NO_TIMEOUT);return CAMERA_SUCCESS;
}

 

CamStatus_e SensorManager::QueueDetectEvent(QCXInputDetectHandlerType* const pDetectHndlr, QCXInputEventMsgType* const pMsg)
{CamStatus_e res = CAMERA_SUCCESS;res = QCXQueuePush(pDetectHndlr->detectQ, static_cast<void *>(pMsg), static_cast<uint64_t>(sizeof(pMsg)));if (CAMERA_SUCCESS == res){res = QCXCameraSetSignal(pDetectHndlr->signal);}else{QCX_LOG(SENSOR_MGR, ERROR, "failed to push to Queue");}return res;
}

 SensorManager::DetectHandlerThread

/*** @brief Detect Handler Thread** @param pDetectHndlr  QCXInputDetectHandlerType** @return #CamStatus_e*/
int SensorManager::DetectHandlerThread(void* const pArg)
{QCXInputDetectHandlerType* const pDetectHndlr = (QCXInputDetectHandlerType*)pArg;SensorManager* const pCtxt = GetInstance();if (pDetectHndlr){while(!pCtxt->m_detectHandlerIsExit){QCX_LOG(SENSOR_MGR, LOW, "AWAKE THREAD");pCtxt->ProcessDetectEvent(pDetectHndlr);QCX_LOG(SENSOR_MGR, LOW, "WAIT");QCXCameraWaitOnSignal(pDetectHndlr->signal, CAM_SIGNAL_WAIT_NO_TIMEOUT);}QCX_LOG(SENSOR_MGR, WARN, "THREAD DONE");}return 0;
}

 SensorManager::ProcessDetectEvent

/*** @brief Process the Event for each thread** @param pDetectHndlr  QCXInputDetectHandlerType** @return #CamStatus_e*/
CamStatus_e SensorManager::ProcessDetectEvent(QCXInputDetectHandlerType* const pDetectHndlr)
{QCXInputEventMsgType msg= {};uint64_t size;CamStatus_e ret = CAMERA_SUCCESS;ret = QCXQueuePop(pDetectHndlr->detectQ, &msg, &size);if (size == 0 || sizeof(msg) != size || ret != CAMERA_SUCCESS){QCX_LOG(SENSOR_MGR, LOW, "Empty Queue");}if (INPUT_EVENT_DETECT == msg.eventId){ret = SensorManager::GetInstance()->DetectInput(msg.devIdx);if (ret != CAMERA_SUCCESS){QCX_LOG(SENSOR_MGR, WARN, "Detect Fail on %d ", msg.devIdx);}}return ret;
}

 //使用ioctl 对sensor 进行上电 MAX96712Ioctl

/*** @brief Detects specific sensor lib devices and subdevices* @param sensorlibIdx Sensor Library Index** @return #CamStatus_e*/
CamStatus_e SensorManager::DetectInput(uint32_t sensorlibIdx)
{CamStatus_e result = CAMERA_SUCCESS;QcxSensorLib_t* const pSensorLib = &m_sensorLibs[sensorlibIdx];SensorRet_e ret = SENSOR_RET_SUCCESS;QCX_LOG(SENSOR_MGR, HIGH, "Detect sensorlibIdx %d", sensorlibIdx);if (nullptr == pSensorLib->pInterface){QCX_LOG(SENSOR_MGR, ERROR, "No interface for sensorlibIdx %d", sensorlibIdx);DetectIncrement();return CAMERA_ENOTFOUND;}SensorLibPowerCtrl_t powerCtrl = {};//配置power cmdpowerCtrl.cmd = SENSORLIB_PWRCMD_POWER_ON;//使用ioctl 对sensor 进行上电 MAX96712Ioctlret = pSensorLib->pInterface->Ioctl(pSensorLib->hSensorLib,SENSORLIB_CMD_POWER_CTRL,&powerCtrl, sizeof(powerCtrl), nullptr, 0);if (SENSOR_RET_SUCCESS != ret){QCX_LOG(SENSOR_MGR, ERROR, "Failed to power on input device %d rc=%d", sensorlibIdx, ret);result = CAMERA_EFAILED;}else{pSensorLib->m_InputDevices[0].state = QCX_INPUT_STATE_ON;}if (CAMERA_SUCCESS == result){QCX_KPI_LOG("QCXSERVER Deserailiser Detect Start (%d)", sensorlibIdx);//max96712_sensor_detect_device & max96712_sensor_detect_device_channels & max96712_sensor_init_settingret = pSensorLib->pInterface->Ioctl(pSensorLib->hSensorLib,SENSORLIB_CMD_DETECT,nullptr, 0,nullptr, 0);QCX_KPI_LOG("QCXSERVER Deserailiser Detect End (%d)", sensorlibIdx);if (SENSOR_RET_SUCCESS == ret){pSensorLib->m_InputDevices[0].state = QCX_INPUT_STATE_DETECTED;}else{QCX_LOG(SENSOR_MGR, ERROR, "Failed to detect sensorlibId %d", pSensorLib->pSensorLibConfig->sensorLibId);result = CAMERA_EFAILED;}}if (CAMERA_SUCCESS == result){SensorLibEnumSubDevices_t* const pEnumSubdevices = &pSensorLib->m_InputDevices[0].enumSubdevices;pEnumSubdevices->devId = 0U;//max96712_enum_subdevicesret = pSensorLib->pInterface->Ioctl(pSensorLib->hSensorLib,SENSORLIB_CMD_ENUM_SUBDEVICES,pEnumSubdevices, sizeof(*pEnumSubdevices),pEnumSubdevices, sizeof(*pEnumSubdevices));if (SENSOR_RET_SUCCESS == ret){QCX_LOG(SENSOR_MGR, WARN, "Detected sensor lib %d num subdevs %d",pSensorLib->pSensorLibConfig->sensorLibId, pEnumSubdevices->numSubDevices);for (uint32_t subdevIdx = 0U; subdevIdx < pEnumSubdevices->numSubDevices; subdevIdx++){SensorLibSubDevice_t* pSubDev = &pEnumSubdevices->subDevices[subdevIdx];QCX_LOG(SENSOR_MGR, WARN, "%d %d %d %d",pSensorLib->pSensorLibConfig->sensorLibId, pSubDev->devId, pSubDev->subdevId, pSubDev->state);for (uint32_t idx = 0U; idx < m_nInputMapping; idx++){QcxInputMapping_t* const pInputMap = &m_InputMappingTable[idx];if ((pSensorLib->pSensorLibConfig->sensorLibId == pInputMap->pInfo->sensorLibId) &&(pSubDev->devId == pInputMap->pInfo->devId) &&(pSubDev->subdevId == pInputMap->pInfo->subdevId)){QCX_LOG(SENSOR_MGR, WARN, "Input %u %s available", pInputMap->pInfo->qcarcamId, pInputMap->pInfo->name);pInputMap->sensorlibIdx  = sensorlibIdx;pInputMap->isAvailable   = TRUE;}}}}else{QCX_LOG(SENSOR_MGR, ERROR, "Failed to enumerate subdevices sensorlibId %d", pSensorLib->pSensorLibConfig->sensorLibId);result = CAMERA_EFAILED;}}DetectIncrement();return result;
}

相关文章:

SM8650 qcxserver.c STRM_Initialize

STRM_Initialize streammanager 初始化流程 目录 STRM_Initialize Gptp::Init Config::Init SensorManager::Init SensorPlatform::SensorPlatformInit SensorManager::LoadSensorLib SensorManager::OpenSensorLib SensorManager::DetectAll SensorManager::DetectHandlerT…...

适配器模式-java实现

意图 复用已经存在的接口&#xff0c;与所需接口不一致的类。即将一个类&#xff08;通常是旧系统中的功能类&#xff09;&#xff0c;通过适配器转化成另一个接口的实现。&#xff08;简单来说&#xff0c;就是复用旧系统的功能&#xff0c;去实现新的接口&#xff09; 我们举…...

【elasticSearch系】3.完整搭建详尽版elk

话不多说,我们先看下经典的elk 是由哪些组件搭建组合起来的 elasticsearch和kibana搭建 可以查看之前我们搭建elasticsearch和kibana 的这篇文章 logstash搭建 为了和之前我们搭建elasticsearch和kibana版本保持一致,这里我们还是选择7.17.3 下载地址 点击下载,这里为了…...

代码随想录day04

24. 两两交换链表中的节点 ● 力扣题目链接 ● 给定一个链表&#xff0c;两两交换其中相邻的节点&#xff0c;并返回交换后的链表。 ● 你不能只是单纯的改变节点内部的值&#xff0c;而是需要实际的进行节点交换。 思路 ● 使用迭代的方法&#xff0c;分析交换逻辑即可 ○ …...

[Realtek] WPA_SUPPLICANT + WPA_CLI使用指南

开启wpa_supplicant wpa_supplicant –Dnl80211 -iwlan0 -c ./wpa.conf –B 或者 wpa_supplicant -Dwext -iwlan0 -c ./wpa.conf -B 扫描AP wpa_cli -p/var/run/wpa_supplicant scan 查看AP扫描结果 wpa_cli -p/var/run/wpa_supplicant scan_results 连接到热点 OPEN…...

# ⛳ Docker 安装、配置和详细使用教程-Win10专业版

目录 ⛳ Docker 安装、配置和详细使用教程-Win10专业版&#x1f69c; 一、win10 系统配置&#x1f3a8; 二、Docker下载和安装&#x1f3ed; 三、Docker配置&#x1f389; 四、Docker入门使用 ⛳ Docker 安装、配置和详细使用教程-Win10专业版 &#x1f69c; 一、win10 系统配…...

Linux 教程

目录 Linux 教程 内核引导 运行init 运行级别 系统初始化 Linux 系统目录结构 Linux 教程 Lin...

图论——最短路算法

引入&#xff1a; 如上图&#xff0c;已知图G。 问节点1到节点3的最短距离。 可心算而出为d[1,2]d[2,3]112,比d[1,3]要小。 求最短路径算法&#xff1a; 1.Floyd(弗洛伊德) 是一种基于三角形不等式的多源最短路径算法。边权可以为负数 表现为a[i,j]a[j,k]<a[i,k]。 …...

在项目中增加网络加载需要考虑什么?

1、下载器 网络加载的第一步肯定是下载&#xff0c;那么选择一个合适的下载器是十分重要的&#xff0c;这个下载器最好支持什么功能&#xff1f; 多线程下载&#xff08;同时需要服务端支持&#xff0c;下载时可指定range&#xff09; 断点续传 通用性&#xff08;其他位置也…...

阿里云服务器部署RabbitMQ流程

阿里云百科分享使用阿里云服务器部署RabbitMQ流程&#xff0c;RabbitMQ是实现了高级消息队列协议&#xff08;AMQP&#xff09;的开源消息代理软件&#xff0c;用于在分布式系统中存储转发消息&#xff0c;有良好的易用性、扩展性和高可用性。本文介绍如何通过ECS实例部署Rabbi…...

青大数据结构【2014】

一、单选 二、简答 为了解决顺序队列的假溢出问题&#xff0c;提出了循环队列&#xff0c;即把存储队列的表从逻辑上看成一个环 判别队列空和满有三种方法&#xff1a; 1&#xff09;采用计数器判别&#xff0c;空时&#xff0c;计数器为0&#xff1b;满时&#xff0c;计数器…...

Ansible Playbook快速部署一主多从MySQL集群

部署目标&#xff1a; 1、快速部署一套一主两从的mysql集群 2、部署过程中支持交互式定义安装目录及监听端口号 部署清单目录结构&#xff1a; rootmaster:/opt/mysql# tree . . ├── group_vars │ └── all.yml ├── hosts ├── mysql.yml └── roles└── mys…...

27.Netty源码之FastThreadLocal

highlight: arduino-light FastThreadLocal FastThreadLocal 的实现与 ThreadLocal 非常类似&#xff0c;Netty 为 FastThreadLocal 量身打造了 FastThreadLocalThread 和 InternalThreadLocalMap 两个重要的类。下面我们看下这两个类是如何实现的。 FastThreadLocalThread 是对…...

linux下离线安装docker

linux下离线安装docker 一、安装docker Docker 官网离线安装文档 https://docs.docker.com/engine/install/binaries/ 整理步骤如下&#xff1a; 官网下载 docker 安装包&#xff0c;地址为 https://download.docker.com/linux/static/stable/&#xff0c;如果是x86就选择x…...

SQL server 异地备份数据库

异地备份数据库 1.备份服务器中设置共享文件夹 2.源服务器数据库中添加异地备份代理作业 EXEC sp_configure show advanced options, 1;RECONFIGURE; EXEC sp_configure xp_cmdshell, 1;RECONFIGURE; declare machine nvarchar(50) 192.168.11.10 --服务器IP declare pa…...

高并发系统设计要点

在系统设计时&#xff0c;如果能预先看到一些问题&#xff0c;并在设计层面提前解决&#xff0c;就会给后期的开发带来很大的便捷。相反&#xff0c;有缺陷的架构设计可能会导致后期的开发工作十分艰难&#xff0c;甚至会造成“推倒重来”的情形。因此&#xff0c;在系统设计阶…...

Redis 拒绝服务漏洞(CVE-2023-28856)修复处理

一、漏洞描述 Redis Labs Redis是美国Redis Labs公司的一套开源的使用ANSI C编写、支持网络、可基于内存亦可持久化的日志型、键值&#xff08;Key-Value&#xff09;存储数据库&#xff0c;并提供多种语言的API。 Redis 7.0.0 到 7.0.10版本、6.2.0 到 6.2.11版本、6.0.0 到 …...

Android保存网页的方法

首先要使用js交互就需要懂原理&#xff1a; 感谢大佬&#xff1a;js中document节点获取页面元素的六种方式 1.querySelector()方法 描述&#xff1a;本方法用于根据给定的选择器选中页面元素 如果有多个元素满足条件&#xff0c;则返回第一个满足条件的元素节点 语法&#xff…...

P2P 网络,PING程序。

没有废话,直接上版本号和代码,以及讲解。 crate版本号libp2p0.52.1tokio1.30.0依赖配置: [dependencies] tokio = { version="1.30.0", features=["full"] } libp2p = { version="0.52.1", features=["tokio","dns", &q…...

OPENCV C++(十二)模板匹配

正常模板匹配函数 matchTemplate(img, templatee, resultMat, 0);//模板匹配 这里0代表的是方法&#xff0c;一般默认为0就ok img是输入图像 templatee是模板 resultmat是输出 1、cv::TM_SQDIFF&#xff1a;该方法使用平方差进行匹配&#xff0c;因此最佳的匹配结果在结果为…...

网络六边形受到攻击

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 抽象 现代智能交通系统 &#xff08;ITS&#xff09; 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 &#xff08;…...

谷歌浏览器插件

项目中有时候会用到插件 sync-cookie-extension1.0.0&#xff1a;开发环境同步测试 cookie 至 localhost&#xff0c;便于本地请求服务携带 cookie 参考地址&#xff1a;https://juejin.cn/post/7139354571712757767 里面有源码下载下来&#xff0c;加在到扩展即可使用FeHelp…...

生成xcframework

打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式&#xff0c;可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...

TDengine 快速体验(Docker 镜像方式)

简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能&#xff0c;本节首先介绍如何通过 Docker 快速体验 TDengine&#xff0c;然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker&#xff0c;请使用 安装包的方式快…...

Linux链表操作全解析

Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表&#xff1f;1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...

【入坑系列】TiDB 强制索引在不同库下不生效问题

文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

Qt Widget类解析与代码注释

#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码&#xff0c;写上注释 当然可以&#xff01;这段代码是 Qt …...

关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案

问题描述&#xff1a;iview使用table 中type: "index",分页之后 &#xff0c;索引还是从1开始&#xff0c;试过绑定后台返回数据的id, 这种方法可行&#xff0c;就是后台返回数据的每个页面id都不完全是按照从1开始的升序&#xff0c;因此百度了下&#xff0c;找到了…...

汽车生产虚拟实训中的技能提升与生产优化​

在制造业蓬勃发展的大背景下&#xff0c;虚拟教学实训宛如一颗璀璨的新星&#xff0c;正发挥着不可或缺且日益凸显的关键作用&#xff0c;源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例&#xff0c;汽车生产线上各类…...

【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表

1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...