uboot里开机LOGO显示功能解析

 uboot里开机LOGO显示功能解析

 

  开机LOGO,对于绝大多数带显示屏的电子产品都是必备的一个功能,是产品开机的第一印象,重要性不言而喻的,那我们下面就看看这个是怎么实现的。

   要尽早的显示出LOGO就需要在系统真正起来之前的boot阶段就能打通显示,而这个任务大多是以U-BOOT这样的角色来充当,全志平台在android4.4平台就是在u-boot里面实现的,支持的是BMP图片。大家分为几个步骤了,首先要读取图片,再解析图片数据,然后再送到显示部分,最后显示出来。事就是这么个事,说起来简单,理起来也简单,真正写出来的人并不简单,需要对这几个部分都很了解,当然对于平台来说,难度倒不是太大。下面一起看看吧!

/*****************************************************************************************************/
声明:本博内容均由http://blog.csdn.net/edsam49原创,转载请注明出处,谢谢!
/*****************************************************************************************************/

   首先,加载图片到内存中。加载的话,大家比较熟悉的也就是fatload,就是挂载一个fat的文件系统,从这个文件系统里面去读取这个文件的数据到指定内存位置,看看代码吧,也不难!

	char *const bmp_argv[6] = { "fatload", "sunxi_flash", "0", "40000000", bmp_name, NULL };

	memset(bmp_name, 0, 32);
	strcpy(bmp_name, name);
    if(do_fat_fsload(0, 0, 5, bmp_argv))
	{
	   printf("sunxi bmp info error : unable to open logo file %s\n", bmp_argv[4]);

	   return -1;
    }

  其次,得到图片原始数据了就需要做解析了,当然BMP图片的数据格式也是确定的,数据头确定,一般是54个字节,我们看看数据头的数据结构:

typedef struct bmp_header {
	/* Header */
	char signature[2];
	__u32	file_size;
	__u32	reserved;
	__u32	data_offset;
	/* InfoHeader */
	__u32	size;
	__u32	width;
	__u32	height;
	__u16	planes;
	__u16	bit_count;
	__u32	compression;
	__u32	image_size;
	__u32	x_pixels_per_m;
	__u32	y_pixels_per_m;
	__u32	colors_used;
	__u32	colors_important;
	/* ColorTable */

} __attribute__ ((packed)) bmp_header_t;

  打印出来又是怎么一个效果呢?如下:

bmp signature[]      B, M
bmp file_size        1536054
bmp reserved         -1
bmp data_offset      54
bmp size             40
bmp width            800
bmp height           -480
bmp planes           1
bmp bit_count        32
bmp compression      0
bmp image_size       1536000
bmp x_pixels_per_m   0
bmp y_pixels_per_m   0
bmp colors_used      0
bmp colors_important 0
bmp x = 320, bmp y = 1e0

   笔者测试的这个BMP图片用工具处理过,就是调整它的透明度,所以显示的高度有一点异常,取反就好了。看看下面的处理:

	if((bmp->header.signature[0]!='B') || (bmp->header.signature[1] !='M'))
	{
		printf("this is not a bmp picture\n");

		return -1;
	}
	debug("bmp dectece\n");

	bmp_bpix = bmp->header.bit_count/8;
	if((bmp_bpix != 3) && (bmp_bpix != 4))
	{
		printf("no support bmp picture without bpix 24 or 32\n");

		return -1;
	}
	if(bmp_bpix ==3)
	{
		zero_num = (4 - ((3*bmp->header.width) % 4))&3;
	}
	debug("bmp bitcount %d\n", bmp->header.bit_count);
	x = bmp->header.width;
	y = (bmp->header.height & 0x80000000) ? (-bmp->header.height):(bmp->header.height);
	printf("bmp x = %x, bmp y = %x\n", x, y);

	tmp_buffer = (char *)bmp_info->buffer;
	bmp_data = (char *)(addr + bmp->header.data_offset);
	if(bmp->header.height & 0x80000000)
    {
	      if(zero_num == 0)
                {
                    memcpy(tmp_buffer,bmp_data,x*y*bmp_bpix);
                }
                else
                {
                    int i, line_bytes, real_line_byte;
	            char *src;
	            line_bytes = (x * bmp_bpix) + zero_num;
		    real_line_byte = x * bmp_bpix;
		    for(i=0; i<y; i++)
                   {
             	    src = bmp_data + i*line_bytes;
                     memcpy(tmp_buffer, src, real_line_byte);
                    tmp_buffer += real_line_byte;
                    }
                }
    }
    else
    {
    	uint i, line_bytes, real_line_byte;
        char *src;

		line_bytes = (x * bmp_bpix) + zero_num;
		real_line_byte = x * bmp_bpix;
		for(i=0; i<y; i++)
        {
        	src = bmp_data + (y - i - 1) * line_bytes;
        	memcpy(tmp_buffer, src, real_line_byte);
            tmp_buffer += real_line_byte;
        }
    }
    bmp_info->x = x;
    bmp_info->y = y;
    bmp_info->bit = bmp->header.bit_count;
	flush_cache((uint)bmp_info->buffer, x * y * bmp_bpix);

  然后就是送到显示的地方了,因为解码buffer的地址是确定的,只要在显示layer的参数里挂上钩就可以了,申请layer,设置参数,打开layer,顺理成章!简单代码如下:

	debug("begin to set framebuffer\n");
	if(board_display_framebuffer_set(bmp_info.x, bmp_info.y, bmp_info.bit, (void *)bmp_info.buffer))
	{
		printf("sunxi bmp display error : set frame buffer error\n");

		return -2;
	}
	debug("begin to show layer\n");
	board_display_show(0);
	debug("bmp display finish\n");
	    board_display_layer_para_set();
		board_display_layer_open();

  整个流程确实就是这样的,有深度的地方就是把各个部分有机的串联起来,组织起来,不会做的事情都难,会做了的事情都不难!当然,我们不要在不懂的情况下就去评说这个事情难不难,难不难谁做谁知道!谦虚谨慎,低调潜行!
 

时间: 2024-07-28 12:25:09

uboot里开机LOGO显示功能解析的相关文章

uboot显示开机logo的问题

问题描述 uboot显示开机logo的问题 我在s3c6410中,uboot能显示一张160*96 没问题,但是当想要显示一张较大的logo时,uboot起不来,请各位大神指点一下,由于是新人,暂时没积分,先谢谢了

联想开机logo不见了的解决方法

联想开机logo不见了或消失怎么恢复?这虽然不是什么大问题,但有时叫人很不爽,下面是解决方法. 问题现象 :联想笔记本开机时的开机LOGO 没有了,开机不再显示品牌logo,而直接进入系统 几种处理方法介绍 : 升级或还原官方BIOS 固件 利用主板 或品牌官方提供的软件 DIY重新上传一个 BIOS LOGO就行了 BIOS菜单还原 或设置开启 下面以联想电脑做为例 正常情况下开机时的联想Logo 开机LOGO没有了 ,提示按F1进入 进入BIOS,Startup选项下的Boot Mode,如

Android MTK平台修改开机动画,开机logo

修改开机logo 找到目录 trunk/mediatek/custom/common/lk/logo/该目录下面有很多的文件夹,都是在不同分辨率下面的logo 要修改的话就看需要修改哪个分辨律下面的了,然后进入相应的目录下面,修改里面的图片,需要注意的是里面的图片必须是bmp格式的. 修改开机动画 需要进入目录trunk/frameworks/base/data/sounds/ 里面会看到一个压缩包bootanimation.zip,解压就会发现里面有两个文件夹和一个文本文件, 比如:文件夹pa

thinkphp-为什么在Thinkphp框架里html页面可以解析php代码

问题描述 为什么在Thinkphp框架里html页面可以解析php代码 今天使用框架发现了一个有趣的现象,在thinkphp框架里的.html文件内编写<?php.......?>代码能够直接解析. 但正常情况下,不都得是.php后缀的文件才能解析内部的<?php.......?>代码吗? 有没有人知道tp框架是怎么处理的? 解决方案 这个是因为think中有一个模板的解析器,你在模板中html里写的代码是要经过think的模板解析器转换成php文件然后再通过php输出浏览器. 也

大神帮忙解答一下这个json数据怎么在java里用json lib解析存放到List里

问题描述 大神帮忙解答一下这个json数据怎么在java里用json lib解析存放到List里 [ { "city": "", "citys": [ { "city": "北京", "id": 2, "level": 2, "province": "北京", "seq": 0, "x":

全志平台boot里TVD倒车显示功能开发

 全志平台boot里TVD倒车显示功能开发           倒车显示分两个部分,前端处理好视频输入信号,准备好内容,后端显示驱动再来把内容显示到LCD上.很明显,前端是TVD模块来处理的,后端是有DE模块来处理的,我们接下来先分析一下TVD模块怎么工作的.       首先,需要加载驱动打开设备驱动,如果有需要还可以执行IOCTL操作,跟在linux系统里操作驱动的IOCTL类似.代码如下: /*************************************************

跪求用VB或者C#获取outlook里的msg并解析里面的内容

问题描述 用VB或者C#获取outlook里的msg并解析里面的内容 解决方案 解决方案二:outlook是软件,接收的邮件有可能还在服务器上,有可能是读取到了本地,反正看你配置,至于读取msg,完全不明所以解决方案三:我现在的意思是比如我现在自己的电脑里有outlook,已经配置好了,我想用程序读取我这个帐号里的未读的邮件,提取里面的内容,应该怎么搞解决方案四:自己接收邮件就行了,为什么要绕一圈?解决方案五:可以用第三方LumiSoft.Net.dll,获取邮箱里面的信息!解决方案六:自己用第

联想台式或一体机,开机LOGO偏小怎么解决?

故障现象: 联想台式或一体机,BIOS设置为Win8模式时,联想开机LOGO图标较小:BIOS设置为Win7模式时,联想开机LOGO图标恢复正常,如何解决? 解决方案: 开机敲击F1键进入BIOS,光标移动到Startup项,选择至Quick Boot项并敲击回车,选择Disabled,点击F10键保存退出即可.     中文BIOS界面对照  

Android开机LOGO

Android 开机会出现3个画面:  1. Linux 系统启动,出现Linux小企鹅画面(reboot)(Android 1.5及以上版本已经取消加载图片):  2. Android平台启动初始化,出现"A N D R I O D"文字字样画面:  3. Android平台图形系统启动,出现含闪动的ANDROID字样的动画图片(start). 1.开机图片(Linux小企鹅) (Android 1.5及以上版本已经取消加载图片):  Linux Kernel引导启动后,加载该图片.