本文转载自:http://blog.csdn.net/u010865783/article/details/54953315

在lcd为竖屏,hdmi显示横屏的情况下,如果按照默认的uboot显示框架来看,只能保证lcd或者hdmi上面显示出来的图片一个是正的,另外一个是旋转了90度的样子。 
为了能是lcd和hdmi同时支持显示图片都是正的,需要对uboot的框架做修改。如果硬件支持旋转功能的话,就可直接使用硬件旋转,不需要软件来调整。 
由于项目原因,折腾了一把这个流程,具体实现记录下: 
1:由于硬件不支持rotation功能,在软件上采用的方法是准备两份logo资源,解析后将两份数据送到不同的显示设备上面做显示。 
在解析logo的时候需要解析两份资源:

static int splash_image_load(void)
{
int ret;
char *filename,*filename_hdmi;
void *splash_image_addr,*splash_image_hdmi_addr;
char splash_image_char[16], splash_image_hdmi_char[16];
//分配给lcd资源的地址
splash_image_addr = memalign(128, CONFIG_SYS_VIDEO_LOGO_MAX_SIZE);
if(splash_image_addr == NULL) {
printk("Malloc size for splash image failed!\n");
return -1;
}
//分配给hdmi资源logo的地址
splash_image_hdmi_addr = memalign(128, CONFIG_SYS_VIDEO_LOGO_MAX_SIZE);
if(splash_image_hdmi_addr == NULL) {
printk("Malloc size for splash image hdmi failed!\n");
return -1;
} filename = splash_image_select();
filename_hdmi = CONFIG_SYS_VIDEO_LOGO_HDMI_NAME;
if (!filename) {
printk("No splash image loaded\n");
return -1;
}
//拿到lcd的logo
ret = file_fat_read(filename, splash_image_addr, CONFIG_SYS_VIDEO_LOGO_MAX_SIZE); if(ret < 0) {
printk("Fail to load splash image\n");
free(splash_image_addr);
return -1;
}
//拿到hdmi的logo
ret = file_fat_read(filename_hdmi, splash_image_hdmi_addr, CONFIG_SYS_VIDEO_LOGO_MAX_SIZE);
if(ret < 0) {
printk("Fail to load splash hdmi image\n");
free(splash_image_hdmi_addr);
return -1;
}
sprintf(splash_image_char, "%x", (unsigned int) splash_image_addr);
sprintf(splash_image_hdmi_char, "%x", (unsigned int) splash_image_hdmi_addr);
//将解析到的地址保存到env中,后续需要再读取出来
setenv("splashimage", splash_image_char);
setenv("splashimagehdmi", splash_image_hdmi_char);
return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47

2:添加对hdmi驱动中的支持和在cfb_console.c中添加解析图片的支持

static int video_init(void)
{
unsigned char color8; pGD = video_hw_init();
if (pGD == NULL)
return -1;
//获取驱动中的hdmi的fb的信息video_hw_hdmi_init在fb的驱动中实现
pGD_HDMI = video_hw_hdmi_init();
if (pGD_HDMI == NULL)
return -1;
...
} static void *video_logo(void)
{
char info[128];
int space, len;
__maybe_unused int y_off = 0;
__maybe_unused ulong addr;
__maybe_unused char *s,*s_hdmi; splash_get_pos(&video_logo_xpos, &video_logo_ypos); //splash_get_pos(&video_logo_xpos, &video_logo_ypos);
video_hdmi_logo_xpos = BMP_ALIGN_CENTER; //init xpos and ypos
video_hdmi_logo_ypos = BMP_ALIGN_CENTER; #ifdef CONFIG_SPLASH_SCREEN
//从env中拿到lcd和hdmi图片的地址
s = getenv("splashimage");
s_hdmi = getenv("splashimagehdmi"); if (s != NULL) {
splash_screen_prepare();
addr = simple_strtoul(s, NULL, 16);
//解析lcd的logo资源成送显的数据
if (video_display_bitmap(addr,
video_logo_xpos,
video_logo_ypos) == 0) {
video_logo_height = 0;
//return ((void *) (video_fb_address));
}
} if (s_hdmi != NULL) {
//printf("xieshsh debug video display\n");
splash_screen_prepare();
addr = simple_strtoul(s_hdmi, NULL, 16);
//解析lcd的hdmi资源成送显的数据
if (video_display_hdmi_bitmap(addr,
video_hdmi_logo_xpos,
video_hdmi_logo_ypos) == 0) {
video_hdmi_logo_ypos = 0;
return ((void *) (video_fb_address));
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58

3:接下来需要对添加对hdmi logo的解析成fb的数据

int video_display_hdmi_bitmap(ulong bmp_image, int x, int y)
{
ushort xcount, ycount;
uchar *fb;
bmp_image_t *bmp = (bmp_image_t *) bmp_image;
uchar *bmap;
ushort padded_line;
unsigned long width, height, bpp;
unsigned colors;
unsigned long compression;
bmp_color_table_entry_t cte; #ifdef CONFIG_VIDEO_BMP_GZIP
unsigned char *dst = NULL;
ulong len;
#endif WATCHDOG_RESET(); if (!((bmp->header.signature[0] == 'B') &&
(bmp->header.signature[1] == 'M'))) { #ifdef CONFIG_VIDEO_BMP_GZIP
/*
* Could be a gzipped bmp image, try to decrompress...
*/
len = CONFIG_SYS_VIDEO_LOGO_MAX_SIZE;
dst = malloc(CONFIG_SYS_VIDEO_LOGO_MAX_SIZE);
if (dst == NULL) {
printf("Error: malloc in gunzip failed!\n");
return 1;
}
/*
* NB: we need to force offset of +2
* See doc/README.displaying-bmps
*/
if (gunzip(dst+2, CONFIG_SYS_VIDEO_LOGO_MAX_SIZE-2,
(uchar *) bmp_image,
&len) != 0) {
printf("Error: no valid bmp or bmp.gz image at %lx\n",
bmp_image);
free(dst);
return 1;
}
if (len == CONFIG_SYS_VIDEO_LOGO_MAX_SIZE) {
printf("Image could be truncated "
"(increase CONFIG_SYS_VIDEO_LOGO_MAX_SIZE)!\n");
} /*
* Set addr to decompressed image
*/
bmp = (bmp_image_t *)(dst+2); if (!((bmp->header.signature[0] == 'B') &&
(bmp->header.signature[1] == 'M'))) {
printf("Error: no valid bmp.gz image at %lx\n",
bmp_image);
free(dst);
return 1;
}
#else
printf("Error: no valid bmp image at %lx\n", bmp_image);
return 1;
#endif /* CONFIG_VIDEO_BMP_GZIP */
} width = le32_to_cpu(bmp->header.width);
height = le32_to_cpu(bmp->header.height);
bpp = le16_to_cpu(bmp->header.bit_count);
colors = le32_to_cpu(bmp->header.colors_used);
compression = le32_to_cpu(bmp->header.compression); debug("Display-bmp: %ld x %ld with %d colors\n",
width, height, colors); if (compression != BMP_BI_RGB
#ifdef CONFIG_VIDEO_BMP_RLE8
&& compression != BMP_BI_RLE8
#endif
) {
printf("Error: compression type %ld not supported\n",
compression);
#ifdef CONFIG_VIDEO_BMP_GZIP
if (dst)
free(dst);
#endif
return 1;
} padded_line = (((width * bpp + 7) / 8) + 3) & ~0x3;
#ifdef CONFIG_SPLASH_SCREEN_ALIGN
if (x == BMP_ALIGN_CENTER){
x = max(0, (int)(VIDEO_HDMI_VISIBLE_COLS - width) / 2);
printf("VVVVVVVVx=%d",x);
}
else if (x < 0)
x = max(0, (int)(VIDEO_HDMI_VISIBLE_COLS - width + x + 1)); if (y == BMP_ALIGN_CENTER)
y = max(0, (int)(VIDEO_HDMI_VISIBLE_ROWS - height) / 2);
else if (y < 0)
y = max(0, (int)(VIDEO_HDMI_VISIBLE_ROWS - height + y + 1));
#endif /* CONFIG_SPLASH_SCREEN_ALIGN */ /*
* Just ignore elements which are completely beyond screen
* dimensions.
*/ if ((x >= VIDEO_HDMI_VISIBLE_COLS) || (y >= VIDEO_HDMI_VISIBLE_ROWS))
return 0; if ((x + width) > VIDEO_HDMI_VISIBLE_COLS)
width = VIDEO_HDMI_VISIBLE_COLS - x;
if ((y + height) > VIDEO_HDMI_VISIBLE_ROWS)
height = VIDEO_HDMI_VISIBLE_ROWS - y; bmap = (uchar *) bmp + le32_to_cpu(bmp->header.data_offset);
fb = (uchar *) (video_hdmi_fb_address +
((y + height - 1) * VIDEO_HDMI_VISIBLE_COLS * VIDEO_HDMI_PIXEL_SIZE) +
x * VIDEO_HDMI_PIXEL_SIZE); /* We handle only 4, 8, or 24 bpp bitmaps */ switch (le16_to_cpu(bmp->header.bit_count)) { case 24:
padded_line -= 3 * width;
ycount = height;
//printf("xiessh----VIDEO_DATA_FORMAT = %d\n",VIDEO_HDMI_DATA_FORMAT);
switch (VIDEO_HDMI_DATA_FORMAT) {
case GDF_32BIT_X888RGB:
while (ycount--) {
WATCHDOG_RESET();
xcount = width;
while (xcount--) {
FILL_32BIT_X888RGB(bmap[2], bmap[1],
bmap[0]);
bmap += 3;
}
bmap += padded_line;
fb -= (VIDEO_HDMI_VISIBLE_COLS + width) *
VIDEO_PIXEL_SIZE;
}
break; default:
printf("Error: 24 bits/pixel bitmap incompatible "
"with current video mode\n");
break;
}
break;
default:
printf("Error: %d bit/pixel bitmaps not supported by U-Boot\n",
le16_to_cpu(bmp->header.bit_count));
break;
} #ifdef CONFIG_VIDEO_BMP_GZIP
if (dst) {
free(dst);
}
#endif if (cfb_do_flush_cache)
flush_cache(VIDEO_FB_ADRS, VIDEO_SIZE);
return (0);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169

实现了上面的内容之后,接下来需要在uboot的fb中做好映射,主要是将fb0对应的logo的资源送到lcd、fb1对应的logo资源送到hdmi显示,具体的代码和平台相关。

这样造成的影响是会使uboot阶段显示的内存增加一倍,之前只用了一个图片,现在用到了两个图片,所以内存会增加一倍。

当android系统起来的时候,因为lcd是竖屏,lcd上面的内容旋转了90度当成了横屏模式在使用,hdmi是横屏,会造成android动画的前半段在hdmi上面显示的android字样变成了垂直显示,知道android的display的java服务启动之后,android的显示系统识别到了hdmi设备,系统才显示正常。

对于这种情况,hdmi的前半段的异常显示,由于硬件无法rotation,只能采取一个规避的方式解决,将开机启动的logo一直保存到android上层的显示系统识别到hdmi后,才释放boot logo的资源,在这个之前,一直都显示logo的图片。具体的实现方式和平台相关,代码就不贴了。

Uboot中支持lcd和hdmi显示不同的logo图片【转】的更多相关文章

  1. U-Boot中支持USB

    转载: http://blog.csdn.net/qiurihuanghua/article/details/6234832 今天查看了一下在P4080DS板子的U-Boot中支持USB,主要是加入U ...

  2. 七、在U-boot中让LCD显示图片

    1. 增加Nandflash读取代码 因为要显示图片,而图片明显是放在Nandflash中比较合适,因此需要有能够操作Nandflash的函数.在U-boot中已经有能操作Nandflash的函数了, ...

  3. uboot中关于LCD的代码分析【转】

    本文转载自:http://blog.csdn.net/oqqHuTu12345678/article/details/72236117 以下内容源于朱有鹏<物联网大讲坛>课程的学习,如有侵 ...

  4. 六、在U-boot中让LCD填充纯色

    1. 编译U-boot 准备好U-boot压缩包urbetter-u-boot-1.1.6-v1.0.tgz,输入命令:tar -xvf urbetter-u-boot-1.1.6-v1.0.tgz ...

  5. u-boot支持LCD显示(基于TQ2440)

    平台简介 Linux版本:Linux-3.14 u-boot版本:u-boot-2015.04 硬件:TQ2440(内存:64MB  NandFlash:256MB) 作者:彭东林 邮箱:pengdo ...

  6. u-boot支持LCD显示(基于TQ2440)【转】

    本文转载自:http://www.cnblogs.com/pengdonglin137/p/4633877.html u-boot支持LCD显示(基于TQ2440)   阅读目录(Content) 平 ...

  7. u-boot中添加mtdparts支持以及Linux的分区设置

    简介 作者:彭东林 邮箱:pengdonglin137@163.com u-boot版本:u-boot-2015.04 Linux版本:Linux-3.14 硬件平台:tq2440, 内存:64M   ...

  8. 东芝开发板驱动OLED模块显示LOGO图片

    前言 在之前的两篇评测文章: 使用系统定时器SysTick实现精确延时微秒和毫秒函数 东芝MCU实现位带操作 介绍了系统SysTick实现精确延时,GPIO的输入输出使用,并实现了位带方式操作GPIO ...

  9. 关于Yaffs2在u-boot中的支持

    开发板是一块2G的MLC的NandFlash,页大小8k+512,为其移植u-boot到yaffs2这了.以前在Mini2440上移植过2k+64的slc的NandFlash的Yaffs2支持,当然也 ...

随机推荐

  1. P1538 迎春舞会之数字舞蹈

    题目背景 HNSDFZ的同学们为了庆祝春节,准备排练一场舞会. 题目描述 在越来越讲究合作的时代,人们注意的更多的不是个人物的舞姿,而是集体的排列. 为了配合每年的倒计时,同学们决定排出——“数字舞蹈 ...

  2. 既可以输入也可以选择的input框

    datalist 是h5中既可以选择也可以输入的属性 具体代码如下 <input list="datalist"/><datalist id="data ...

  3. 超经典~超全的jQuery插件大全

    海量的jQuery插件帖,很经典,不知道什么时候开始流传,很早以前就收藏过,为了工作方便还是发了一份放在日志里面. 其中有些已经无法访问,或许是文件移除,或许是被封锁.大家分享的东西,没什么特别的可说 ...

  4. oracle for linux服务器磁盘空间不足,通过过期的文件释放磁盘空间

    --2013-09-16截取的数据-- 使用df-h命令查看系统磁盘空间 [root@erpdbs PROD]# df -h Filesystem Size Used Avail Use% Mount ...

  5. JS高级——作用域链

    基本概念 1.只要是函数就可以创造作用域 2.函数中又可以再创建函数 3.函数内部的作用域可以访问函数外部的作用域 4.如果有多个函数嵌套,那么就会构成一个链式访问结构,这就是作用域链 <scr ...

  6. post发送 ArrayBuffer

    // 用 POST 方法将 ArrayBuffer 发送到服务器 ); var longInt8View = new Uint8Array(myArray); ; i< longInt8View ...

  7. Linux 通过cksum 来判断文件是否是相同

    1. 最近scp部署文件时 发现日期会发生变化 (刚查了下 可以使用 -p 命令进行处理) 会变成部署时的日期. 不好判断文件倒是有没有部署 2. 最简单的办法 我mount了 补丁服务器  到lin ...

  8. privot函数使用

    语法: table_source PIVOT( 聚合函数(value_column) FOR pivot_column IN(<column_list>) ) 将列转化为行 写个小示例 : ...

  9. ie9以下提示用户升级浏览器

    <!--[if lt IE 9]> <div style='border: 4px solid #FFF500; background: #FDFDC8; text-align: c ...

  10. JS数组reduce()方法

    1.语法 arr.reduce(callback,[initialValue]) reduce 为数组中的每一个元素依次执行回调函数,不包括数组中被删除或从未被赋值的元素,接受四个参数:初始值(或者上 ...