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的value
    resultTemp = 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未进行配置不会初始化gptpInit
    if(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;
}

 

/**************************************************************************************************
@brief
    Get camera config

@return
    Error 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 file
    while(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中配置的settingsOverrrides
                    boardInfo->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->detectQ
        result = 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中的SensorLibConfig
        pSensorLib->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;
        }
        //加载sensorlib
        result = 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);
       //匹配解串器型号配置 解串器地址mode
        result = 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 use
        for (uint32_t devIdx = 0U; devIdx < pSensorLib->m_nInputDevices; devIdx++)
        {
            QcxInputDevice_t* const pInputDev = &pSensorLib->m_InputDevices[devIdx];
            pInputDev->delaySuspendFlag = FALSE;
            //配置解串器的index rang 0-3
            pInputDev->sensorlibId = libIdx;
            //配置解串器numdevices id
            pInputDev->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 detected
    return 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 0
    m_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_DEVICES
    pSensorLib->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
    }
#endif

    if (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 handle
        pSensorLib->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 cmd
    powerCtrl.cmd = SENSORLIB_PWRCMD_POWER_ON;
    //使用ioctl 对sensor 进行上电 MAX96712Ioctl
    ret = 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_setting
        ret = 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_subdevices
        ret = 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;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值