CFE文件内嵌bmp图像并显示
来源:互联网 发布:webmethod 返回json 编辑:程序博客网 时间:2024/04/30 06:33
1. CFE
中的splash
CFE
启动后,初始化各种设备,然后初始化显示相关的寄存器,从flash
中读取图片splash.bmp
并绘制到surface memory
区域。
由于splash
存放在flash
的分区中,所以必须要等待flash
驱动完成初始化后,读取出图像splash.bmp
才能显示。
那如果想CFE
一启动就显示splash
呢?显然最好是将splash.bmp
嵌入到代码中。
本文基于机顶盒上使用的CFE v15.2
版本将splash.bmp
编译嵌入到cfe.bin
中,并在启动时显示图像。
2. 生成可连接的目标文件splash.bmp.o
GNU binutils
的objcopy
工具用途比较广泛,其中一项就是各种目标文件之间的转换。
因此使用objcopy
可以将任意文件转换为可以连接的目标文件,参与生成最终的可以执行文件。
2.1 sde-objcopy
CFE
编译使用MIPS
提供的工具套件MIPS SDE v5.03
,这是一个相当老的工具套件了,gcc
版本只有2.96
,objcopy
版本为2.9
,如下:
ygu@ubuntu:/opt/cfe_v15.2$ sde-gcc -vReading specs from /opt/toolchains/sde-v5.03/bin/../lib/gcc-lib/sde/2.96-mipssde-031117/specsgcc version 2.96-mipssde-031117ygu@ubuntu:/opt/cfe_v15.2$ sde-objcopy -VGNU objcopy 2.9-mipssde-031003Copyright 1997, 98, 99, 2000 Free Software Foundation, Inc.This program is free software; you may redistribute it under the terms ofthe GNU General Public License. This program has absolutely no warranty.
对于sde-objcopy
甚至还不支持-B
选项,我曾经尝试用sde-objcopy
去转换splash.bmp
,但最终都失败了。最后手动用编译应用的mipsel-linux-objcopy
将splash.bmp
转换为可连接的目标文件splash.bmp.o
后,再将这个可连接文件用于最终CFE
的生成。
2.2 使用mipsel-linux-objcopy
工具进行转换
2.2.1 -B mipsisa32
选项
转换命令如下(此处使用的是stbgcc-4.5.4-2.9
包中的objcopy
):
ygu@ubuntu:/opt/cfe_v15.2$ mipsel-linux-objcopy -I binary -O elf32-tradlittlemips -B mipsisa32 splash.bmp splash.bmp.o
用file
命令查看生成的可连接文件:
ygu@ubuntu:/opt/cfe_v15.2$ file splash.bmp.o splash.bmp.o: ELF 32-bit LSB relocatable, MIPS, MIPS32 version 1 (SYSV), not stripped
再用file
查看下cfe
编译生成的其它文件,如cfe_main.o
:
ygu@ubuntu:/opt/cfe_v15.2/build/7584$ file cfe_main.ocfe_main.o: ELF 32-bit LSB relocatable, MIPS, MIPS32 version 1 (SYSV), not stripped
可见手动生成的splash.bmp.o
和cfe_main.o
格式是一致的。
2.2.2 -B mips
选项
如果objcopy
使用-B mips
而不是-B mipsisa32
选项进行转换,则由于指定cpu
架构不一致而存在问题。
ygu@ubuntu:/opt/cfe_v15.2$ mipsel-linux-objcopy -I binary -O elf32-tradlittlemips -B mips splash.bmp splash.bmp.oygu@ubuntu:/opt/cfe_v15.2$ file splash.bmp.o splash.bmp.o: ELF 32-bit LSB relocatable, MIPS, MIPS-I version 1 (SYSV), not stripped
仔细查看file
命令的输出,这里生成的是MIPS-I version 1
的格式,跟CFE
原生编译生成的格式不一样。
2.3 使用nm
工具检查符号
使用objcopy
工具生成的可连接文件objfile
会内置三个位置相关的符号变量_binary_objfile_start
, _binary_objfile_end
和_binary_objfile_size
,可以用nm
工具查看。
这里使用mipsel-linux-nm
检查生成文件splash.bmp.o
中的符号:
ygu@ubuntu:/opt/cfe_v15.2$ mipsel-linux-nm -a splash.bmp.o 00000000 d .data0006b892 D _binary_splash_bmp_end0006b892 A _binary_splash_bmp_size00000000 D _binary_splash_bmp_start
可见生成了三个符号变量,名字也很直观:
+ _binary_splash_bmp_start
指示bmp
数据开始的位置
+ _binary_splash_bmp_end
指示bmp
数据结束的位置
+ _binary_splash_bmp_size
指示bmp
数据的大小
3. CFE
链接splash.bmp.o
将生成的splash.bmp.o
放到splash
目录下,然后在编译系统中添加对splash.bmp.o
的编译引用:
3.1 链接splash.bmp.o
生成ssbl
在cfe_link.mk
文件中修改ssbl
的生成规则,让其链接splash.bmp.o
:
ssbl ssbl.bin: $(DEV_OBJS) $(COMMON_OBJS) $(ECM_OBJS) $(LIBCFE) splash.bmp.o $(GLD) -o ssbl -Map ssbl.map $(SSBL_LDFLAGS) -L. $(DEV_OBJS) $(COMMON_OBJS) $(ECM_OBJS) splash.bmp.o -lcfe $(LDLIBS)
3.2 复制splash.bmp.o
到编译目录
3.1节中指定的splash.bmp.o
默认的位置在build/7xxx
下,即跟编译生成的文件在同一个地方,但我们预先生成了splash.bmp.o
,所以还需要添加规则将splash.bmp.o
从splash
目录复制到当前目录来。
在cfe.mk
中添加这个规则:
# copy splash/splash.bmp.o to build dirsplash.bmp.o : ../../splash/splash.bmp.o @echo 'copy $(notdir $<)' @cp -rf $< $@
添加以上两个规则后,就可以顺利将splash.bmp.o
嵌入到生成的cfe.bin
中了。
3.3 编译时生成`splash.bmp.o
如果预先设置了mipsel-linux-objcopy
的路径也可以在编译时才生成splash.bmp.o
,则cfe.mk
中生成splash.bmp.o
的规则如下:
splash.bmp.o : splash.bmp @echo 'mipsel-linux-objcopy $(notdir $<)' @mipsel-linux-objcopy -I binary -O elf32-tradlittlemips -B mipsisa32 $^ $@
4. CFE
中引用splash.bmp.o
的数据
默认情况下,CFE
的cfe_splash
函数会先从flash
中读取图片,然后再显示。
这里我们对这个函数稍作修改,使其直接显示cfe.bin
中内嵌的图片,修改如下:
(cfe_main.c
中的cfe_splash
函数)
/* 声明splash.bmp.o中的位置相关的外部变量 */extern unsigned long _binary_splash_bmp_start;extern unsigned long _binary_splash_bmp_end;extern unsigned long _binary_splash_bmp_size;void cfe_splash(){ BMP_HEADER_INFO bmpinfo[2]; int x,y; void *surfaceMemory[2]; void *bmpMemory[2]; int ii; /* PORT POINT: if you have more than 2 surfaces */ surfaceMemory[0] = (void *)PHYS_TO_K0(SURFACE_MEM_ADDRS); surfaceMemory[1] = (void *)PHYS_TO_K0(SURFACE_MEM_ADDRS_1); /* 直接引用bmp数据的起始地址 */ bmpMemory[0] = (void *)&_binary_splash_bmp_start;; bmpMemory[1] = (void *)&_binary_splash_bmp_start;; for(ii=0; ii<g_ulNumSurface; ii++) { /* 解析bmp头部结构,获取bmp图片信息 */ if(splash_bmp_getinfo(bmpMemory[ii], &bmpinfo[ii]) != 0 || bmpinfo[ii].header.size > SPLASH_IMAGE_SIZE || bmpinfo[ii].header.offset > SPLASH_HDR_SIZE) { if (ii == 0) { xprintf("No valid image found in " SPLASH_IMAGE_FILE " - disabling splash\n"); return ; } else { bmpinfo[ii] = bmpinfo[0]; } } /* 输出bmp的一些调试信息 */ xprintf("Found splash image %d - Width = %d Height = %d at: [0x%08x - 0x%08x, %d bytes]\n", ii, bmpinfo[ii].info.width, bmpinfo[ii].info.height, (unsigned long *)&_binary_splash_bmp_start, (unsigned long *)&_binary_splash_bmp_end, (unsigned long)&_binary_splash_bmp_size);#ifdef SPLASH_SURFACE_SELECT_ENABLED surfaceMemory[ii] = g_pvSplashSurfaceAddr[ii];#endif BMEM_ConvertAddressToOffset(NULL, surfaceMemory[ii], &g_SplashInfo.aulSurfaceBufOffset[ii]); } splash_bvn_init(NULL, &g_SplashInfo); /* 以下部分没有修改,同原函数 */ ...}
修改后编译生成cfe.bin
,烧写到机顶盒上就可以在开机启动时显示内嵌到cfe
里面的图像数据。
5. 其它
不仅可以转换图片数据,objcopy
还可以将任何格式的文件转换为可连接的目标文件,如字体、固件等,比较灵活也比较方便。
- CFE文件内嵌bmp图像并显示
- VC/MFC读取BMP文件并显示
- VC 创建BMP文件并显示
- 【OPENGL】读取并显示BMP文件
- MFC显示bmp图像
- 获取当前屏幕图像并保存为bmp文件
- OpenCV显示摄像头图像保存成bmp文件
- 黑白BMP文件的读写和数据黑白图像显示
- 通过修改CFE文件里的vlan设置,并telnet刷新CFE,改造WAN口坏的WRT310N V2
- 利用opengl将3ds文件导入场景并显示,然后保存这个场景为bmp格式图像,其结果与显示不同,问题出在哪儿了
- VC打开并缩放显示位图(.BMP)文件的方法
- 显示BMP文件
- OpenGL BMP文件显示
- CStatic显示bmp文件
- DirectShow中利用SampleGrabber捕获摄像头每一帧图像,并转为BMP文件信息写入内存
- DirectShow中利用SampleGrabber捕获摄像头每一帧图像,并转为BMP文件信息写入内存
- DirectShow中利用SampleGrabber捕获摄像头每一帧图像,并转为BMP文件信息写入内存
- 如何把位图读入内存中并显示?实现从打包文件中读取bmp文件并显示!
- Android端外推送到底有多烦?
- Java IO流——序列化的基本操作
- python 抓取网页内容
- kafka搭建
- c++详解【new和delete】
- CFE文件内嵌bmp图像并显示
- 排序算法之归并排序
- Android进程保活招式大全
- Jenkins 配置邮件通知
- 里氏替换原则
- [LeetCode]Subsets
- 算法学习笔记之均值滤波法
- 设置EditText设置为两位小数,或者其他位数
- python虚拟环境搭建