Uboot中支持lcd和hdmi显示不同的logo图片【转】
本文转载自: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图片【转】的更多相关文章
- U-Boot中支持USB
转载: http://blog.csdn.net/qiurihuanghua/article/details/6234832 今天查看了一下在P4080DS板子的U-Boot中支持USB,主要是加入U ...
- 七、在U-boot中让LCD显示图片
1. 增加Nandflash读取代码 因为要显示图片,而图片明显是放在Nandflash中比较合适,因此需要有能够操作Nandflash的函数.在U-boot中已经有能操作Nandflash的函数了, ...
- uboot中关于LCD的代码分析【转】
本文转载自:http://blog.csdn.net/oqqHuTu12345678/article/details/72236117 以下内容源于朱有鹏<物联网大讲坛>课程的学习,如有侵 ...
- 六、在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 ...
- u-boot支持LCD显示(基于TQ2440)
平台简介 Linux版本:Linux-3.14 u-boot版本:u-boot-2015.04 硬件:TQ2440(内存:64MB NandFlash:256MB) 作者:彭东林 邮箱:pengdo ...
- u-boot支持LCD显示(基于TQ2440)【转】
本文转载自:http://www.cnblogs.com/pengdonglin137/p/4633877.html u-boot支持LCD显示(基于TQ2440) 阅读目录(Content) 平 ...
- u-boot中添加mtdparts支持以及Linux的分区设置
简介 作者:彭东林 邮箱:pengdonglin137@163.com u-boot版本:u-boot-2015.04 Linux版本:Linux-3.14 硬件平台:tq2440, 内存:64M ...
- 东芝开发板驱动OLED模块显示LOGO图片
前言 在之前的两篇评测文章: 使用系统定时器SysTick实现精确延时微秒和毫秒函数 东芝MCU实现位带操作 介绍了系统SysTick实现精确延时,GPIO的输入输出使用,并实现了位带方式操作GPIO ...
- 关于Yaffs2在u-boot中的支持
开发板是一块2G的MLC的NandFlash,页大小8k+512,为其移植u-boot到yaffs2这了.以前在Mini2440上移植过2k+64的slc的NandFlash的Yaffs2支持,当然也 ...
随机推荐
- Angular——表单指令
基本介绍 这些指定只能针对input标签 基本使用 <!DOCTYPE html> <html lang="en"> <head> <me ...
- JS——旋转木马
1.opacity和zIndex的综合运用 2.样式的数组的替换:向右边滑动---删除样式数组第一位并在数组最后添加:向左边滑动---删除样式数组最后一位并在数组前添加 3.开闭原则,只有当回调函数执 ...
- git使用原理
如果需要新建仓库: mkdir new_artcle//artcle为文件名 cd new_artcle//进入该目录 git init //初始化工作空间 git add 文件名(article) ...
- haproxy故障处理
1. haproxy 在配置健康检查的时候,默认没有配置页面检查 ,通过端口状态来检测.后端IIS web服务开始可能 是一个站点,或者采用了基于域名的配置方式,导致目前站点停了,后端主机不能被hap ...
- Centos6.6 安装nfs网络文件系统
一.介绍 nfs网络文件系统的,大部分用在内网文件共享,比如,对集群上传文件做共享,经常用在图片部分,当然数据量大了还是要做分离,做为专门的接口比较好,介绍一下基本安装环境: 1)Cnetos6.6 ...
- Apache 在Linux上的安装
1.获取源码 wget http://mirror.bit.edu.cn/apache//httpd/httpd-2.4.37.tar.gz 2.卸载centos自带的apache 3.解压apach ...
- Ubuntu 18.04 如何固定图标到任务栏
参考 https://blog.csdn.net/u014160286/article/details/81631863
- 微信小程序——weui的使用
使用在根目录中复制weui.wxss,app.wxss中引入 在weui.io中查看到自己想要的样式表后,到第二个网站复制代码,复制到自己的项目中即可 <!--pages/register/re ...
- 考试T1总结(又CE?!)
考试T1CE... 最近不适合考试 T1 扶苏是个喜欢一边听古风歌一边写数学题的人,所以这道题其实是五三原题.歌曲中的主人公看着墙边的海棠花,想起当年他其实和自己沿着墙边种了一排海棠,但是如今都已枯萎 ...
- 解决Scrapy抓取中文网页保存为json文件时中文不显示而是显示unicode的问题
注意:此方法跟之前保存成json文件的写法有少许不同之处,注意区分 情境再现: 使用scrapy抓取中文网页,得到的数据类型是unicode,在控制台输出的话也是显示unicode,如下所示 {'au ...