顯示屏幕(LCD)模塊提供屏幕相關功能接口,調用者為上層應用模塊(含 init、狀態機、ui),上下文依賴關系,如圖 3-7 所示。
系統框架為 linux+Huawei LiteOS 雙系統架構,媒體業務部署在 Huawei LiteOS 端,為了上電快速預覽,需要屏幕需部署在 Huawei LiteOS。
- 用戶交互業務在 linux 端,屏幕亮度、熄屏/亮屏等屏幕動態屬性需要在 linux 端提供接口。
- 屏幕 HAL 層含 linux 和 Huawei LiteOS 業務接口。
- linux 通過 ipcmsg 將命令傳送給 Huawei liteOS,所有業務功能實現都在 Huawei LiteOS 端。
LCD HAL 層架構圖
媒體流程圖:
初始化流程主要包含以下方面:
- 操作系統配置,如雙核驅動、共享文件系統初始化;
- 芯片配置,如管腳配置、系統時鍾、媒體驅動加載;
- 外設配置,如屏幕配置、外設驅動加載;
- 業務服務啟動,如媒體初始化、開機業務、UI 啟動。
INIT 模塊在系統中對外的依賴關系如圖 4-82 所示。
1. 目錄結構:
1.1 雙系統 AMP 目錄結構
├──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
2. HAL的代碼
通過全局搜索,可以知道在build.mk/kconfig.mak
中的AMP_TYPE為linux_liteos
Linux 端初始化主要處理與業務功能強相關的初始化操作,如狀態管理業務、按鍵業務、儲存管理業務、文件管理業務、UI 等。
在Hi3556AV100_MobileCam_SDK_V2.0.1.0\reference\actioncam\modules\init\amp\linux\src
中的hi_product_main.c
2.1 Linux中的reference啟動代碼:
進程名字為main_app
,在bootapp腳本下運行:
從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");
}
- HI_MSG_CLIENT_Init
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;
- 創造PDT_LoadDriverThread線程
讀取驅動的線程:
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;
}
- 其他都以注釋的方式的再以上面來說:
2.1.1 以clinet端screen代碼的HAL而言:
我們使用了以下兩個函數:
- HI_HAL_SCREEN_Register
- HI_HAL_SCREEN_Init
在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
;
2.1.2 client端的HI_HAL_SCREEN_Init函數
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;
}
2.2 liteos下的reference啟動代碼:
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 ;
}
2.2.1 PDT_INIT_PreInit函數
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;
}
2.2.1.1 HI_PDT_INIT_OS_PreInit()函數
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;
}
2.2.1.2 HI_PDT_INIT_CHIP_PreInit函數
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;
}
其中說幾個重要的函數:
2.2.1.3 HI_PDT_INIT_PERIPHERAL_PreInit()函數
則是一條空函數
2.2.1.4 HI_PDT_PARAM_Init()函數
初始化變量
2.3 PDT_INIT_Init()函數
先解析一下這個函數:
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;
}
2.3.1 HI_PDT_INIT_OS_Init()函數
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;
}
2.3.2 HI_PDT_INIT_CHIP_Init()函數
空函數
2.3.3 HI_PDT_INIT_PERIPHERAL_Init()函數
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;
}
2.3.3.1 pfnInit()函數
這里調用的是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;
}
2.3.3.2 hi_ssp_lcd_init函數
hi_ssp_lcd_init函數則是在reference/actioncam/modules/init/amp/liteos
下的Makefile調用了amp\a53_liteos\drv\extdrv\screen\st7789
的libhi_ssp_st7789.a
的靜態庫,具體如下:
這個函數就是在liteos下初始化了整個屏幕;
2.3.4 HI_PDT_INIT_SERVICE_Init函數
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;
}
2.3.4.1 HI_MSG_SERVER_Init函數
//增加一個線程
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;
}
2.3.4.2 HI_SYSTEM_ServiceInit()函數
注冊了所有接口關於屏幕的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;
}
2.3.4.3 MSG_HAL_SCREEN_ServiceInit()函數
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;
}
2.3.4.4 PDT_MEDIA_MSG_RegisterCallback()函數
注冊了請求media消息的處理函數
2.4 PDT_INIT_PostInit()函數
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;
}
3. server與client端之間的通信
首先要知道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;
}