显示屏幕(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"); }
  1. 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;

  1. 创造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;
}
  1. 其他都以注释的方式的再以上面来说:

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\st7789libhi_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;
}

海思屏幕HAL代码解析的更多相关文章

  1. 海思的一个 Makefile 解析

    Makefile 原文 include ../Makefile.param #ifeq ($(SAMPLE_PARAM_FILE), ) # SAMPLE_PARAM_FILE:=../Makefil ...

  2. 建立live555海思编码推流服务

    因项目需要,这一周弄了一下live555.需求:海思编码——>RTSP server,使用VLC可以访问,类似于网络摄像机的需求.看了一下,live555的架构太复杂了,半桶水的C++水平还真的 ...

  3. 海思hi35xx 开发学习(3):视频输入

    视频输入(VI)模块实现的功能:通过 MIPI Rx(含 MIPI 接口.LVDS 接口和 HISPI 接口),SLVS-EC,BT.1120,BT.656,BT.601,DC 等接口接收视频数据.V ...

  4. 海思HI35xx平台软件开发快速入门之H264解码实例学习

    ref :https://blog.csdn.net/wytzsjzly/article/details/82500277   前言 H264视频编码技术诞生于2003年,至今已有十余载,技术相当成熟 ...

  5. 【海思】Hi3516A 运行sample_venc的demo内核奔溃(DDR问题)

    作者:李春港 出处:https://www.cnblogs.com/lcgbk/p/14514297.html 目录 一.前言 二.使用memtester对ddr进行压力测试 三.修改uboot的DD ...

  6. 海思3516系列芯片SPI速率慢问题深入分析与优化(基于PL022 SPI 控制器)

    海思3516系列芯片SPI速率慢问题深入分析与优化(基于PL022 SPI 控制器) 我在某个海思主控的项目中需要使用SPI接口来驱动一块液晶屏,液晶屏主控为 st7789,分辨率 240x240,图 ...

  7. 用VS2013+VELT-0.1.4进行海思平台 Linux内核 的开发

    快乐虾 http://blog.csdn.net/lights_joy/(QQ群:Visual EmbedLinux Tools 375515651) 欢迎转载,但请保留作者信息 本文仅适用于vs20 ...

  8. 主流芯片解决方案Ambarella的高清网络摄像机、德州仪器和控制海思

    (本文由四川艾普作为数码科技有限公司 苏斌.范清华 收集) 高清网络视频监控发展到今天.正的高清时代.诸多有实力的高清摄像机厂家的产品线也逐渐完好起来,高清网络视频监控的配套产品有更加丰富和成熟.与此 ...

  9. 用vs2013+velt-0.1.4进行嵌入式开发 进行海思平台 UBOOT 开发

    1.1    什么是VELT VELT的全称是Visual EmbedLinuxTools,它是一个与visual gdb类似的visual studio插件,用以辅助完成Linux开发.利用这个插件 ...

随机推荐

  1. Easy User Manager System writeup

    0x01 解题 思路 一个进程用自己的ip去申请拿到code然后进入verify页面,另外一个进程去申请8.8.8.8 步骤 1. 首先注册一个账号 然后用两个不同的浏览器进入Change页面.这里我 ...

  2. iOS 中UICollectionView实现各种视觉效果

    参考链接:https://www.jianshu.com/p/b3322f41e84c 基础:https://www.jianshu.com/p/d0b034f59020

  3. nRF24L01+组网方式及防撞(防冲突)机制的实战分享

    利用多个nRF24L01+模块组网通信的实现方式 这里讨论的组网方式,不包含使用6个通道实现的多对1通信方式,因其只限于6个发送端,局限性很大,可以附加其他技术实现更好的组网,暂时这里不讨论.这里分享 ...

  4. 网络管理和nmcli命令的使用——网络接口配置-bonding实验步骤

    (实验)网络接口配置-bonding  Bonding 将多块网卡绑定同一IP地址对外提供服务,可以实现高可用或者负载均衡.直接给两块网卡设置同\一IP地址是不可以的.通过bonding,虚拟一块网 ...

  5. macOS 10.15 开启 HiDPI

    普通的显示,接上 MacBook 发现原生的分辨率设置在 2K 显示器上字体很小,换成 1080P 分辨率显示效果又特别模糊.下面介绍MacBook强行开启 HiDPI. 什么是 HiDPI 它使用横 ...

  6. poj 1979 Red and Black 题解《挑战程序设计竞赛》

    地址 http://poj.org/problem?id=1979 Description There is a rectangular room, covered with square tiles ...

  7. 设计模式-Bridge(结构型模式)-用于客户需求较多,频繁对类进行添加修改的情形,将抽象类与具体实现类分开

    以下代码来源: 设计模式精解-GoF 23种设计模式解析附C++实现源码 //AbstractionImp.h #pragma once class AbstractionImp { public: ...

  8. DevExpress中TreeList树样式调整

    DevExpress的TreeList默认是没有树状线的,修改TreeLineStyle属性无效,这对于Tree并不好看. 解决方案一 官方解释说对于DevExpress的标准主题是不支持TreeLi ...

  9. python进阶之垃圾回收

    内存使用: 程序在运行的过程需要开辟内存空间,比如创建一个对象需要一片内存空间,定义变量需要内存空间.有内存的开辟,势必也要有内存的释放,不然只进不出那不是貔貅了吗?即使有开辟有释放在短期内还是会有垃 ...

  10. Java连载52-单例模式的缺点以及抽象类

    一.单例模式 1.单例模式的缺点:单例模式的类型没有子类,无法被继承. 例如:下面的例子,由于父类的构造方法是私有的,所以子类中的构造方法是无法创建的,因为它是引用父类的构造方法 package co ...