最近由于项目需要,要在blackfin 的bf548上运行minigui的图形应用程序。因此将minigui移植到了blackfin的uclinux上。minigui对blackfin的支持并不好,因此移植过程还颇费周折。
首先上minigui的官方网站 http://www.minigui.org/res.shtml 上下载最新的GPL版本 1.6.10,需要的文件如下:
1、编译 libminigui-1.6.10
这是minigui的核心,编译过程如下:
说明一下:
- 我在Fedora 9上直接编译的时候编译是通不过的,原因是minigui即使是最新的版本,仍然在使用较旧的autoconf / automake套件,因此无法正确的交叉编译blackfin的程序。需要将本机的automake所带的config.sub拷贝到libminigui目录下替换原来的文件。
- 还是minigui对blackfin的支持不够好,不能正确识别CPU的大小端。因此需要加上-D__LITTLE_ENDIAN__来显式的指明其为小端,否则在读取资源文件时会出现文件不能正确读取的问题。
2、安装资源文件
将文件 minigui-res-1.6.10.tar.gz 解压出来后make install就可以了,要说明的是如果安装目录不是/usr/local/目录下的话(对于嵌入式系统似乎从来就不应该安装在/usr/loca目录下),就需要修改config.linux文件,将安装目录改正到需要的目录。
3、编译mde-1.6.10
OK,编译完成。
3、运行
编译完成后在开发板上运行demo程序,并没有预期的图形用户界面出现,而是出现如下错误:
从错误信息来看是由于未对齐访问内存所导致的。由于 blackfin 不允许未对齐的内存访问,对32位的blackfin bf548来说,未对齐的内存访问包括16位字操作时地址没有按2字对齐,32位的内存操作时没有按4字节对齐,而对于字节访问来说,就对地址没有什么要求。
知道了错误的原因,现在要找到出错的代码所在的行。上面的错误信息给出了出错误时的程序指针PC的值,因此可以根据该值来确定出错代码所在的位置。
错误信息
PC : <0x030afbce> [ /usr/local/lib/libminigui-1.6.so.10.0.0 + 0xafbce ]
指出出错代码位于/usr/local/lib/libminigui-1.6.so.10.0.0的偏移0xafbce处。
使用readelf命令在libminigui-1.6.so.10.0.0中读取符号信息:
[xhs@watsonxu lib]$ readelf -s libminigui-1.6.so.10.0.0 | grep 000afb
1122: 000afbf4 650 FUNC GLOBAL DEFAULT 10 __begin_fill_bitmap
9083: 000afb40 72 FUNC LOCAL DEFAULT 10 _MGUI_ReadLE16Mem
9084: 000afb88 106 FUNC LOCAL DEFAULT 10 __mem_set_pixel
10488: 000afbf4 650 FUNC GLOBAL DEFAULT 10 __begin_fill_bitmap
上面的代码可以看出,出错的代码应该位于 _mem_set_pixel 函数处,找到 _mem_set_pixel 函数的定义处 src/include/dc.h
由于blackfin BF548-EZKIT开发板使用了24位的LCD显示屏,因此对应于此处的bpp就为3,即
case 3:
*(Uint16 *) dst = pixel; //此处使用了16位的内存访问,并导致了内存访问未对齐。
*(dst + 2) = pixel >> 16;
break;
很明显,按照24位显存的组织方式,dst这个地址是可能出现未对齐到16位字的。
找到了问题的所在,解决起来相对就容易了,将16位的内存访问改成两个8位的内存访问就可以了。修正如下:
case 3:
*dst = pixel & 0xFF;
*(dst + 1) = pixel >> 8;
*(dst + 2) = pixel >> 16;
break;
重新编译,运行,还有多处类似的错误出现,同样的方法全部改正后运行,终于出现了预期的图形用户界面了。
此外,在输入法模块中也有未对齐的内存访问,主要是在读文件时有未对齐的内存访问,暂时禁用输入法模块解决,留待以后解决。