海思屏幕HAL代碼解析

顯示屏幕(LCD)模塊提供屏幕相關功能接口,調用者爲上層應用模塊(含 init、狀態機、ui),上下文依賴關係,如圖 3-7 所示。linux

系統框架爲 linux+Huawei LiteOS 雙系統架構,媒體業務部署在 Huawei LiteOS 端,爲了上電快速預覽,須要屏幕需部署在 Huawei LiteOS。api

  • 用戶交互業務在 linux 端,屏幕亮度、熄屏/亮屏等屏幕動態屬性須要在 linux 端提供接口。
  • 屏幕 HAL 層含 linux 和 Huawei LiteOS 業務接口。
  • linux 經過 ipcmsg 將命令傳送給 Huawei liteOS,全部業務功能實現都在 Huawei LiteOS 端。

LCD HAL 層架構圖架構

初始化流程主要包含如下方面:app

  • 操做系統配置,如雙核驅動、共享文件系統初始化;
  • 芯片配置,如管腳配置、系統時鐘、媒體驅動加載;
  • 外設配置,如屏幕配置、外設驅動加載;
  • 業務服務啓動,如媒體初始化、開機業務、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. linux 一端的代碼

Linux 端初始化主要處理與業務功能強相關的初始化操做,如狀態管理業務、按鍵業務、儲存管理業務、文件管理業務、UI 等。ide

Hi3556AV100_MobileCam_SDK_V2.0.1.0\reference\actioncam\modules\init\amp\linux\src中的hi_product_main.c函數

進程名字爲main_app,在bootapp腳本下運行:oop

main函數開始:ui

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媒體處理開發流程》
    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 以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;
}
相關文章
相關標籤/搜索