概述
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 %sn", 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 picturen");
return -1;
}
debug("bmp dectecen");
bmp_bpix = bmp->header.bit_count/8;
if((bmp_bpix != 3) && (bmp_bpix != 4))
{
printf("no support bmp picture without bpix 24 or 32n");
return -1;
}
if(bmp_bpix ==3)
{
zero_num = (4 - ((3*bmp->header.width) % 4))&3;
}
debug("bmp bitcount %dn", 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 = %xn", 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 framebuffern");
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 errorn");
return -2;
}
debug("begin to show layern");
board_display_show(0);
debug("bmp display finishn");
board_display_layer_para_set();
board_display_layer_open();
整个流程确实就是这样的,有深度的地方就是把各个部分有机的串联起来,组织起来,不会做的事情都难,会做了的事情都不难!当然,我们不要在不懂的情况下就去评说这个事情难不难,难不难谁做谁知道!谦虚谨慎,低调潜行!
最后
以上就是土豪西装为你收集整理的uboot里开机LOGO显示功能解析的全部内容,希望文章能够帮你解决uboot里开机LOGO显示功能解析所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复