make
通过该步骤,我们在/$QTEDIR/lib/下生成了libqte.so、libqte.so.2、libqte.so.2.3和libqte.so.2.3.10这四个文件,我们可以使用file来查看这四个文件是不是我们开发板上要跑的库。
file libqte.so.2.3.10
libqte.so.2.3.10: ELF 32-bit LSB shared object, ARM, version 1 (ARM), stripped
如果出现了上述结果,则说明正确,将这四个文件通过NFS拷贝到开发板中。
在移植之前需要做一个修改:
将tmake中的…/lib/qws/linux-arm-g++/tmake.conf中的
TMAKE_LINK= arm-linux-gcc
TMAKE_LINK_SHLIB= arm-linux-gcc
修改为
TMAKE_LINK= arm-linux-g++
TMAKE_LINK_SHLIB= arm-linux-g++
这下子,我们可以在开发板上移植一下子Qt程序了。
编写一个Qt程序:hello.cpp。
progen -t app.t -o hello.pro。
tmake -o makefile hello.pro
make
在开发板中相应的位置处,运行./hello –qws。
注意在编译之前得确保TMAKEPATH的环境变量是:TMAKEPATH=…(tmake的路径)/lib/qws/linux-arm-g++;同时还要使用Qt/Embedded的路径令QTDIR=/……/qt-2.3.10。
(1)在qvfs中显示,每次都必须重新export好些环境变量设置,好麻烦!
export QT2DIR=/home/rock/pxa270Qt/qt-2.3.2
export QTEDIR=/home/rock/pxa270Qt/qt-2.3.10
export QTDIR=$QTEDIR
export PATH=$QTEDIR/bin:$PATH
export LD_LIBRARY_PATH=$QTEDIR/lib:$QT2DIR/lib:$LD_LIBRARY
#export TMAKEPATH=/usr/local/tmake-1.13/lib/qws/linux-x86-g++
解决方案:
方案一:重新在用户所在目录下,建立.bash_profile文件,将上述环境变量设置放在其中。该法案的缺点:每次重新启动shell时,都需要source .bash_profile。
方案二:将上述环境变量放在用户目录下的.profile文件中,修改完毕之后,利用source执行一下子,以后就可以不需要source命令,而生效。法案二为最终解决方案。
(2)如何在本地qt-creator上开发好了程序之后,然后在qvfb中显示呢?
解决方案:简单的程序,重新利用tmake生成.pro文件;再生成Makefile,然后make;最后在qvfb中显示。
但是,较为复杂的程序(由多个文件组成),如何在利用tmake来生成可以在qvfb中显示的二进制文件呢?
后者比较复杂:前提是必须将环境搭建好;采用批处理将所有文件中所包含的头文件用批处理来替换掉(统一小写,且后边带.h);用tmake先后生成.pro和Makefile文件,最后make。
需要注意的是:本地linux下边头文件后边不带.h,且大小写兼有,例如#include<QApplication>,利用qt-creator的qmake等编译工具可以顺利通过;而要在qvfb中显示时,用tmake,则make不能通过,会报错,其要求程序中头文件需要带.h,且全部为小写。
(3)在本机上运行的时候,总是出错?
如果想在本机的frame buffer上运行,本机系统需要支持framebuffer,如果系统用的是Xwindow,没有启动frame buffer,那么就又可能出错。
(4)编译完毕Qt/Embedded之后,在编译qt应用程序的时候,常常会出错。纵观起来,大多数是环境变量设置的问题。
帧缓冲设备提供了显卡的抽象描述。他同时代表了显卡上的显存,应用程序通过定义好的接口可以访问显卡,而不需要知道底层的任何操作。该设备使用特殊的设备节点,通常位于/dev目录,如/dev/fb*。
framebuffer相当于一个中间层,对驱动和硬件进行一个封装和管理,便于用户开发图形界面或进行视频输出操作。
(1)用户角度的/dev/fb*。从用户的角度看,帧缓冲设备和其他位于/dev下面的设备类似。他是一个字符设备,通常主设备号是29,次设备号定义帧缓冲的个数。
通常,使用如下方式(前面的数字代码次设备号)
0 = /dev/fb0 First frame buffer
1 = /dev/fb1 Second frame buffer
...
31 = /dev/fb31 32nd frame buffer
考虑到向下兼容,你可以创建符号链接:
/dev/fb0current -> fb0
/dev/fb1current -> fb1
and so on...
帧缓冲设备也是一种普通的内存设备,你可以读写其内容。例如,对屏幕抓屏:
cp /dev/fb0 myfile
你也可以同时有多个显示设备,例如你的主板上出了内置的显卡还有另一独立的显卡。对应的帧缓冲设备(/dev/fb0 and /dev/fb1 etc.)可以独立工作。
应用程序如 X server一般使用/dev/fb0作为默认的显示帧缓冲区。你可以自定把某个设备作为默认的帧缓冲设备,设置$FRAMEBUFFER环境变量即可。在sh/bash:
export FRAMEBUFFER=/dev/fb1
在csh中:
setenv FRAMEBUFFER /dev/fb1
设定后,X server将使用第二个帧缓冲区设备。
(2)程序员角度看/dev/fb*。正如你所知,一个帧缓冲设备和内存设备类似/dev/mem,并且有许多共性。你可以read,write,seek以及mmap()。不同仅仅是帧缓冲的内存不是所有的内存区,而是显卡专用的那部分内存。
/dev/fb*也允许尽行ioctl操作,通过ioctl可以读取或设定设备参数。颜色映射表也是通过Ioctl设定。查看<linux/fb.h>就知道有多少ioctl应用以及相关数据结构。
这里给出摘要:
① 你可以获取设备一些不变的信息,如设备名,屏幕的组织(平面,象素,...)对应内存区 的长度和起始地址。
②也可以获取能够发生变化的信息,例如位深,颜色格式,时序等。如果你改变这些值, 驱动程序将对值进行优化,以满足设备特性(返回EINVAL,如果你的设定,设备不支持)
③你也可以获取或设定部分颜色表。
所有这些特性让应用程序十分容易的使用设备。X server可以使用/dev/fb*而不需知道硬件的寄存器是如何组织的。 XF68_FBDev是一个用于位映射(单色)X server,唯一要做的就是在应用程序在相应的位置设定是否显示。
在新内核中,帧缓冲设备可以工作于模块中,允许动态加载。这类驱动必须调用register_framebuffer()在系统中注册。使用模块更方便!
(3)简单的说就是 你写到fb里面的数据会立刻以像素的方式显示到屏幕上,
你可以把一个位图文件copy到fb里面然后这个图像就会立刻显示到屏幕上。
很多图像库就是基于framebuffer的。
除了framebuffer还有xwindow 也可以做gui。
(4)Linux下的显卡驱动有两层, 一个是kernel层的也就是framebuffer驱动, 另一个是Xserver层驱动, 在进入X-windows之前是由framebuffer来驱动, 进入X-windows之后由XSERVER层的驱动作用(/etc/X11/xorg.conf中可以设置显卡等驱动), 当然如果你想要在X-WINDOWS上用framebuffer驱动也可以, 可以使用Xserver中的fbdev驱动, 这个驱动可以指定你要使用kernel层的framebuffer, 比如在xorg.conf中这样写
Section "Device"
Identifier "Videocard0"
Driver "fbdev"
VendorName "Videocard vendor"
BoardName "VESA driver (generic)"
BusID "PCI:0:14:0"
Option "fbdev" "/dev/fb1" #使用/dev/fb1这个framebuffer驱动
EndSection
(5) Framebuffer是在内核中,而Xwindows只不过是一个用户进程而已。我们的Gui如果想高效和移植性好那就直接和Framebuffer打交道就可以了。要是想简单点那就在XWindows上搭建自己的Gui。但是Xwindows也封装了外设的处理,如鼠标和键盘等。
如果读者先阅读完毕bufferframe杂谈,相信君会明白我们为什么要那么麻烦地去建立qvfb bufferframe模拟环境了。但是,一直笔者却甚感不爽。原因笔者以前一直是在xwindows下边进行的:qt-creator、Qdevelop以及eclipse中进行开发qt gui程序的,现在突然要脱离这些工具,而手工的在vim、gedit、emacs等编辑器下编写,众多不便,已经无法言谈。所以笔者还是在继续探索:能否在xwindows下的集成开发环境中做好程序,然后建立一个兼容集合开发环境代码(不需要改动,或做少许改动即可通过编译)的交叉编译环境,最后编译顺利通过,移植到开发板中…… 呵呵。