鄢夢林,殷張發(fā),高心寬,葉 翔,姚 莉
(湖北理工學院計算機學院,湖北黃石435003)
隨著信息化、智能化、網(wǎng)絡化的發(fā)展,嵌入式系統(tǒng)的廣泛應用已經(jīng)滲入到我們?nèi)粘I畹母鱾€方面。在手機、MP3、PDA、數(shù)碼相機、電視機、甚至電飯鍋、手表里都有嵌入式系統(tǒng)的身影。據(jù)統(tǒng)計,每年全球嵌入式系統(tǒng)帶來的相關(guān)工業(yè)產(chǎn)值已超過1萬億美元。隨著多功能手機、便攜式多媒體播放機、數(shù)碼相機、HDTV和機頂盒等新興產(chǎn)品逐漸獲得市場的認可,嵌入式系統(tǒng)的市場正在以每年30%的速度遞增[1]。
數(shù)碼相框正是這樣一種嵌入式技術(shù)應用的代表產(chǎn)品,它的主要功能是保存和查看電腦、U盤或手機等存儲設備上的數(shù)碼照片。數(shù)碼相框在市場上的用途很多,比如產(chǎn)品展示、車載、數(shù)碼攝影、個人娛樂等。數(shù)碼相框作為伴隨數(shù)碼相機及互聯(lián)網(wǎng)不斷飛速發(fā)展的衍生產(chǎn)物進入市場至今,已經(jīng)被愈來愈多的普通消費者所接受。
嵌入式系統(tǒng)是指以應用為中心,以計算機技術(shù)為基礎,軟硬件可裁剪,適用于應用系統(tǒng)對功能、可靠性、成本、體積和功耗有嚴格要求的專用計算機系統(tǒng)。嵌入式系統(tǒng)由嵌入式微處理器、外圍硬件設備、嵌入式操作系統(tǒng)以及用戶應用程序4部分組成[1]。
本系統(tǒng)采用了廣州友善之臂設計、生產(chǎn)和發(fā)行銷售的mini6410開發(fā)板進行設計與實現(xiàn)。Mini6410屬于ARM11系列的微處理器,采用三星公司的S3C6410芯片。ARM11系列微處理器是ARM公司近年推出的新一代RISC處理器,是ARM新指令架構(gòu)-ARMv6的第一代設計實現(xiàn)。Mini6410處理器一方面,包含了更多的多媒體處理指令來加速視頻和音頻處理;另一方面,它的新型存儲器系統(tǒng)進一步提高了操作系統(tǒng)的性能,提供了新指令來加速實時性能和中斷的響應,為軟件開發(fā)者帶來便利。
目前較為流行的嵌入式操作系統(tǒng)有VxWorks、Windows CE、Linux、C/OS等。Linux是以 Unix為基礎發(fā)展而成的操作系統(tǒng),能夠支持 ARM、MIPS、ALPHA、x86、PowerPC等多種系列的嵌入式微處理器[2]。Linux操作系統(tǒng)最大的特性就是開源性和可剪裁性,除此之外linux操作系統(tǒng)還有內(nèi)核高效穩(wěn)定,良好的可移植性,支持多種文件系統(tǒng)等優(yōu)點,有利于Linux在嵌入式設備中的應用。因此,本系統(tǒng)選用嵌入式Linux操作系統(tǒng)作為開發(fā)平臺,選用Ubuntu系統(tǒng)作為前臺開發(fā)編譯的操作系統(tǒng)。Ubuntu是一個以桌面應用為主的Linux操作系統(tǒng)。
本系統(tǒng)實現(xiàn)市場現(xiàn)有的數(shù)碼相框圖片顯示功能。通過解析圖片信息獲取圖片名稱及圖片說明信息,分析圖片類型確定圖片格式,調(diào)用libjpeg庫文件實現(xiàn)jpeg圖片解碼,調(diào)用freetype字體庫實現(xiàn)圖片說明信息的處理。通過FrameBuffer幀緩沖設備的使用,實現(xiàn)對jpeg格式圖片,文字的各種效果顯示,音樂播放等,完成對數(shù)碼相框的設計。
Framebuffer(幀緩沖)是Linux內(nèi)核的一種圖形設備驅(qū)動接口,提供了LCD控制器的抽象性描述。它將LCD控制器上的顯存抽象成一種字符設備,應用程序通過定義好的接口可以訪問LCD控制器的顯存,直接對顯示緩沖區(qū)進行讀/寫操作,而不需要知道底層的任何操作細節(jié)。對于開發(fā)者來講,framebuffer是一塊顯示緩沖區(qū),向這個顯示緩沖區(qū)寫入特定格式的數(shù)據(jù)就可以更新顯示屏的輸出[2]。
FrameBuffer機制模仿顯卡的功能,將顯卡硬件結(jié)構(gòu)進行抽象,可以通過FrameBuffer的讀寫直接對顯存進行操作。Linux抽象出FrameBuffer設備來供用戶態(tài)進程實現(xiàn)直接寫屏,這種操作是抽象、統(tǒng)一的,由Framebuffer設備驅(qū)動完成。用戶不必關(guān)心物理顯存的位置、換頁機制等,允許應用程序不必關(guān)心底層硬件細節(jié)利用Framebuffer通過指定的接口訪問圖形硬件。
Framebuffer設備的設備節(jié)點位于/dev目錄,設備文件一般是 /dev/fb0、/dev/fb1等。要想系統(tǒng)支持FrameBuffer,首先要在內(nèi)核(Kernel)里設置對該功能的支持。我們選擇的操作系統(tǒng)Ubuntu不需要另外配置Kernel選項,可以在/dev下看到fb0設備文件。本系統(tǒng)在Linux下將顯示模式設置為圖形模式,采用1024x768-16位色,使用命令$dd if=/dev/zero of=/dev/fb0 bs=1024 count=768。FrameBuffer設備提供了若干 ioctl命令,通過ioctl操作可以讀取或設定設參數(shù)。例如:顯示設備的固定信息(設備名、顯示屏的組織等)、與顯示模式相關(guān)的可變信息(比如分辨率、象素結(jié)構(gòu)、每掃描線的字節(jié)寬度等),以及偽彩色模式下的調(diào)色板信息等。本系統(tǒng)設計通過FrameBuffer將設備映射到進程地址空間,并通過mmap系統(tǒng)調(diào)用進行地址映射,以實現(xiàn)對設備的圖像顯示控制。實現(xiàn)代碼如下:
short*fbmem;
int fd,w,h;
struct fb_var_screeninfo fb_var;
fd=open("/dev/fb0",O_RDWR);
ioctl(fd,F(xiàn)BIOGET_VSCREENINFO,&fb_var);
w=fb_var.xres;
h=fb_var.yres;
fbmem=mmap(0,w*h*2,PROT_WRITE|PROT_READ,MAP_SHARED,fd,0);
因此,本系統(tǒng)中只需要將相框中需要顯示的JPEG圖片進行解碼為bmp像素點,再通過Framebuffer設備寫入就可以實現(xiàn)圖像顯示。
本系統(tǒng)設計支持JPEG格式和PNG格式圖片,兩者都是位圖文件存儲格式。JPEG格式是一種支持8位和24位色彩的壓縮位圖格式,適合在網(wǎng)絡上傳輸,是非常流行的圖形文件格式。在Linux下使用的JPEG壓縮/解壓縮函數(shù)庫是libjpeg,它能夠讀寫JFIF標記圖像文件格式)格式的JPEG圖像文件,通常這類文件是以.jpg或者.jpeg為后綴名的。通過libjpeg庫,應用程序可以每次從jpeg壓縮圖像中讀取一個或多個掃描線(scanline),而諸如顏色空間轉(zhuǎn)換、降采樣/增采樣、顏色量化之類的工作則都由libjpeg完成[3]。PNG格式是設計來替代gif,它對于更小范圍的TIFF(標記圖像文件格式)來說有了非常多的進步和拓展,并且減少了關(guān)于專利權(quán)的麻煩。Linux下使用的PNG壓縮/解壓縮函數(shù)庫是libpng。
實現(xiàn)圖片解壓并通過FrameBuffer進行顯示的任務主要分為三步。首先,實現(xiàn)FrameBuffer設備的初始化操作;其次,獲取圖片名稱、判斷圖片類型、調(diào)用 libjpeg、libpng庫函數(shù)實現(xiàn)圖片解壓;最后,通過FrameBuffer實現(xiàn)圖片的效果播放。在數(shù)碼相框系統(tǒng)設計中,由于我們需要顯示的圖片信息被保存在鏈表節(jié)點中,若想顯示圖片需要從鏈表中獲取圖片文件信息[4]。主要實現(xiàn)代碼如下:
intmain(int argc,char*argv[])
{…………
/*Open the Framebuffer equipment files*/
if((fb_device=getenv("FRAMEBUFFER"))==NULL)
fb_device=FB_DEV;
fbdev=fb_open(fb_device);
/*Access equipment's parameters,wide,high,bpp*/
if(fbdev>=0)
iotcl(fbdev,F(xiàn)BIOGET_VSCREENINFO,&fb_var);
else return-1;
fb_width=fb_var.xres;
fb_height=fb_var.yres;
fb_depth=fb_var.bits_per_pixel;
printf("please check display mode%d*%d-%dbpp”,fb_width,fb_height,fb_depth);
/*The frame buffer equipment Framebuffer mapped intomemory area*/
screensize=fb_width*fb_height*(fb_depth/8);
fbmem=fb_mmap(fbdev,screensize);
init_config();
new=&head;
for(i=0;i<1000;i++)
{int type;
new=get_next_link(new);
if(new->filename==NULL)
break;
type=get_file_type(new->filename);
if(type==JPEG)
display_jpeg(new- > filename,fbmem,200,120,1);
if(type==PNG)
display_png(new- > filename,fbmem,200,120,1);
}
……….return 0;
}
本系統(tǒng)采用多進程編程解決數(shù)碼相框的背景音樂設計問題。每個進程在內(nèi)核中都有一個進程控制塊(PCB)來維護進程相關(guān)的信息,Linux內(nèi)核的進程控制塊是task_struct結(jié)構(gòu)體。系統(tǒng)調(diào)用fork()的作用是根據(jù)一個現(xiàn)有的進程復制出一個新進程,原來的進程稱為父進程(Parent Process),新進程稱為子進程(Child Process)。System()會調(diào)用fork()產(chǎn)生子進程,由子進程來調(diào)用/bin/sh-c string執(zhí)行參數(shù)string字符串所代表的命令,此命令執(zhí)行完后隨即返回原調(diào)用的進程。在調(diào)用system()期間SIGCHLD信號會被暫時擱置,SIGINT和SIGQUIT信號則會被忽略。如果system()調(diào)用成功則最后會返回執(zhí)行shell命令后的返回值來確認執(zhí)行成功。本系統(tǒng)中,主要用到一個調(diào)用系統(tǒng)播放器的命令來控制音樂的播放。具體函數(shù)如下:
void*code_music(void*m)
{
system("/usr/bin/mplayer /home/dpf/mus/snq.mp3>/dev/null");
return 0;
}
本系統(tǒng)采用交叉編譯進行應用程序移植。交叉編譯是嵌入式開發(fā)中最常見的概念,簡單地說,就是在一個平臺上生成另一個平臺上的可執(zhí)行代碼。交叉編譯這個概念的出現(xiàn)和流行是與嵌入式系統(tǒng)的廣泛發(fā)展同步的。因為在進行嵌入式系統(tǒng)的開發(fā)時,開發(fā)平臺和運行平臺是不同系列的機器。當開發(fā)平臺(主機系統(tǒng))和運行平臺(目標系統(tǒng))不兼容時,就必須使用交叉編譯的方式把用高級語言編寫的程序轉(zhuǎn)換成機器可以執(zhí)行的二進制程序。
本文介紹的嵌入式數(shù)碼相框系統(tǒng)設計主機采用x86體系結(jié)構(gòu)的Ubuntu Linux系統(tǒng),在此操作系統(tǒng)下安裝Linux發(fā)行包以及交叉編譯器arm-linux-gcc。目標系統(tǒng)是S3C6410 ARM11處理器。我們在主機(PC機)上開發(fā)程序、運行交叉編譯器,并成功編譯生成執(zhí)行程序后,再移植到目標機(mini6410開發(fā)板)上運行。由于 PC機與 mini6410開發(fā)板的編譯工具不同,在配置安裝上首先解決對動態(tài)鏈接庫和靜態(tài)鏈接庫的支持??墒褂萌缦旅?
#export CC=arm-linux-gcc
#./configure--host=arm-unknown-linux--prefix=/home/jpeg/jpeg--enable-shared--enable-static
下載、安裝和編譯jpeg庫,可使用如下命令:
[root@monahans jpeg]#tar-xzf jpegsrc.v8b.tar.gz
[root@monahans jpeg]#mv jpeg-8b jpeg
[root@monahans jpeg]#cd jpeg
[root@monahans jpeg]#./configure--host=arm-unknown-linux--prefix=/home/jpeg/jpeg--enable-shared--enable-static
修改生成的Makefile文件:
prefix=/home/jpeg/jpeg
CC= /usr/local/arm/3.4.1/arm-linux/bin/arm-linux-gcc
最后通過如圖1所示命令對文件(fb.c,img.c,jpeg.c)進行交叉編譯生成可執(zhí)行的文件fb,此文件是本系統(tǒng)的主程序代碼。
圖1 交叉編譯
把目標機上可執(zhí)行程序fb下載或燒寫到目標機上,終端運行可執(zhí)行文件,即可看到數(shù)碼相框圖片的展示效果。運行效果圖如圖2所示。
本文主要介紹了在Linux操作系統(tǒng)下采用廣州友善之臂公司生產(chǎn)的嵌入式開發(fā)板mini6410設計實現(xiàn)的數(shù)碼相框產(chǎn)品。本系統(tǒng)實現(xiàn)了圖片瀏覽和音頻播放功能,已經(jīng)完成了數(shù)碼相框的基本功能,鼠標的加入為后面數(shù)碼相框的進一步制作奠定了基礎。對于數(shù)碼相框的后續(xù)研究設計,仍有可以進一步擴展和改進的地方。如可以在本系統(tǒng)上擴展USB功能和網(wǎng)絡通信功能,加入觸摸屏功能進一步完善上層操作界面的設計等。
圖2 系統(tǒng)運行效果圖
[1]馬忠梅.ARM&Linux嵌入式系統(tǒng)教程(第2版)[M].北京航空航天出版社,2008.
[2]陳賾.ARM9嵌入式技術(shù)及Linux高級實踐教程[M].北京航空航天大學出版社,2005.
[3]涂克亮.基于ARM嵌入式的圖像采集與顯示系統(tǒng)設計[J].工業(yè)控制計算機,2011(08):10~12.
[4]Li Yao.On the S3C2440-based design for embedded system of digital photo frame[J].IEEC,2011:386~389.