海思屏幕HAL代码解析
显示屏幕(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_DEBUGprintf(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); //屏幕注册0PDT_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_ONHI_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_PROCESSif (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_ONHI_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_ONs32Ret = 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");
#endifPDT_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_DEBUGHI_LOG_Config(HI_TRUE, HI_FALSE, HI_LOG_LEVEL_INFO);HI_MAPI_LOG_SetEnabledLevel(HI_MAPI_LOG_LEVEL_DEBUG);
#elseHI_LOG_Config(HI_TRUE, HI_FALSE, HI_LOG_LEVEL_ERROR);HI_MAPI_LOG_SetEnabledLevel(HI_MAPI_LOG_LEVEL_ERR);
#endifHI_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_ONMLOGD("HI_PDT_INIT_SERVICE_PreInit ...\n");s32Ret = HI_PDT_INIT_SERVICE_PreInit();HI_APPCOMM_CHECK_RETURN(s32Ret, HI_FAILURE);
#endifreturn 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_GPIOMLOGD("-->gpio init ...\n");extern int gpio_dev_init(void);gpio_dev_init();
#endifreturn 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){//因为上文已经用了这个,所以会用到这一路的I2C1if (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_IMX377g_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_IMX477g_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_ONMLOGD("HI_PDT_INIT_SERVICE_Init ...\n");s32Ret = HI_PDT_INIT_SERVICE_Init();HI_APPCOMM_CHECK_RETURN(s32Ret, HI_FAILURE);
#endifreturn 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_MOTIONSENSORMLOGI(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();
#endifreturn 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;#endifreturn 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_SCREENMLOGD("msg hal screen init ...\n");extern HI_S32 MSG_HAL_SCREEN_ServiceInit(HI_VOID);MSG_HAL_SCREEN_ServiceInit();HI_TIME_STAMP;
#endifMLOGD("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_RELEASEs32Ret = HI_PDT_SCENE_Init();HI_APPCOMM_CHECK_RETURN_WITH_ERRINFO(s32Ret,HI_FAILURE,"init scene");
#endif#ifdef CFG_RAW_PARAM_ONs32Ret = PDT_INIT_MediaInit();HI_APPCOMM_CHECK_RETURN_WITH_ERRINFO(s32Ret, HI_FAILURE, "HI_INIT_PDT_MediaInit");
#endifreturn 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;
#endifs_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_ONMLOGD("HI_PDT_INIT_SERVICE_PostInit ...\n");HI_TIME_STAMP;s32Ret = HI_PDT_INIT_SERVICE_PostInit();HI_APPCOMM_CHECK_RETURN(s32Ret, HI_FAILURE);
#endifreturn 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;
}
转载于:https://www.cnblogs.com/linhaostudy/p/11077703.html
海思屏幕HAL代码解析相关推荐
- 4 海思Hi3518E实例代码分析
海思媒体(mmp)处理平台架构 海思媒体处理平台的主要内部处理流程如图 1-2 所示,主要分为视频输入(VI).视频处理(VPSS).视频编码(VENC).视频解码(VDEC).视频输出(VO).视频 ...
- 【投稿】海思手撕代码之_RR_arbiter
背景:优先级仲裁器的关键缺点是,在非常繁忙的系统中,对于较低优先级的请求在收到授权之前需要等待的时间没有限制.另一方面,循环仲裁器允许每个请求者按顺序进行一轮.维护一个指针寄存器,它指向下一个请求者. ...
- 海思IVE算法原理解析一--遮挡检测(occlusion deection)
前言 这个算法就是满足摄像头遮挡报警这个功能需求 代码分析 0xfffffffLL是个长整形, 如果你也好奇这个写法的话. 流程 创建灰度图像的积分图计算任务 算出图像灰度值的平均值,均方差,u, v ...
- 海思屏幕MIPI显示颜色异常
现象是使用 mipi 显示时,视频颜色是正常的,但是 QT 程序和 hifb 测试程序颜色均不正常,但是 hifb 的背景颜色是正常的. 主要的问题是 sample hifb 的颜色也都不对,怎么调都 ...
- 音视频数据采集及单向传输的实现(海思3516EV200平台)
目录 2.硬件选型 2.1远端无线装置 2.1.1音视频采集模块 2.1.2光电转换模块 2.2本地接受设备 2.2.1光电转换模块 2.2.2音视频还原模块 3.串口配置 4.音视频采集 5.音视频 ...
- 海思芯片(hi3516dv300)uboot镜像生成过程详解
1.前言 (1)本文介绍的uboot编译过程是基于海思提供SDK包里的uboot源码进行编译,具体的编译参数是根据hi3516dv300芯片来设置的,编译生成的uboot烧录镜像也是用于hi3516d ...
- 如何用海思HI3516DV300/3518EV200推流H.264
一开始尝试用hi3518EV200, 后来为了给自己加难度, 就买了个hi3516的板子, 看看差异多大, 结论是, 不大... 前期准备: 你得有一个3516或者3518的开发板(淘宝有卖各种开发板 ...
- [海思]--Hi3516a--GPIO(用户层)
[海思]–Hi3516a–GPIO(用户层)控制篇 海思Hi3516aGPIO用户层控制篇 简介 海思GPIO配置说明 海思GPIO复用寄存器 海思GPIO寄存器 代码 伪代码 C代码 简介 gpio ...
- 海思视频传输延时与速率问题初步解决
题记:在上个月,用hi3518c+live555,实现在局域网中传输视频后,然后延时太大,大概延时域网中720p的画面延时在8s,640*480 在5s,320*240在3s左右,当时没有多去研究,然 ...
最新文章
- Python学习之字符串格式化
- lua学习笔记之开始
- ios开发入门篇(四):UIWebView结合UISearchBar的简单用法
- python变量声明语句_python – 在条件语句中声明变量有问题吗?
- coreboot学习0:二度相逢是初识
- 搜索引擎的那些事(32位MD5算法)
- mysql中的表显示“使用中”解决办法!
- 用Maven新建Web项目时报错
- 段地址寄存器、偏移地址寄存器
- Linux 人大金仓安装部署记录
- 玩转Linux与运维岗(21)
- win10电脑自带的office突然变成英文解决办法
- 离散型随机变量及其分布律2
- 【postgresql】数据聚合之PERCENTILE_CONT
- Postgresql日期转字符串
- 最短路径——Dijkstra算法与Floyd算法
- windows计算器(calc)按键功能详解
- P10-Windows与网络基础-Windows基本命令-DOS网络相关操作命令
- 如何在网站中加入qq咨询
- php如何实现添加到购物车_php购物车功能如何实现
热门文章
- Charles的基本使用方法
- Java实现字数统计(中文英文韩文日文混合),类似word效果
- Python PDF转JPG
- win10打开蓝牙_Win10开启蓝牙移动热点共享上网教程
- 传统 以太网 时隙(slot time) 理解
- iOS -- 使用蒲公英进行内测
- 世界级3D渲染大赛TOP3大佬们的制作流程大揭秘!
- 华为k662c的虚拟服务器,华为k662c路由器怎么设置 | 华为k662c路由器设置_什么值得买...
- 上个礼拜公司组织去浙江旅游的照片
- SP3232串口上电瞬间发乱码问题