注:以下文章出自 "电子商务月刊",作者:李占岭
原文地址: http://www.ebjournal.info/news_Show_jou.asp?ID=3145
摘要:交叉编译就是在一种计算机环境中运行的编译程序,能编译出在另外一种环境下运行的代码,简单地说,就是在一个平台上生成另一个平台上的可执行代码。本论文以Mini2440+Fedora12嵌入式开发平台为例,主要介绍了基于FrameBuffer和Libjpeg库的数码相框的交叉编译工作。
关键词:交叉编译、FrameBuffer、Libjpeg库、数码相框
数码相框,由于它的新颖性、便携性,在电子产品市场倍受关注,拥有数码相框已成为一种时尚。又由于它技术门槛较低,各种大小电子厂商都尝试来做这个产品,本论文目的是通过这个数码相框项目来熟悉嵌入式Linux的开发环境及流程,重点掌握嵌入式交叉编译过程和原理。
交叉编译就是在一种计算机环境中运行的编译程序,能编译出在另外一种环境下运行的代码,简单地说,就是在一个平台上生成另一个平台上的可执行代码。本论文以Mini2440+Fedora12嵌入式开发平台为例,主要阐述基于FrameBuffer和Libjpeg库的数码相框的交叉编译工作。
1.FrameBuffer
1.1 什么是FrameBuffer
FrameBuffer 是出现在Linux 2.2.xx 内核当中的一种驱动程序接口。 Linux抽象出FrameBuffer这个设备来供用户态进程实现直接写屏。Framebuffer机制模仿显卡的功能,将显卡硬件结构抽象掉,可以通过Framebuffer的读写直接对显存进行操作。用户可以将Framebuffer看成是显示内存的一个映像,将其映射到进程地址空间之后,就可以直接进行读写操作,而写操作可以立即反应在屏幕上
1.2 工作原理
Framebuffer 本身不具备任何运算数据的能力,就好比是一个暂时存放水的水池.CPU 将运算后的结果放到这个水池,水池再将结果流到显示器. 中间不会对数据做处理. 应用程序也可以直接读写这个水池的内容.在这种机制下,尽管Framebuffer 需要真正的显卡驱动的支持,但所有显示任务都有CPU 完成,因此CPU 负担很重。
1.3 FrameBuffer设备文件
FrameBuffer的设备文件一般是/dev/fb0、/dev/fb1 等等。可以用命令: #dd if=/dev/zero of=/dev/fb 清空屏幕;如果显示模式是1024x768-8 位色,用命令:$ dd if=/dev/zero of=/dev/fb0 bs=1024 count=768 清空屏幕;用命令: #dd if=/dev/fb of=fbfile 可以将fb 中的内容保存下来;用命令: #dd if=fbfile of=/dev/fb可以重新写回屏幕。
在使用Framebuffer 时,Linux 是将显卡置于图形模式下的.在应用程序中,一般通过将FrameBuffer 设备映射到进程地址空间的方式使用,本项目应用程序就是打开/dev/fb0 设备,并通过mmap 系统调用进行地址映射,随后用memset 将屏幕清空。
2.Libjpeg库
Libjpeg 是一个被广泛使用的jpeg 压缩/解压缩函数库,它能够读写JFIF 格式的jpeg 图像文件,通常这类文件是以.jpg 或者.jpeg 为后缀名的。通过Libjpeg 库,应用程序可以每次从jpeg 压缩图像中读取一个或多个扫描线,而诸如颜色空间转换、降采样/增采样、颜色量化之类的工作则都由Libjpeg 去完成了。
对于Libjpeg而言,图像数据是一个二维的像素矩阵。对于彩色图像,每个像素通常用三个分量表示,即RGB三个分量,每个分量用一个字节表示,因此每个分量的取值范围从0 到255;对于灰度图像,每个像素通常用一个分量表示,一个分量同样由一个字节表示,取值范围从0 到255。
3.Libjpeg库的编译
在Fedora12中,测试应用程序,执行tar zxvf jpegsrc.v8.tar.gz将文件解压到与源码文件夹相同的父目录下,进入目录cd jpeg-8,执行./configure 配置makefile 文件。configure脚本默认选项是X86PC系统环境。然后执行make命令,编译libjpeg。这步完成后,最好不要执行 make install 命令,否则会引起其他程序的错误。
进入到源文件下,编辑makefile文件,将其中的CFLAGS和LDFLAGS 两项设置为CFLAGS = -Wall -c -I../jpeg-8,LDFLAGS = -L ../jpeg-8/.libs -l jpeg,指定包含文件和库文件分别在父目录下的jpeg-8和jpeg-8/.libs中。jpeg使用RGB888格式,即每个像素用3个字节,而作者的Framebuffer驱动luxeon led 用的是RGB565格式,即每个像素用2个字节。这样在显示图片时必须抛弃部分数据,采用的方法是直接抛弃RGB各分量相应的低Bit位。图像看起来会有些失真。编译时需要加上-l jpeg选项。编辑好源程序后,编译。这时候会提示 ./main: error while loading shared libraries: libjpeg.so.8: cannot open shared object file: No such file or directory,说明程序调用动态库时找不到共享库文件,这时我们需要设置一下LD_LIBRARY_PATH环境变量。
LD_LIBRARY_PATH是Linux环境变量名,主要用于指定查找共享库时除了默认路径之外的其他路径。移植程序时的经常碰到需要使用一些特定的动态库,而这些编译好的动态库放在我们自己建立的目录里,这时可以将这些目录设置到LD_LIBRARY_PATH中。当执行函数动态链接.so时,如果此文件不在缺省目录“/usr/local/lib” 和“/usr/lib” 下,那么就需要指定环境变量LD_LIBRARY_PATH,假如现在需要在已有的环境变量上添加新的路径名,则需要在终端中输入:export LD_LIBRARY_PATH=newdirs(newdirs是新的路径串),然后用env | grep LD_LIBRARY_PATH命令查看LD_LIBRARY_PATH值是否为newdirs,如果变量中没有newdirs,甚至没有LD_LIBRARY_PATH,这时就需要编辑/root/.bash_profile和/etc/profile两个文件。在root用户下修改/root/.bash_profile文件,在PATH=$PATH:;$HOME/bin下面添加D_LIBRARY_PATH=$LD_LIBRARY_PATH:;/usr/local/lib:;/usr/lib:;/newdirs,并且更改export PATH 为 export PATH LD_LIBRARY_PATH。修改/etc/profile文件,在HISTSIZE=1000下面添加 LD_LIBRARY_PATH=$LD_LIBRARY_PATH:;/usr/local/lib:;/usr/lib:;/newdirs,同时在export后增加LD_LIBRARY_PATH,保存后退出。执行source /root/.bash_profile,更新系统变量,使其生效。
4.基于Mini2440+Fedora12平台的交叉编译
从PC机移植到开发板时需要重新编译源文件和库文件。首先交叉编译源文件,修改Makefile文件中的CC=gcc为CC=arm-linux-gcc,保存退出,执行make clean后再执行make即可。然后上传到开发板。接着交叉编译库文件,进入到jpeg-8目录下,执行make clean,清除编译好的动态库和链接文件,然后执行./configure host=arm-linux,生成arm平台的Makefile文件。既然共享库是arm平台上的共享库,那么它也需要交叉编译,所以,在执行make命令之前,设定编译器CC=arm-linux-gcc,然后再执行make生成共享库。编译完成之后进入/jpeg-8/.libs文件夹,将libjpeg.so.8.0.0上传至开发板的/usr/local/lib中。
运行开发板上的程序,如果遇到./main: error while loading shared libraries: libjpeg.so.8: cannot open shared object file: No such file or directory这样的错误提示,说明应用程序没有找到共享库,我们需要新建一个和PC机相同路径的jpeg-8文件夹,执行命令ln -s libjpeg.so.8 /usr/local/lib/libjpeg.so.8.0.0,生成一个链接到库文件。然后将链接的位置加入到D_LIBRARY_PATH变量中,详细方法与PC机修改方法相同。
基于FrameBuffer和Libjpeg库的数码相框的交叉编译,是基于嵌入式Linux的动态库交叉编译的一种典型应用,为从事嵌入式研发项目或技术服务提供了技术保障。
没有评论:
发表评论