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