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实现
意图 复用已经存在的接口,与所需接口不一致的类。即将一个类(通常是旧系统中的功能类),通过适配器转化成另一个接口的实现。(简单来说,就是复用旧系统的功能,去实现新的接口) 我们举…...

【elasticSearch系】3.完整搭建详尽版elk
话不多说,我们先看下经典的elk 是由哪些组件搭建组合起来的 elasticsearch和kibana搭建 可以查看之前我们搭建elasticsearch和kibana 的这篇文章 logstash搭建 为了和之前我们搭建elasticsearch和kibana版本保持一致,这里我们还是选择7.17.3 下载地址 点击下载,这里为了…...
代码随想录day04
24. 两两交换链表中的节点 ● 力扣题目链接 ● 给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。 ● 你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。 思路 ● 使用迭代的方法,分析交换逻辑即可 ○ …...
[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专业版🚜 一、win10 系统配置🎨 二、Docker下载和安装🏭 三、Docker配置🎉 四、Docker入门使用 ⛳ Docker 安装、配置和详细使用教程-Win10专业版 🚜 一、win10 系统配…...
Linux 教程
目录 Linux 教程 内核引导 运行init 运行级别 系统初始化 Linux 系统目录结构 Linux 教程 Lin...
图论——最短路算法
引入: 如上图,已知图G。 问节点1到节点3的最短距离。 可心算而出为d[1,2]d[2,3]112,比d[1,3]要小。 求最短路径算法: 1.Floyd(弗洛伊德) 是一种基于三角形不等式的多源最短路径算法。边权可以为负数 表现为a[i,j]a[j,k]<a[i,k]。 …...
在项目中增加网络加载需要考虑什么?
1、下载器 网络加载的第一步肯定是下载,那么选择一个合适的下载器是十分重要的,这个下载器最好支持什么功能? 多线程下载(同时需要服务端支持,下载时可指定range) 断点续传 通用性(其他位置也…...

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

青大数据结构【2014】
一、单选 二、简答 为了解决顺序队列的假溢出问题,提出了循环队列,即把存储队列的表从逻辑上看成一个环 判别队列空和满有三种方法: 1)采用计数器判别,空时,计数器为0;满时,计数器…...

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

27.Netty源码之FastThreadLocal
highlight: arduino-light FastThreadLocal FastThreadLocal 的实现与 ThreadLocal 非常类似,Netty 为 FastThreadLocal 量身打造了 FastThreadLocalThread 和 InternalThreadLocalMap 两个重要的类。下面我们看下这两个类是如何实现的。 FastThreadLocalThread 是对…...
linux下离线安装docker
linux下离线安装docker 一、安装docker Docker 官网离线安装文档 https://docs.docker.com/engine/install/binaries/ 整理步骤如下: 官网下载 docker 安装包,地址为 https://download.docker.com/linux/static/stable/,如果是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…...

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

Redis 拒绝服务漏洞(CVE-2023-28856)修复处理
一、漏洞描述 Redis Labs Redis是美国Redis Labs公司的一套开源的使用ANSI C编写、支持网络、可基于内存亦可持久化的日志型、键值(Key-Value)存储数据库,并提供多种语言的API。 Redis 7.0.0 到 7.0.10版本、6.2.0 到 6.2.11版本、6.0.0 到 …...
Android保存网页的方法
首先要使用js交互就需要懂原理: 感谢大佬:js中document节点获取页面元素的六种方式 1.querySelector()方法 描述:本方法用于根据给定的选择器选中页面元素 如果有多个元素满足条件,则返回第一个满足条件的元素节点 语法ÿ…...
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代表的是方法,一般默认为0就ok img是输入图像 templatee是模板 resultmat是输出 1、cv::TM_SQDIFF:该方法使用平方差进行匹配,因此最佳的匹配结果在结果为…...

网络六边形受到攻击
大家读完觉得有帮助记得关注和点赞!!! 抽象 现代智能交通系统 (ITS) 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 (…...
谷歌浏览器插件
项目中有时候会用到插件 sync-cookie-extension1.0.0:开发环境同步测试 cookie 至 localhost,便于本地请求服务携带 cookie 参考地址:https://juejin.cn/post/7139354571712757767 里面有源码下载下来,加在到扩展即可使用FeHelp…...
生成xcframework
打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式,可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...

TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...
Linux链表操作全解析
Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表?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; }//解释这串代码,写上注释 当然可以!这段代码是 Qt …...

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

汽车生产虚拟实训中的技能提升与生产优化
在制造业蓬勃发展的大背景下,虚拟教学实训宛如一颗璀璨的新星,正发挥着不可或缺且日益凸显的关键作用,源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例,汽车生产线上各类…...
【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表
1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...