Hass screen HAL code analysis

A display screen (LCD) module provides an interface screen related functions, the caller is the upper layer application module (including the init, state machine, UI), the context dependency, shown in Figure 3-7.

The system framework for linux + Huawei LiteOS dual system architecture, media services deployed Huawei LiteOS end, in order to power up a quick preview, the screen needs to be deployed in Huawei LiteOS.

  • Linux user interactive services at the end, the screen brightness, the screen quenching / bright screen like the screen in the dynamic properties necessary to provide an interface end linux.
  • Screen HAL layer containing Huawei LiteOS linux and service interfaces.
  • By ipcmsg linux commands sent to Huawei liteOS, all business functions to achieve in Huawei LiteOS end.

LCD HAL layer of the architecture of FIG.

Initialization process mainly includes the following aspects:

  • Operating system configuration, such as dual-core driver, shared file system initialization;
  • Chip configuration, pin configuration as the system clock, loading the media drive;
  • Peripheral configuration, such as screen configuration, the peripheral driver is loaded;
  • Business service starts, such as media initialization, boot business, UI start.

INIT module external dependencies in the system shown in FIG 4-82.

1. Directory structure:

1.1 pairs AMP system directory structure

├──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

An end of the code 2. linux

Linux strongly correlated with the business end of the initialization process the main functions of the initialization operation, such as state management services, service keys, storage management services, file management services, the UI and the like.

In Hi3556AV100_MobileCam_SDK_V2.0.1.0\reference\actioncam\modules\init\amp\linux\srcthehi_product_main.c

Name for the process main_app, run under bootapp script:

From the mainbeginning of the function:

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

Look at the main function of PDT_Init()the function, the following is mainly about several major functions on the 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媒体处理开发流程》
    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 initialization details, refer to: "HiSysLink API development of reference .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;
}

This proves that the way on the map, Linux as a client, to establish contact with ipcm and liteos, reading and writing sharefs;

  1. Create PDT_LoadDriverThread thread

Reading drive thread:

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 以screen代码而言:

我们使用了以下两个函数:

  • 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)
{
    //检查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.2 HI_HAL_SCREEN_Init函数

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 pfnInit()函数

这里调用的是stHALSCREENObj为ST7789实现的结构体;

在hal_screens_st7789文件中:

/** 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)

    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))
    //所以在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;
}

Guess you like

Origin www.cnblogs.com/linhaostudy/p/11077703.html