顯示屏幕(LCD)模塊提供屏幕相關功能接口,調用者爲上層應用模塊(含 init、狀態機、ui),上下文依賴關係,如圖 3-7 所示。linux
系統框架爲 linux+Huawei LiteOS 雙系統架構,媒體業務部署在 Huawei LiteOS 端,爲了上電快速預覽,須要屏幕需部署在 Huawei LiteOS。shell
LCD HAL 層架構圖api
媒體流程圖:架構
初始化流程主要包含如下方面:app
INIT 模塊在系統中對外的依賴關係如圖 4-82 所示。框架
├──liteos │ ├── src │ │ ├── hi_product_init_main.c //Huawei LiteOS 端初始化 main 函數 │ │ ├── hi_product_init_hi35xxvxx.c //芯片相關初始化 C 文件 │ │ ├── hi_product_init_chip.h //芯片相關初始化頭文件 │ │ ├── hi_product_ init _os.c //OS 相關初始化 C 文件 │ │ ├── hi_product_ init _os.h //OS 相關初始化頭文件 │ │ ├── hi_product_ init _peripheral.c //外設相關初始化 C 文件 │ │ ├── hi_product_ init _peripheral.h //外設相關初始化頭文件 │ │ └── hi_product_ init _service.c //業務相關初始化 C 文件 │ │ └── hi_product_ init _service.h //業務相關初始化頭文件 │ ├──Makefile ├──linux │ ├── src │ │ ├── hi_product_main.c //linux 端初始化實現 │ ├──Makefile └── Makefile
經過全局搜索,能夠知道在build.mk/kconfig.mak
中的AMP_TYPE爲linux_liteos
dom
Linux 端初始化主要處理與業務功能強相關的初始化操做,如狀態管理業務、按鍵業務、儲存管理業務、文件管理業務、UI 等。ide
在Hi3556AV100_MobileCam_SDK_V2.0.1.0\reference\actioncam\modules\init\amp\linux\src
中的hi_product_main.c
函數
進程名字爲main_app
,在bootapp腳本下運行:oop
從main
函數開始:
HI_S32 main(HI_S32 s32Argc, HI_CHAR* pszArgv[]) { HI_TIME_STAMP; HI_PDT_WORKMODE_E enPoweronWorkmode = HI_PDT_WORKMODE_BUTT; HI_STORAGEMNG_CFG_S stStorageMngCfg; PDT_Init(&enPoweronWorkmode, &stStorageMngCfg); #if PDT_APP_COMMAND_DEBUG printf(GREEN"\nenable command line debug tool\n\n"NONE); PDT_CommandDebug(enPoweronWorkmode, &stStorageMngCfg); #endif /** wait for poweroff Semaphore, it can not run to here when ** PDT_APP_COMMAND_DEBUG is true and the while loop is not over */ while((HI_SUCCESS != sem_wait(&s_PowerOffSem)) && (errno == EINTR)); PDT_Deinit(&stStorageMngCfg); return HI_SUCCESS; }
看一下主要的函數PDT_Init()
函數,下面主要講幾個主要的關於LCD的函數:
static HI_VOID PDT_Init(HI_PDT_WORKMODE_E *penPoweronWorkmode, HI_STORAGEMNG_CFG_S* pstStorageMngCfg) { HI_S32 s32Ret = HI_SUCCESS; /** init debug related setting */ PDT_SetDebugLogLevel(); //初始化打印優先級 PDT_SetCrashHandleType(); //初始化錯誤發生的時候的處理的句柄函數,其實裏面就是處理了相應的信號函數 /** init semaphore */ sem_init(&s_PowerOffSem, 0, 0); //初始化信號量 /** init Param */ s32Ret = HI_PDT_PARAM_Init(); //初始化變量 PDT_APP_CHECK_RET(s32Ret, "HI_PDT_PARAM_Init"); /** init ShareFs */ extern void sharefs_server_init(void); sharefs_server_init(); //這裏是調用ipcm 中的sharefs,sharedfs是liteos與Linux之間利用 IPCM 通訊和共享內存,實現其讀寫 Linux上指定目錄下的內容。 /** init custom msg client */ s32Ret = HI_MSG_CLIENT_Init(); //初始化ipcm中的client端 PDT_APP_CHECK_RET(s32Ret, "HI_MSG_CLIENT_Init"); /** set system time */ PDT_SyncLinuxLiteosTime(); //同步liteos和Linux的時間 /** register hal sreen ops */ #if defined(CONFIG_SCREEN) extern HI_HAL_SCREEN_OBJ_S stHALSCREENObj; s32Ret = HI_HAL_SCREEN_Register(HI_HAL_SCREEN_IDX_0, &stHALSCREENObj); //HI_HAL_SCREEN_IDX_0是指枚舉,是指第一個屏幕,初始化重複註冊一次 PDT_APP_CHECK_RET(s32Ret, "HI_HAL_SCREEN_Register"); s32Ret = HI_HAL_SCREEN_Init(HI_HAL_SCREEN_IDX_0); //屏幕註冊0 PDT_APP_CHECK_RET(s32Ret, "HI_HAL_SCREEN_Init"); #endif /** create load driver thread */ s32Ret = PDT_LoadDriverThread(); PDT_APP_CHECK_RET(s32Ret, "PDT_LoadDriverThread"); /** get rtc time from liteOS */ /** init eventhub */ s32Ret = HI_EVTHUB_Init(); //初始化事件路由模塊,詳情參考《camera 中間件開發參考》,統一管理系統中事件訂閱和發佈的模塊 PDT_APP_CHECK_RET(s32Ret, "HI_EVTHUB_Init"); HI_STORAGEMNG_RegisterEvent(); //將存儲註冊到eventhub裏面 HI_RECMNG_RegisterEvent(); //將RECMNG註冊到eventhub裏面 HI_PHOTOMNG_RegisterEvent(); HI_FILEMNG_RegisterEvent(); HI_PDT_USBCTRL_RegisterEvent(); HI_PDT_STATEMNG_RegisterEvent(); HI_KEYMNG_RegisterEvent(); HI_PDT_MEDIA_RegisterEvent(); HI_PDT_PARAM_RegisterEvent(); HI_LIVESVR_RegisterEvent(); HI_PDT_SCENE_RegisterEvent(); HI_UPGRADE_RegisterEvent(); HI_PDT_NETCTRL_RegisterEvent(); #ifdef CONFIG_GAUGE_ON HI_GAUGEMNG_RegisterEvent(); #endif /** init mapi sys */ s32Ret = HI_MAPI_Sys_Init(); //初始化系統資源,參考文檔《HiMAPI V1.0媒體處理開發流程》 //在MPI升級爲MAPI,MPI參考過於繁瑣 PDT_APP_CHECK_RET(s32Ret, "HI_MAPI_Sys_Init"); HI_PDT_WORKMODE_E enPoweronWorkmode = HI_PDT_WORKMODE_BUTT; HI_PDT_POWERON_ACTION_E enPoweronAction = HI_PDT_POWERON_ACTION_BUTT; s32Ret = HI_PDT_STATEMNG_GeneratePoweronWorkmode(&enPoweronAction, &enPoweronWorkmode); //狀態管理電源開機狀態機 PDT_APP_CHECK_RET(s32Ret,"GetPowerOnWorkMode"); MLOGD("PowerOn WorkMode(%d)\n", enPoweronWorkmode); *penPoweronWorkmode = enPoweronWorkmode; HI_PDT_MEDIAMODE_E enMediaMode = HI_PDT_MEDIAMODE_BUTT; s32Ret = HI_PDT_PARAM_GetWorkModeParam(enPoweronWorkmode, HI_PDT_PARAM_TYPE_MEDIAMODE, (HI_VOID *)&enMediaMode); //獲取工做模式參數 PDT_APP_CHECK_RET(s32Ret,"GetWorkModeParam MediaMode"); MLOGD("Init MediaMode[%d]\n", enMediaMode); HI_PDT_MEDIA_CFG_S stMediaCfg; HI_PDT_SCENE_MODE_S stSceneModeCfg; s32Ret = HI_PDT_PARAM_GetMediaCfg(enPoweronWorkmode, enMediaMode, &stMediaCfg, &stSceneModeCfg); //獲取媒體模式的配置 PDT_APP_CHECK_RET(s32Ret,"GetMediaModeCfg"); HI_BOOL bLoadDsp = HI_FALSE; #ifdef CFG_POST_PROCESS if (HI_PDT_WORKMODE_SING_PHOTO == enPoweronWorkmode || HI_PDT_WORKMODE_DLAY_PHOTO == enPoweronWorkmode) { bLoadDsp = HI_TRUE; } #endif /** init media */ s32Ret = HI_PDT_MEDIA_Init(&stMediaCfg.stViVpssMode, &stMediaCfg.stVBCfg, bLoadDsp); //媒體初始化,包括 VI VPSS 模式配置和通路 VB 配置。 PDT_APP_CHECK_RET(s32Ret,"HI_MEDIA_Init"); /** update vo config */ s32Ret = HI_PDT_Media_UpdateDispCfg(&stMediaCfg, &stMediaCfg.stVideoOutCfg.astDispCfg[0]); PDT_APP_CHECK_RET(s32Ret, "HI_PDT_Media_UpdateDispCfg"); /** init video out */ s32Ret = HI_PDT_MEDIA_VideoOutInit(&(stMediaCfg.stVideoOutCfg)); //視頻輸出通路初始化 PDT_APP_CHECK_RET(s32Ret,"HI_MEDIA_VideoOutInit"); MLOGD(GREEN"vo init done\n"NONE); /** init timedtask */ s32Ret = HI_TIMEDTASK_Init(); //定時器初始化 PDT_APP_CHECK_RET(s32Ret, "HI_TIMEDTASK_Init"); /** init player */ s32Ret = HI_PLAYER_Init(); //初始化播放器 PDT_APP_CHECK_RET(s32Ret, "HI_PLAYER_Init"); /** init ui */ s32Ret = HI_PDT_UI_Init(); PDT_APP_CHECK_RET(s32Ret, "HI_PDT_UI_Init"); MLOGD(GREEN"UI init done\n"NONE); /** load mmc driver */ PDT_LoadMmcDriver(); //加載mmc driver /** init storagemng */ memset(pstStorageMngCfg, 0, sizeof(HI_STORAGEMNG_CFG_S)); s32Ret = HI_PDT_PARAM_GetStorageCfg(pstStorageMngCfg); PDT_APP_CHECK_RET(s32Ret, "GetStorageCfg"); MLOGD("DevPath[%s] MountPath[%s]\n"NONE, pstStorageMngCfg->szDevPath, pstStorageMngCfg->szMntPath); HI_STORAGEMNG_CALLBACK_S stCallback; stCallback.pfnFormatPreProc = PDT_StoragemngFormatPreProc; s32Ret = HI_STORAGEMNG_Create(pstStorageMngCfg,&stCallback); //建立SD卡管理模塊 PDT_APP_CHECK_RET(s32Ret, "HI_STORAGEMNG_Create"); /* init osd */ HI_PDT_MEDIA_OSD_VIDEO_ATTR_S stOsdVideoAttr; HI_PDT_PARAM_GetOSDVideoAttr(&stOsdVideoAttr); s32Ret = HI_PDT_MEDIA_InitOSD(&stOsdVideoAttr, &stMediaCfg.stVideoCfg.stOsdCfg); //OSD 初始化,分配時間/字符串格式 OSD 位圖資源。 PDT_APP_CHECK_RET(s32Ret, "InitOSD"); /** init netCtrl */ s32Ret = HI_PDT_NETCTRL_Init(); PDT_APP_CHECK_RET(s32Ret, "HI_PDT_NETCTRL_Init"); #ifdef CONFIG_GAUGE_ON HI_GAUGEMNG_CFG_S stGaugeCfg = {}; stGaugeCfg.s32LowLevel = PDT_BATTERT_LOW_LEVEL; stGaugeCfg.s32UltraLowLevel = PDT_BATTERT_ULTRA_LOW_LEVEL; s32Ret = HI_GAUGEMNG_Init(&stGaugeCfg); //初始化電源管理模塊 PDT_APP_CHECK_RET(s32Ret, "HI_GAUGEMNG_Init"); #endif #ifdef CONFIG_RAWCAP_ON /** init rawcap */ s32Ret = HI_RAWCAP_Init(); PDT_APP_CHECK_RET(s32Ret, "HI_RAWCAP_Init"); #endif /** init statemng */ HI_PDT_STATEMNG_CONFIG_S stStatemngCfg; stStatemngCfg.pfnExitMode = PDT_ExitModeCallback; stStatemngCfg.pfnFormatPreProc = PDT_StoragemngFormatPreProc; s32Ret = HI_PDT_STATEMNG_Init(&stStatemngCfg); //以普通錄像爲主 PDT_APP_CHECK_RET(s32Ret, "HI_PDT_STATEMNG_Init"); /** create delay services start thread */ s32Ret = PDT_ServiceDelayedStartThread(); PDT_APP_CHECK_RET(s32Ret, "PDT_ServiceDelayedStartThread"); }
IPCM的初始化,詳情參考:《HiSysLink API 開發參考.pdf》
/** * @brief init the msg client. * @return 0 success,non-zero error code. * @exception None * @author HiMobileCam Reference Develop Team * @date 2017/12/22 */ HI_S32 HI_MSG_CLIENT_Init(HI_VOID) { HI_S32 s32Ret = 0; HI_APPCOMM_CHECK_EXPR(-1 == g_s32MsgFd, HI_EINITIALIZED); HI_IPCMSG_CONNECT_S stConnectAttr = {1, HI_APPCOMM_MSG_SRVPORT, 1}; s32Ret = HI_IPCMSG_AddService(HI_APPCOMM_MSG_SRVNAME, &stConnectAttr); //增長IPCM的服務 if (HI_SUCCESS != s32Ret) { HI_LOG_PrintFuncErr(HI_IPCMSG_AddService, s32Ret); return HI_EINTER; } s32Ret = HI_IPCMSG_Connect(&g_s32MsgFd, HI_APPCOMM_MSG_SRVNAME, MSG_Handler); //阻塞方式創建鏈接 if (HI_SUCCESS != s32Ret) { HI_IPCMSG_DelService(HI_APPCOMM_MSG_SRVNAME); HI_LOG_PrintFuncErr(HI_IPCMSG_Connect, s32Ret); return HI_EINTER; } pthread_t threadid; s32Ret = pthread_create(&threadid, NULL, MSG_CLIENT_Run, NULL); if (HI_SUCCESS != s32Ret) { HI_IPCMSG_Disconnect(g_s32MsgFd); HI_IPCMSG_DelService(HI_APPCOMM_MSG_SRVNAME); g_s32MsgFd = -1; MLOGE("pthread_create fail:%s\n", strerror(errno)); return HI_ENORES; } return HI_SUCCESS; }
這就證實了上圖的方式,Linux做爲client,用ipcm與liteos創建聯繫,讀寫sharefs;
讀取驅動的線程:
HI_S32 HI_insmod(const HI_CHAR* pszPath, const HI_CHAR* pszOptions) { HI_S32 rc = 0; HI_APPCOMM_CHECK_POINTER(pszPath, HI_EINVAL); rc = hi_init_module(pszPath, pszOptions); if (rc) { MLOGE("can't insert '%s': %s\n", pszPath, moderror(rc)); } return rc; } HI_S32 HI_HAL_TOUCHPAD_Init(HI_VOID) { HI_S32 s32Ret = HI_SUCCESS; if (HI_FALSE == s_bTOUCHPADInitState) { HAL_TOUCHPAD_PinoutInit(); //初始化相應的管腳 /** insmod touchpad driver */ s32Ret = HI_insmod(HAL_TOUCHPAD_KO_PATH,NULL); if(0 != s32Ret) { MLOGE("insmod touchpad:failed, errno(%d)\n", errno); return HI_HAL_EINVOKESYS; } s_bTOUCHPADInitState = HI_TRUE; } else { MLOGE("touchapd already init\n"); return HI_HAL_EINITIALIZED; } return HI_SUCCESS; } /** load driver task */ static HI_U32 PDT_LoadDriver(void* pVoid) { HI_S32 s32Ret = HI_SUCCESS; pthread_detach(pthread_self()); #ifdef CFG_LCD_TOUCHPAD_ON s32Ret = HI_HAL_TOUCHPAD_Init(); //先加載驅動 PDT_APP_CHECK_RET(s32Ret, "HI_HAL_TOUCHPAD_Init"); s32Ret = HI_HAL_TOUCHPAD_Suspend(); //而後觸摸板進行睡眠 PDT_APP_CHECK_RET(s32Ret, "HI_HAL_TOUCHPAD_Suspend"); #endif PDT_LoadUSBPhy(); return s32Ret; } /** create thread to load driver */ static HI_S32 PDT_LoadDriverThread() { HI_S32 s32Ret = HI_SUCCESS; s32Ret = pthread_create(&s_KoThread, NULL, (void*)PDT_LoadDriver, NULL); PDT_APP_CHECK_RET(s32Ret, "pthread_create for PDT_LoadDriver"); return s32Ret; }
咱們使用瞭如下兩個函數:
在HI_HAL_SCREEN_Register
中:
HI_S32 HI_HAL_SCREEN_Register(HI_HAL_SCREEN_IDX_E enScreenIndex, const HI_HAL_SCREEN_OBJ_S* pstScreenObj) { HI_APPCOMM_CHECK_POINTER(pstScreenObj, HI_HAL_EINVAL); HI_APPCOMM_CHECK_POINTER(pstScreenObj->pfnDeinit, HI_HAL_EINVAL); HI_APPCOMM_CHECK_POINTER(pstScreenObj->pfnGetAttr, HI_HAL_EINVAL); HI_APPCOMM_CHECK_POINTER(pstScreenObj->pfnGetBackLightState, HI_HAL_EINVAL); HI_APPCOMM_CHECK_POINTER(pstScreenObj->pfnGetContrast, HI_HAL_EINVAL); HI_APPCOMM_CHECK_POINTER(pstScreenObj->pfnGetDisplayState, HI_HAL_EINVAL); HI_APPCOMM_CHECK_POINTER(pstScreenObj->pfnGetLuma, HI_HAL_EINVAL); HI_APPCOMM_CHECK_POINTER(pstScreenObj->pfnGetSaturature, HI_HAL_EINVAL); HI_APPCOMM_CHECK_POINTER(pstScreenObj->pfnInit, HI_HAL_EINVAL); HI_APPCOMM_CHECK_POINTER(pstScreenObj->pfnSetBackLightState, HI_HAL_EINVAL); HI_APPCOMM_CHECK_POINTER(pstScreenObj->pfnSetContrast, HI_HAL_EINVAL); HI_APPCOMM_CHECK_POINTER(pstScreenObj->pfnSetDisplayState, HI_HAL_EINVAL); HI_APPCOMM_CHECK_POINTER(pstScreenObj->pfnSetLuma, HI_HAL_EINVAL); HI_APPCOMM_CHECK_POINTER(pstScreenObj->pfnSetSaturature, HI_HAL_EINVAL); HAL_SCREEN_CHECK_IDX(enScreenIndex); if (s_astHALSCREENCtx[enScreenIndex].bRegister) { MLOGD("Screen[%d] has been registered\n", enScreenIndex); return HI_HAL_EREGRED; } memcpy(&s_astHALSCREENCtx[enScreenIndex].stScreenObj, pstScreenObj, sizeof(HI_HAL_SCREEN_OBJ_S)); s_astHALSCREENCtx[enScreenIndex].bRegister = HI_TRUE; return HI_SUCCESS; }
其實就是將傳進來的參數賦值給s_astHALSCREENCtx
;
HI_HAL_SCREEN_Init函數分爲server端的和client端的,而根據海思的代碼結構,server端的代碼是在liteos下的,client端的則是在Linux下的:
HI_S32 HI_HAL_SCREEN_Init(HI_HAL_SCREEN_IDX_E enScreenIndex) { HAL_SCREEN_CHECK_IDX(enScreenIndex); HAL_SCREEN_CHECK_REGISTER(enScreenIndex); if (s_astHALSCREENCtx[enScreenIndex].bInit) { MLOGD("Screen[%d] has been inited\n", enScreenIndex); return HI_HAL_EINITIALIZED; } HI_S32 s32Ret = HI_SUCCESS; //發送同步信息 s32Ret = HI_MSG_SendSync(MSG_HAL_SCREEN_INIT, &enScreenIndex, sizeof(HI_HAL_SCREEN_IDX_E), HI_NULL, HI_NULL, 0); HI_APPCOMM_CHECK_RETURN_WITH_ERRINFO(s32Ret, HI_HAL_EINTER, "HI_MSG_CLIENT_SendSync"); s_astHALSCREENCtx[enScreenIndex].bInit = HI_TRUE; return HI_SUCCESS; }
liteos下的代碼是從reference/actioncam/modules/init/amp/liteos/src/hi_product_init_main.c
中的app_init
函數開始的:
HI_VOID app_init(HI_VOID) { #ifdef CONFIG_DEBUG HI_LOG_Config(HI_TRUE, HI_FALSE, HI_LOG_LEVEL_INFO); HI_MAPI_LOG_SetEnabledLevel(HI_MAPI_LOG_LEVEL_DEBUG); #else HI_LOG_Config(HI_TRUE, HI_FALSE, HI_LOG_LEVEL_ERROR); HI_MAPI_LOG_SetEnabledLevel(HI_MAPI_LOG_LEVEL_ERR); #endif HI_TIME_STAMP; PDT_INIT_PreInit(); PDT_INIT_Init(); PDT_INIT_PostInit(); HI_TIME_STAMP; PDT_INIT_CmdReg(); HI_TIME_PRINT; return ; }
static HI_S32 PDT_INIT_PreInit(HI_VOID) { HI_S32 s32Ret = HI_SUCCESS; MLOGD("HI_PDT_INIT_OS_PreInit ...\n"); s32Ret = HI_PDT_INIT_OS_PreInit(); HI_APPCOMM_CHECK_RETURN(s32Ret, HI_FAILURE); MLOGD("HI_PDT_INIT_CHIP_PreInit ...\n"); s32Ret = HI_PDT_INIT_CHIP_PreInit(); HI_APPCOMM_CHECK_RETURN(s32Ret, HI_FAILURE); MLOGD("HI_PDT_INIT_PERIPHERAL_PreInit ...\n"); s32Ret = HI_PDT_INIT_PERIPHERAL_PreInit(); HI_APPCOMM_CHECK_RETURN(s32Ret, HI_FAILURE); #ifndef CONFIG_PQT_STREAM_SUPPORT_ON MLOGD("HI_PDT_INIT_SERVICE_PreInit ...\n"); s32Ret = HI_PDT_INIT_SERVICE_PreInit(); HI_APPCOMM_CHECK_RETURN(s32Ret, HI_FAILURE); #endif return s32Ret; }
HI_S32 HI_PDT_INIT_OS_PreInit(HI_VOID) { HI_S32 s32Ret = HI_SUCCESS; // Huawei LiteOS調用_ipcm_vdd_init初始化,Linux用命令insmod hi_ipcm.ko 加載 extern int _ipcm_vdd_init(void); MLOGD("-->ipcm init ...\n"); _ipcm_vdd_init(); //調用osdrv/components/ipcm/ipcm中的sharefs的初始化 extern int sharefs_client_init(const char *path); MLOGD("-->sharefs init ...\n"); sharefs_client_init(HI_SHAREFS_ROOT_PATH); //virt_tty 初始化,也是在ipcm中初始化的 extern int virt_tty_dev_init(void); MLOGD("-->virt tty init ...\n"); virt_tty_dev_init(); /* uart init */ //初始化liteos的串口的使用 if (uart_dev_init() != 0) { MLOGE("uart_dev_init failed"); } //虛擬串口初始化,在osdrv/platform/liteos/platform/bsp/common/virtual_serial.c中 if (virtual_serial_init(TTY_DEVICE) != 0) { MLOGE("virtual_serial_init failed"); } if (system_console_init(SERIAL) != 0) { MLOGE("system_console_init failed\n"); } /* shell init */ extern unsigned int osShellInit(void); if (osShellInit() != 0) { MLOGE("osShellInit\n"); } MLOGD("-->random dev init ...\n"); extern int ran_dev_register(void); ran_dev_register(); MLOGD("-->mem dev init ...\n"); //liteo 的mem驅動管理 extern int mem_dev_register(void); mem_dev_register(); MLOGD("-->porc fs init ...\n"); extern void proc_fs_init(void); proc_fs_init(); #ifdef LOSCFG_DRIVERS_GPIO MLOGD("-->gpio init ...\n"); extern int gpio_dev_init(void); gpio_dev_init(); #endif return s32Ret; }
static HI_VOID sensor_pinmux_config(void) { HI_U32 i = 0; sensor_pin_mux(); for (i = 0; i < MAX_SENSOR_NUM; i++) { if (g_stSensorCfg[i].enSensortype == PDT_INIT_SENSOR_TYPE_I2C) { //由於上文已經用了這個,因此會用到這一路的I2C1 if (0 == g_stSensorCfg[i].u32SensorBusId) { i2c1_pin_mux(); } else if (1 == g_stSensorCfg[i].u32SensorBusId) { i2c2_pin_mux(); } else if (2 == g_stSensorCfg[i].u32SensorBusId) { i2c3_pin_mux(); } else if (3 == g_stSensorCfg[i].u32SensorBusId) { i2c4_pin_mux(); } else if (4 == g_stSensorCfg[i].u32SensorBusId) { i2c5_pin_mux(); } else { return; } } else if (g_stSensorCfg[i].enSensortype == PDT_INIT_SENSOR_TYPE_SPI) { if (0 == g_stSensorCfg[i].u32SensorBusId) { spi0_pin_mux(); } else if (1 == g_stSensorCfg[i].u32SensorBusId) { spi1_pin_mux(); } else if (2 == g_stSensorCfg[i].u32SensorBusId) { spi2_pin_mux(); } else if (3 == g_stSensorCfg[i].u32SensorBusId) { //spi3_pin_mux(); } else if (4 == g_stSensorCfg[i].u32SensorBusId) { spi4_pin_mux(); } else { return; } } else { } } }
/**< CLK config **/ static void system_clk_cfg(void) { himm(0x045100dc, 0x06080008); himm(0x045100EC, 0x00007fff); himm(0x04510104, 0x000036db); himm(0x04510108, 0x000036db); himm(0x0451010C, 0x0001b000); himm(0x04510110, 0x0000003c); himm(0x04510118, 0x00000007); himm(0x0451011C, 0x00003017); himm(0x0451011C, 0x00003011); himm(0x04510120, 0x2815e4c3); himm(0x04510140, 0x2); himm(0x04510150, 0x2); himm(0x04510168, 0x00000010); himm(0x0451016c, 0x00000362); himm(0x04510194, 0x009aaa80); himm(0x04510198, 0x68ff0000); himm(0x045101a0, 0x33ff0000); }
static void peripheral_pinmux_cfg(void) { /**<bus_pin_mux for lcd*/ Lcd_Pin_Mux(); /**<bus_pin_mux for 9022 */ i2c0_pin_mux(); /**<bus_pin_mux for hmdi*/ hmdi_pin_mode(); /**<bus_pin_mux for audio dev */ //i2s_pin_mux(); }
HI_S32 HI_PDT_INIT_CHIP_PreInit(HI_VOID) { HI_S32 s32Ret = HI_SUCCESS; memset(g_stSensorCfg, 0x00, sizeof(g_stSensorCfg)); #ifdef CONFIG_SNS0_IMX377 g_stSensorCfg[0].enSensortype = PDT_INIT_SENSOR_TYPE_I2C; g_stSensorCfg[0].u32SensorBusId = 0; g_stSensorCfg[0].enSensorClk = PDT_INIT_SENSOR_CLK_24MHz; snprintf(g_stSensorCfg[0].szSensorName, MAX_SENSOR_NAME_LEN, "%s", "imx377"); #endif #ifdef CONFIG_SNS0_IMX477 g_stSensorCfg[0].enSensortype = PDT_INIT_SENSOR_TYPE_I2C; g_stSensorCfg[0].u32SensorBusId = 0; g_stSensorCfg[0].enSensorClk = PDT_INIT_SENSOR_CLK_24MHz; snprintf(g_stSensorCfg[0].szSensorName, MAX_SENSOR_NAME_LEN, "%s", "imx477"); #endif //在這裏g_stSensorCfg[0].enSensortype = I2C1, sensor_pinmux_config(); //系統時鐘初始化 system_clk_cfg(); //system_pwr_en(); //amp_unmute(); sys_ctl(0); //system_qosbuf(); lowpower_cfg(); //初始化i2c、lcd、hmdi的管腳 peripheral_pinmux_cfg(); osal_proc_init(); //mmz內存區初始化 s32Ret = MMZ_init(); HI_APPCOMM_CHECK_EXPR_WITHOUT_RETURN((HI_SUCCESS == s32Ret), "MMZ_init"); //讀取mmp數據 load_mpp(); himm(0x0452a000, 0x74664444); /**<Set VICAP Priority->7*/ himm(0x0460409c,0x40);/**<Set VICAP timeout = 256*/ //初始化i2c驅動 sensor_driver_load(); //i2c時鐘配置 sensor_clock_config(); axi_lowpower_cfg(); s32Ret = PM_init(); HI_APPCOMM_CHECK_EXPR_WITHOUT_RETURN((HI_SUCCESS == s32Ret), "PM_init"); ao_unmute(); return s32Ret; }
其中說幾個重要的函數:
則是一條空函數
初始化變量
先解析一下這個函數:
static HI_S32 PDT_INIT_Init(HI_VOID) { HI_S32 s32Ret = HI_SUCCESS; MLOGD("HI_PDT_INIT_OS_Init ...\n"); s32Ret = HI_PDT_INIT_OS_Init(); HI_APPCOMM_CHECK_RETURN(s32Ret, HI_FAILURE); MLOGD("HI_PDT_INIT_CHIP_Init ...\n"); s32Ret = HI_PDT_INIT_CHIP_Init(); HI_APPCOMM_CHECK_RETURN(s32Ret, HI_FAILURE); MLOGD("HI_PDT_INIT_PERIPHERAL_Init ...\n"); s32Ret = HI_PDT_INIT_PERIPHERAL_Init(); HI_APPCOMM_CHECK_RETURN(s32Ret, HI_FAILURE); //CONFIG_PQT_STREAM_SUPPORT_ON已經在build/kconfig.mak沒有定義,因此能夠進來 #ifndef CONFIG_PQT_STREAM_SUPPORT_ON MLOGD("HI_PDT_INIT_SERVICE_Init ...\n"); s32Ret = HI_PDT_INIT_SERVICE_Init(); HI_APPCOMM_CHECK_RETURN(s32Ret, HI_FAILURE); #endif return s32Ret; }
HI_S32 HI_PDT_INIT_OS_Init(HI_VOID) { HI_S32 s32Ret = HI_SUCCESS; extern char __init_array_start__, __init_array_end__; //C++構造函數初始化 LOS_CppSystemInit((unsigned long)&__init_array_start__, (unsigned long)&__init_array_end__,NO_SCATTER); //增長相對路徑 LOS_PathAdd(HI_SHAREFS_ROOT_PATH); HI_SYSTEM_TM_S stDateTime; //獲取系統時鐘 HI_SYSTEM_GetRTCDateTime(&stDateTime); //設置時間等內容 HI_SYSTEM_SetDateTime(&stDateTime); return s32Ret; }
空函數
HI_S32 HI_PDT_INIT_PERIPHERAL_Init(HI_VOID) { HI_S32 s32Ret = HI_SUCCESS; #if defined(CONFIG_SCREEN) MLOGD("-->screen init ...\n"); extern HI_HAL_SCREEN_OBJ_S stHALSCREENObj; s32Ret = HI_HAL_SCREEN_Register(HI_HAL_SCREEN_IDX_0, &stHALSCREENObj); HI_APPCOMM_CHECK_EXPR_WITHOUT_RETURN(HI_SUCCESS == s32Ret, "HI_HAL_SCREEN_Register"); //重點看這裏 s32Ret= HI_HAL_SCREEN_Init(HI_HAL_SCREEN_IDX_0); HI_APPCOMM_CHECK_EXPR_WITHOUT_RETURN(HI_SUCCESS == s32Ret, "HI_HAL_SCREEN_Init"); #if (!defined(BOARD_ACTIONCAM_REFB)) s32Ret = HI_HAL_SCREEN_SetBackLightState(HI_HAL_SCREEN_IDX_0, HI_HAL_SCREEN_STATE_ON); HI_APPCOMM_CHECK_EXPR_WITHOUT_RETURN(HI_SUCCESS == s32Ret, "HI_HAL_SCREEN_SetBackLightState"); #endif #endif #ifdef CONFIG_MOTIONSENSOR MLOGI(YELLOW"-->motionsensor init ...\n"NONE); s32Ret = HI_HAL_MOTIONSENSOR_Init(); HI_APPCOMM_CHECK_EXPR_WITHOUT_RETURN(HI_SUCCESS == s32Ret, "HI_HAL_MOTIONSENSOR_Init"); Gyro_Dis_init(); MOTIONFUSION_init(); #endif return s32Ret; }
HI_S32 HI_HAL_SCREEN_Init(HI_HAL_SCREEN_IDX_E enScreenIndex) { HAL_SCREEN_CHECK_IDX(enScreenIndex); HAL_SCREEN_CHECK_REGISTER(enScreenIndex); if (s_astHALSCREENCtx[enScreenIndex].bInit) { MLOGD("Screen[%d] has been inited\n", enScreenIndex); return HI_SUCCESS; } HI_S32 s32Ret = HI_SUCCESS; if(HI_NULL != s_astHALSCREENCtx[enScreenIndex].stScreenObj.pfnInit) { s32Ret = s_astHALSCREENCtx[enScreenIndex].stScreenObj.pfnInit(); //在這裏調用了相應的函數 HI_APPCOMM_CHECK_RETURN_WITH_ERRINFO(s32Ret, HI_HAL_EINTER, "pfnInit"); } else { MLOGE("Screen[%d] Null ptr.\n", enScreenIndex); return HI_HAL_EINVAL; } s_astHALSCREENCtx[enScreenIndex].bInit = HI_TRUE; return HI_SUCCESS; }
這裏調用的是stHALSCREENObj
爲ST7789實現的結構體;
在reference\hal\screen\st7789\hal_screen_st7789.c
文件中:
/** OTA5182 Object */ HI_HAL_SCREEN_OBJ_S stHALSCREENObj = { .pfnInit = HAL_SCREEN_ST7789_Init, .pfnGetAttr = HAL_SCREEN_ST7789_GetAttr, .pfnSetDisplayState = HAL_SCREEN_ST7789_SetDisplayState, .pfnGetDisplayState = HAL_SCREEN_ST7789_GetDisplayState, .pfnSetBackLightState = HAL_SCREEN_ST7789_SetBackLightState, .pfnGetBackLightState = HAL_SCREEN_ST7789_GetBackLightState, .pfnSetLuma = HAL_SCREEN_ST7789_SetLuma, .pfnGetLuma = HAL_SCREEN_ST7789_GetLuma, .pfnSetSaturature = HAL_SCREEN_ST7789_SetSatuature, .pfnGetSaturature = HAL_SCREEN_ST7789_GetSatuature, .pfnSetContrast = HAL_SCREEN_ST7789_SetContrast, .pfnGetContrast = HAL_SCREEN_ST7789_GetContrast, .pfnDeinit = HAL_SCREEN_ST7789_Deinit, };
static HI_S32 HAL_SCREEN_ST7789_Init(HI_VOID) { /** Initial screen Device */ #if (defined(AMP_LINUX_HUAWEILITE) && defined(__HuaweiLite__)) || defined(AMP_HUAWEILITE) //liteos端用的是這邊的函數 HI_S32 s32Ret = HI_SUCCESS; s32Ret = hi_ssp_lcd_init(); if (HI_SUCCESS != s32Ret) { MLOGE("init screen failed\n"); return HI_HAL_EINTER; }; s_stHALSCREENFt7789Ctx.enSCREENDisplayState = HI_TRUE; #elif (defined(AMP_LINUX)) //這個沒有定義,因此沒有進這裏面 HI_S32 s32Ret = HI_SUCCESS; s32Ret = HI_insmod(HI_APPFS_KOMOD_PATH"/hi_ssp_st7789.ko",NULL); if(HI_SUCCESS != s32Ret) { MLOGE("insmod hi_ssp_st7789:failed\n"); return HI_HAL_EINTER; } s_s32HALSCREENFd = open(HAL_SCREEN_DEV, O_RDWR); if (HAL_FD_INITIALIZATION_VAL == s_s32HALSCREENFd) { HI_rmmod(HI_APPFS_KOMOD_PATH"/hi_ssp_st7789.ko"); return HI_HAL_EINTER; } s_stHALSCREENFt7789Ctx.enSCREENDisplayState = HI_TRUE; #endif return HI_SUCCESS; }
hi_ssp_lcd_init函數則是在reference/actioncam/modules/init/amp/liteos
下的Makefile調用了amp\a53_liteos\drv\extdrv\screen\st7789
的libhi_ssp_st7789.a
的靜態庫,具體以下:
這個函數就是在liteos下初始化了整個屏幕;
HI_S32 HI_PDT_INIT_SERVICE_Init(HI_VOID) { HI_S32 s32Ret = HI_SUCCESS; HI_TIME_STAMP; /* mapi log level */ //設置mapi的打印優先級 HI_MAPI_LOG_SetEnabledLevel(HI_MAPI_LOG_LEVEL_WARN); //創建多核之間通訊,初始化系統資源,創建多CPU間消息通訊管道 s32Ret = HI_MAPI_Sys_Init(); HI_APPCOMM_CHECK_RETURN_WITH_ERRINFO(s32Ret, HI_FAILURE, "HI_MAPI_Sys_Init"); HI_TIME_STAMP; //這個宏定義也是能夠進來的 #if defined(AMP_LINUX_HUAWEILITE) /* msg */ MLOGD("msg server init ...\n"); HI_MSG_SERVER_Init(); HI_TIME_STAMP; MLOGD("msg system server init ...\n"); HI_SYSTEM_ServiceInit(); HI_TIME_STAMP; #ifdef CONFIG_SCREEN MLOGD("msg hal screen init ...\n"); extern HI_S32 MSG_HAL_SCREEN_ServiceInit(HI_VOID); MSG_HAL_SCREEN_ServiceInit(); HI_TIME_STAMP; #endif MLOGD("msg scene msg server init ...\n"); HI_PDT_SCENE_MSG_SERVER_Init(); HI_TIME_STAMP; extern HI_S32 PDT_MEDIA_MSG_RegisterCallback(HI_VOID); MLOGI("msg media init ...\n"); PDT_MEDIA_MSG_RegisterCallback(); #endif #ifdef CONFIG_RELEASE s32Ret = HI_PDT_SCENE_Init(); HI_APPCOMM_CHECK_RETURN_WITH_ERRINFO(s32Ret,HI_FAILURE,"init scene"); #endif #ifdef CFG_RAW_PARAM_ON s32Ret = PDT_INIT_MediaInit(); HI_APPCOMM_CHECK_RETURN_WITH_ERRINFO(s32Ret, HI_FAILURE, "HI_INIT_PDT_MediaInit"); #endif return s32Ret; }
//增長一個線程 static HI_VOID* MSG_SERVER_Run(HI_VOID* arg) { prctl(PR_SET_NAME, __func__, 0, 0, 0); HI_S32 s32Ret = 0; while (s_bMSGServerRun) { //以阻塞的方式創建鏈接 s32Ret = HI_IPCMSG_Connect(&g_s32MsgFd, HI_APPCOMM_MSG_SRVNAME, MSG_Handler); if (HI_SUCCESS != s32Ret) { HI_LOG_PrintFuncErr(HI_IPCMSG_Connect, s32Ret); break; } if (0 < g_s32MsgFd) { HI_IPCMSG_Run(g_s32MsgFd); HI_IPCMSG_Disconnect(g_s32MsgFd); g_s32MsgFd = -1; } } HI_LOG_FuncExit(); return NULL; }
/** * @brief init the msg server. * @return 0 success,non-zero error code. * @exception None * @author HiMobileCam Reference Develop Team * @date 2017/12/22 */ HI_S32 HI_MSG_SERVER_Init(HI_VOID) { HI_S32 s32Ret = 0; HI_APPCOMM_CHECK_EXPR(0 == s_MSGServerTid, HI_EINITIALIZED); HI_IPCMSG_CONNECT_S stConnectAttr = {0, HI_APPCOMM_MSG_SRVPORT, 1}; //增長服務,因此能夠看到server與client的都有一個服務,之間是用共享內存來操做數據的 s32Ret = HI_IPCMSG_AddService(HI_APPCOMM_MSG_SRVNAME, &stConnectAttr); if (HI_SUCCESS != s32Ret) { HI_LOG_PrintFuncErr(HI_IPCMSG_AddService, s32Ret); return HI_EINTER; } pthread_attr_t threadattr; pthread_attr_init(&threadattr); #ifdef __HuaweiLite__ threadattr.stacksize = 0x10000; threadattr.inheritsched = PTHREAD_EXPLICIT_SCHED; threadattr.schedparam.sched_priority = 5; #endif s_bMSGServerRun = HI_TRUE; //建立了一個線程MSG_SERVER_Run函數 s32Ret = pthread_create(&s_MSGServerTid, &threadattr, MSG_SERVER_Run, NULL); pthread_attr_destroy(&threadattr); if (HI_SUCCESS != s32Ret) { HI_IPCMSG_DelService(HI_APPCOMM_MSG_SRVNAME); s_bMSGServerRun = HI_FALSE; MLOGE("pthread_create fail:%s\n", strerror(errno)); return HI_ENORES; } return HI_SUCCESS; }
註冊了全部接口關於屏幕的server端接口
/** * @brief register requst msg process function. * @param[in] s32MsgID:unique msg id. * @param[in] pfnReqProc:requst process function. * @param[in] pvUserData:user data. * @return 0 success,non-zero error code. * @exception None * @author HiMobileCam Reference Develop Team * @date 2017/12/22 */ HI_S32 HI_MSG_RegisterMsgProc(HI_S32 s32MsgID, HI_MSG_PROC_CALLBACK_FN_PTR pfnMsgProc, HI_VOID* pvUserData) { MSG_PROC_S* pstMsgProc = NULL; HI_List_Head_S* pstNode = NULL; HI_APPCOMM_CHECK_POINTER(pfnMsgProc, HI_FAILURE); //在消息創建一個鏈表 HI_List_For_Each(pstNode, &g_stMSGProcList) { pstMsgProc = HI_LIST_ENTRY(pstNode, MSG_PROC_S, stList); if (pstMsgProc) { if (s32MsgID == pstMsgProc->s32MsgID) { MLOGW("s32MsgID:%08x has been registered already,replace process function.\n", s32MsgID); break; } pstMsgProc = NULL; } } if (NULL == pstMsgProc) { pstMsgProc = (MSG_PROC_S*)malloc(sizeof(MSG_PROC_S)); HI_APPCOMM_CHECK_POINTER(pstMsgProc, HI_ENORES); HI_List_Add(&pstMsgProc->stList, &g_stMSGProcList); } pstMsgProc->s32MsgID = s32MsgID; pstMsgProc->pfnMsgProc = pfnMsgProc; pstMsgProc->pvUserData = pvUserData; return HI_SUCCESS; }
HI_S32 MSG_HAL_SCREEN_ServiceInit(HI_VOID) { HI_S32 s32Ret = HI_SUCCESS; s32Ret = HI_MSG_RegisterMsgProc(MSG_HAL_SCREEN_INIT, MSG_HAL_SCREEN_InitCallback, NULL); if (HI_FAILURE == s32Ret) { MLOGE(RED"msg RegReq failed\n\n"NONE); } s32Ret = HI_MSG_RegisterMsgProc(MSG_HAL_SCREEN_GETATTR, MSG_HAL_SCREEN_GetAttrCallback,NULL); if (HI_FAILURE == s32Ret) { MLOGE(RED"msg RegReq failed\n\n"NONE); } s32Ret = HI_MSG_RegisterMsgProc(MSG_HAL_SCREEN_GETDISPLAYSTATE, MSG_HAL_SCREEN_GetDisplayStateCallback,NULL); if (HI_FAILURE == s32Ret) { MLOGE(RED"msg RegReq failed\n\n"NONE); } s32Ret = HI_MSG_RegisterMsgProc(MSG_HAL_SCREEN_SETDISPLAYSTATE, MSG_HAL_SCREEN_SetDisplayStateCallback,NULL); if (HI_FAILURE == s32Ret) { MLOGE(RED"msg RegReq failed\n\n"NONE); } s32Ret = HI_MSG_RegisterMsgProc(MSG_HAL_SCREEN_GETBACKLIGHTSTATE, MSG_HAL_SCREEN_GetBackLightStateCallback,NULL); if (HI_FAILURE == s32Ret) { MLOGE(RED"msg RegReq failed\n\n"NONE); } s32Ret = HI_MSG_RegisterMsgProc(MSG_HAL_SCREEN_SETBACKLIGHTSTATE, MSG_HAL_SCREEN_SetBackLightStateCallback,NULL); if (HI_FAILURE == s32Ret) { MLOGE(RED"msg RegReq failed\n\n"NONE); } s32Ret = HI_MSG_RegisterMsgProc(MSG_HAL_SCREEN_GETLUMA, MSG_HAL_SCREEN_GetLumaCallback,NULL); if (HI_FAILURE == s32Ret) { MLOGE(RED"msg RegReq failed\n\n"NONE); } s32Ret = HI_MSG_RegisterMsgProc(MSG_HAL_SCREEN_SETLUMA, MSG_HAL_SCREEN_SetLumaCallback,NULL); if (HI_FAILURE == s32Ret) { MLOGE(RED"msg RegReq failed\n\n"NONE); } s32Ret = HI_MSG_RegisterMsgProc(MSG_HAL_SCREEN_GETSATURATURE, MSG_HAL_SCREEN_GetSaturatureCallback,NULL); if (HI_FAILURE == s32Ret) { MLOGE(RED"msg RegReq failed\n\n"NONE); } s32Ret = HI_MSG_RegisterMsgProc(MSG_HAL_SCREEN_SETSATURATURE, MSG_HAL_SCREEN_SetSaturatureCallback,NULL); if (HI_FAILURE == s32Ret) { MLOGE(RED"msg RegReq failed\n\n"NONE); } s32Ret = HI_MSG_RegisterMsgProc(MSG_HAL_SCREEN_GETCONTRAST, MSG_HAL_SCREEN_GetContrastCallback,NULL); if (HI_FAILURE == s32Ret) { MLOGE(RED"msg RegReq failed\n\n"NONE); } s32Ret = HI_MSG_RegisterMsgProc(MSG_HAL_SCREEN_SETCONTRAST, MSG_HAL_SCREEN_SetContrastCallback,NULL); if (HI_FAILURE == s32Ret) { MLOGE(RED"msg RegReq failed\n\n"NONE); } s32Ret = HI_MSG_RegisterMsgProc(MSG_HAL_SCREEN_DEINIT, MSG_HAL_SCREEN_DeinitCallback,NULL); if (HI_FAILURE == s32Ret) { MLOGE(RED"msg RegReq failed\n\n"NONE); } return s32Ret; }
註冊了請求media消息的處理函數
static HI_S32 PDT_INIT_PostInit(HI_VOID) { HI_S32 s32Ret = HI_SUCCESS; MLOGD("HI_PDT_INIT_OS_PostInit ...\n"); HI_TIME_STAMP; //空函數 s32Ret = HI_PDT_INIT_OS_PostInit(); HI_APPCOMM_CHECK_RETURN(s32Ret, HI_FAILURE); MLOGD("HI_PDT_INIT_CHIP_PostInit ...\n"); HI_TIME_STAMP; //空函數 s32Ret = HI_PDT_INIT_CHIP_PostInit(); HI_APPCOMM_CHECK_RETURN(s32Ret, HI_FAILURE); MLOGD("HI_PDT_INIT_PERIPHERAL_PostInit ...\n"); HI_TIME_STAMP; //註冊回調函數的背光 s32Ret = HI_PDT_INIT_PERIPHERAL_PostInit(); HI_APPCOMM_CHECK_RETURN(s32Ret, HI_FAILURE); #ifndef CONFIG_PQT_STREAM_SUPPORT_ON MLOGD("HI_PDT_INIT_SERVICE_PostInit ...\n"); HI_TIME_STAMP; s32Ret = HI_PDT_INIT_SERVICE_PostInit(); HI_APPCOMM_CHECK_RETURN(s32Ret, HI_FAILURE); #endif return s32Ret; }
首先要知道IPCMSG之間的通訊狀況,IPCMSG之間採用的是共享內存;
server與client端的通訊是以HI_MSG_SendSync
函數來傳遞信息的:
/** * @brief sync send msg. * @param[in] s32MsgID:unique msg id. * @param[in] pvRequest:request data. * @param[in] u32ReqLen:request data lenght. * @param[out] pvResponse:response data. * @param[in] u32RespLen:response data lenght. * @return 0 success,non-zero error code. * @exception None * @author HiMobileCam Reference Develop Team * @date 2017/12/22 */ HI_S32 HI_MSG_SendSync(HI_S32 s32MsgID, const HI_VOID* pvRequest, HI_U32 u32ReqLen, HI_MSG_PRIV_DATA_S* pstPrivData, HI_VOID* pvResponse, HI_U32 u32RespLen) { HI_S32 s32Ret = HI_SUCCESS; HI_IPCMSG_MESSAGE_S* pstReq = NULL; HI_IPCMSG_MESSAGE_S* pstResp = NULL; HI_APPCOMM_CHECK_EXPR(-1 != g_s32MsgFd, HI_ENOINIT); //建立消息 pstReq = HI_IPCMSG_CreateMessage(0, (HI_U32)s32MsgID, (HI_VOID*)pvRequest, u32ReqLen); if (pstReq) { if(pstPrivData != NULL) { memcpy(pstReq->as32PrivData, pstPrivData->as32PrivData, sizeof(HI_S32)*HI_IPCMSG_PRIVDATA_NUM); } //發送同步消息,同步消息是阻塞接口,會等待對端消息命令處理完成後再返回,因此對端必須回覆。 s32Ret = HI_IPCMSG_SendSync(g_s32MsgFd, pstReq, &pstResp, MSG_SEND_SYNC_TIMEOUT); HI_IPCMSG_DestroyMessage(pstReq); if (HI_SUCCESS != s32Ret || NULL == pstResp) { HI_LOG_PrintH32(s32MsgID); HI_LOG_PrintFuncErr(HI_IPCMSG_SendSync, s32Ret); return HI_EINTER; } else { s32Ret = pstResp->s32RetVal; if (NULL != pvResponse && NULL != pstResp->pBody && 0 < u32RespLen) { memcpy(pvResponse, pstResp->pBody, u32RespLen); } HI_IPCMSG_DestroyMessage(pstResp); return s32Ret; } } return HI_EINTER; }