显示屏幕(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\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;
}

海思屏幕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. JS 输出

    JS 输出 JavaScript 通常用于操作 HTML 元素. 操作 HTML 元素 如需从 JavaScript 访问某个 HTML 元素,您可以使用 document.getElementByI ...

  2. 【转】java中使用WebSocket

    传统的请求,都是从客服端到服务端,表现在web应用上就是,消息都只能由浏览器发起请求,调用客户端的方法. webSocket可以从服务器端推送消息给浏览器. 使用场景: 当客户端发起缴费请求时,由服务 ...

  3. Spark中持久化和序列化学习

    一.cache和persisit的对比 -rw-r--r--@ 1 hadoop staff 68M 5 17 07:04 access.log    cache/persitence是 laz ...

  4. TypeScript 学习笔记(四)

    函数: 1.函数是一组一起执行一个任务的语句 2.我们可以把一段可复用的代码放到一起组成函数,从而提高效率 3.函数声明(通过关键字 function 来声明)告诉编译器函数的名称.返回类型和参数 4 ...

  5. python中基本数据类型以及运算符

    python中基本数据类型以及运算符的知识 一.与用户的交互以及python2与python的区别 1.1什么是与用户交互 用户交互就是人往计算机中input(输入数据),计算机print(输出结果) ...

  6. centos7.6 创建磁盘格式化

    fdisk /dev/vdb mkfs.ext4 /dev/vdb echo '/dev/vdb /sdata ext4 defaults 0 0' >> /etc/fstab mount ...

  7. 《数据挖掘导论》实验课——实验一、数据处理之Numpy

    实验一.数据处理之Numpy 一.实验目的 1. 了解numpy库的基本功能 2. 掌握Numpy库的对数组的操作与运算 二.实验工具: 1. Anaconda 2. Numpy 三.Numpy简介 ...

  8. HashMap与HashTable的区别和理解

    Hashmap的理解 1:HashMap是基于哈希表的Map接口的非同步实现.此实现提供所有可选的映射操作,并允许使用null值和null键.HashMap储存的是键值对,HashMap很快.此类不保 ...

  9. Noip2016Day1T2 天天爱跑步

    题目链接 problem solution 这是一道一个顶六个的好题!!! 说一下各档部分分怎么写吧. 先看一下\(S_i=1\)和\(T_i=1\)的部分分怎么写. 如果\(S_i=1\) 当且仅当 ...

  10. C#开发BIMFACE系列15 服务端API之获取模型的View token

    系列目录     [已更新最新开发文章,点击查看详细] 在<C#开发BIMFACE系列3 服务端API之获取应用访问凭证AccessToken>中详细介绍了应用程序访问API的令牌凭证.我 ...