我是靠谱客的博主 腼腆绿茶,最近开发中收集的这篇文章主要介绍屏的启动流程,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

.

屏的启动流程

取的代码为:
svn+ssh://svn@10.20.30.18/svn-repos/mtk6735m-aly/trunk/pb3.2.0
使用的屏为:
lcd: HL_5093D,
IC: ILI9806E,
size: 5.0寸,
Resolution:480*854,
亮屏修改与增加的文件为:
LK:
新建 pb3.2.0bootablebootloaderlkdevlcmWZP_FW_ILI9806E WZP_FW_ILI9806E.c
主要实现
LCM_DRIVER WZP_FW_ILI9806E_drv =
{
.name = “WZP_FW_ILI9806E_drv”,
.set_util_funcs = wzp_lcm_set_util_funcs,
.get_params = wzp_lcm_get_params, //屏的相关参数
.init = wzp_lcm_init, //屏的初始化函数
.suspend = wzp_lcm_suspend, //屏的睡眠函数(在Kernel中调用)
.resume = wzp_lcm_resume, //屏的睡眠唤醒函数(在Kernel中调用)
.compare_id = wzp_lcm_compare_id, //多个屏驱动的比较函数
};

新建 pb3.2.0bootablebootloaderlkdevlcmWZP_FW_ILI9806E Makefile
新增行obj-y += WZP_FW_ILI9806E.o

修改pb3.2.0bootablebootloaderlkdevlcm mt65xx_lcm_list.c
	(新增一行extern LCM_DRIVER WZP_FW_ILI9806E_drv;
	  在LCM_DRIVER* lcm_driver_list[] 中新增

#if defined(WZP_FW_ILI9806E)
&WZP_FW_ILI9806E_drv,
#endif

修改 pb3.2.0bootablebootloaderlkproject ali6735_35gt_a_l1.mk

(在文件中这一行增加CUSTOM_LK_LCM=“WZP_FW_ILI9806E jd9161ba_fwvga_vdo hx8389b_qhd_dsi_vdo otm8018b_dsi_vdo”)

Kernel:
新建pb3.2.0kernel-3.10driversmiscmediateklcmWZP_FW_ILI9806EWZP_FW_ILI9806E.c
新建pb3.2.0kernel-3.10driversmiscmediateklcmWZP_FW_ILI9806E Makefile
修改pb3.2.0kernel-3.10driversmiscmediateklcmmt65xx_lcm_list.c
修改pb3.2.0kernel-3.10archarmconfigsali6735_35gt_a_l1_debug_defconfig
(在文件中这一行增加CONFIG_CUSTOM_KERNEL_LCM=“WZP_FW_ILI9806E lcm_common jd9161ba_fwvga_vdo hx8389b_qhd_dsi_vdo otm8018b_dsi_vdo”)

在LK中初始化,并显示手机第一屏:
Lk指(pb3.2.0/bootable/bootloader/lk),lk启动代码从main.c开始
Main.c (lk/kernel/main.c)
static int bootstrap2(void *arg)
{

platform_init(); //跳转到Platform.c
}

Platform.c (lk/platform/mt6735/platform.c)
void platform_init(void) //这个函数完成部分硬件的初始化,如震动马达、nand、背光、屏
{
	…

g_fb_size = mt_disp_get_vram_size();//屏的初始化从这里开始,跳到
Mt_disp_drv.c
// g_fb_base为内存的地址,作为屏的显存frame buffer,
}

Mt_disp_drv.c (lk/platform/mt6735/Mt_disp_drv.c)
UINT32 mt_disp_get_vram_size(void)

{
return DISP_GetVRamSize();//跳转到primary_display.c
}

Primary_display.c (lk/platform/mt6735/Primary_display.c)
unsigned int DISP_GetVRamSize(void)
{
static UINT32 vramSize = 0;
if (0 == vramSize)
{
vramSize = DISP_GetFBRamSize();//跳转

}
跳转到这个函数:
UINT32 DISP_GetFBRamSize(void)
{
return ALIGN_TO(DISP_GetScreenWidth(), MTK_FB_ALIGNMENT) * DISP_GetScreenHeight() * ((DISP_GetScreenBpp() + 7) >> 3) * DISP_GetPages();
}
跳转到这个函数:
UINT32 DISP_GetScreenWidth(void)
{
return primary_display_get_width();
}
跳转到这个函数:
int primary_display_get_width(void)
{
if(pgc->plcm == NULL)
{
pgc->plcm = disp_lcm_probe(NULL, LCM_INTERFACE_NOTDEFINED);
DISPMSG(“lcm handle is null, after probe:0x%08xn”,pgc->plcm);
if(pgc->plcm == NULL)//跳转到Disp_lcm.c
return 0;
}

}

Disp_lcm.c (lk/platform/mt6735/Disp_lcm.c)
disp_lcm_handle* disp_lcm_probe(char* plcm_name, LCM_INTERFACE_ID lcm_id)
{ //寻找匹配的屏的驱动

if(_lcm_count() == 0) //确定mt65xx_lcm_list.c中定义的屏驱动的个数
{
DISPERR(“no lcm driver defined in linux kernel drivern”);
return NULL;
}
else
{
// in lk, plcm_name should always be NULL
if(plcm_name == NULL) //LK默认没有name,Kernel中为mtkfb
{
int i = 0;
disp_path_handle handle = NULL;
disp_lcm_handle hlcm;
disp_lcm_handle *plcm = &hlcm;
LCM_PARAMS hlcm_param;

		for(i=0;i<_lcm_count();i++) //遍历mt65xx_lcm_list.c中的屏驱动,寻找匹配的
		{
			memset((void*)&hlcm, 0, sizeof(disp_lcm_handle));
			memset((void*)&hlcm_param, 0, sizeof(LCM_PARAMS));
			
			lcm_drv= lcm_driver_list[i]; //调用WZP_FW_ILI9806E.c或其它

的用户定义的驱动函数
lcm_drv->get_params(&hlcm_param);
plcm->drv = lcm_drv;
plcm->params = &hlcm_param;
plcm->lcm_if_id = plcm->params->lcm_if;
DISPMSG(“we will check lcm: %sn”, lcm_drv->name);
if(lcm_id == LCM_INTERFACE_NOTDEFINED ||(lcm_id != LCM_INTERFACE_NOTDEFINED && plcm->lcm_if_id == lcm_id))
{
handle = _display_interface_path_init(plcm);//获取到驱动后,执行
屏的初始化
if(handle == NULL)
{
DISPERR("_display_interface_path_init returns NULLn");
goto FAIL;
}

				if(lcm_drv->init_power)
				{
					lcm_drv->init_power();
				}

				if(lcm_drv->compare_id != NULL)
				{
					if(lcm_drv->compare_id() != 0)//多驱动时,比较ID匹配屏驱动
					{
						isLCMFound = true;//如果ID匹配,则找到驱动,退出循环
						_display_interface_path_deinit(handle);
						break;
					}
				}
				
				_display_interface_path_deinit(handle);//如果没找到匹配的驱动,则消

除屏相关初始化,再次开始循环遍历
}
}

		if(isLCMFound == false)//如果遍历完毕没匹配到合适的,默认使用第一个
		{
			DISPERR("we have checked all lcm driver, but no lcm foundn");
			lcm_drv = lcm_driver_list[0];
			isLCMFound = true;
		}
	}
	else
	{
		int i = 0;
		for(i=0;i<_lcm_count();i++)
		{
			lcm_drv = lcm_driver_list[i];
			if(!strcmp(lcm_drv->name, plcm_name))
			{
				isLCMFound = true;
				break;
			}
		}
	}
}

}

至此,LK中屏初始化完成,可以正常显示画面,
Platform.c (lk/platform/mt6735/platform.c)
void platform_init(void)
{

mt_disp_init((void *)g_fb_base);//初始化完成后继续往下执行
mt_disp_fill_rect(0, 0, CFG_DISPLAY_WIDTH, CFG_DISPLAY_HEIGHT, 0x0);//显示黑色画面
mt_disp_update(0, 0, CFG_DISPLAY_WIDTH, CFG_DISPLAY_HEIGHT); //刷新屏显示画面

}

在LK启动完成后,将初始化相关参数保存入command_line中,供Kernel中调用。

最后

以上就是腼腆绿茶为你收集整理的屏的启动流程的全部内容,希望文章能够帮你解决屏的启动流程所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(45)

评论列表共有 0 条评论

立即
投稿
返回
顶部