廣東工業(yè)大學(xué)自動(dòng)化學(xué)院 黃偉杰
?
基于linux系統(tǒng)平臺(tái)下的nfs方式應(yīng)用程序開(kāi)發(fā)及實(shí)現(xiàn)
廣東工業(yè)大學(xué)自動(dòng)化學(xué)院黃偉杰
與Windows系統(tǒng)以及ios系統(tǒng)不同,Linux操作系統(tǒng)因?yàn)樗碛忻赓M(fèi)的開(kāi)源代碼資源特性因而在各種臺(tái)式計(jì)算機(jī)、大型機(jī)以及超級(jí)計(jì)算機(jī)中裝載并且廣泛應(yīng)用于各種工業(yè)控制領(lǐng)域。而嵌入式下的Linux系統(tǒng)則是在目前盛行的Linux系統(tǒng)下進(jìn)行修改然后移植到各種相關(guān)的嵌入式設(shè)備中運(yùn)行的操作系統(tǒng)。目前廣泛運(yùn)用在移動(dòng)終端網(wǎng)絡(luò)、市面上各種消費(fèi)型電子媒體播放器甚至軍工領(lǐng)域。面對(duì)市面上各種Linux系統(tǒng)程序的使用以及開(kāi)發(fā),初學(xué)者不免會(huì)產(chǎn)生相應(yīng)的疑惑。因此,本人在基于ARM類(lèi)下的內(nèi)核A8芯片,處理器為三星公司生產(chǎn)的s5pv210開(kāi)發(fā)板搭載的Linux系統(tǒng)平臺(tái)下,運(yùn)用一個(gè)簡(jiǎn)單易懂的例子來(lái)對(duì)嵌入式Linux開(kāi)發(fā)環(huán)境下的NFS配置以及實(shí)現(xiàn)進(jìn)行闡述,具有一定現(xiàn)實(shí)意義以及研究?jī)r(jià)值。
嵌入式下的Linux;進(jìn)線程;后臺(tái);交叉編譯;NFS配置
本文主要通過(guò)三部分內(nèi)容來(lái)實(shí)現(xiàn),第一部分是系統(tǒng)開(kāi)發(fā)平臺(tái)的搭建,第二部分是基于系統(tǒng)平臺(tái)之上對(duì)NFS開(kāi)發(fā)環(huán)境的搭建,最后介紹的是通過(guò)Linux嵌入式系統(tǒng)平臺(tái)搭建的NFS方式下的程序?qū)崿F(xiàn)。
2.1當(dāng)今各大系統(tǒng)操作平臺(tái)
當(dāng)今主流的系統(tǒng)操作平臺(tái)有微軟公司旗下的windows操作平臺(tái)、蘋(píng)果公司的Mac OS操作平臺(tái)以及Linux/Unix操作平臺(tái)。其中本文著重于介紹嵌入式Linux開(kāi)發(fā)平臺(tái)的搭建[1]。
Linux操作系統(tǒng)是一個(gè)免費(fèi)的類(lèi)Unix的操作系統(tǒng),基于POSIX和UNIX多用戶,同時(shí)支持多線程,與此同時(shí),它還繼承了Unix網(wǎng)絡(luò)為核心的設(shè)計(jì)思想,性能穩(wěn)定。與微軟的windows系統(tǒng)以及蘋(píng)果公司的Mac Os系統(tǒng)不同,它擁有大量的開(kāi)源代碼,圖形界面設(shè)計(jì)也是相當(dāng)優(yōu)秀,同時(shí)也支持多平臺(tái)。當(dāng)今主流的Linux系統(tǒng)有Ubuntu和紅帽(Redhat)等。
2.2嵌入式Linux平臺(tái)的搭建
應(yīng)用程序在嵌入式Linux下的開(kāi)發(fā)與windows下的開(kāi)發(fā)是完全不同的。微軟公司的windows系統(tǒng)下,可以隨意下載各種集成好的編譯軟件,例如visual Studio,在此環(huán)境下可以迅速完成程序的編輯、編譯和運(yùn)行。與此相比,Linux系統(tǒng)平臺(tái)缺少像visual studio這樣簡(jiǎn)單高效的編譯軟件,因此進(jìn)行程序開(kāi)發(fā)需要PC機(jī)與之搭載的嵌入式Linux平臺(tái)下進(jìn)行。出于開(kāi)發(fā)的方便出發(fā),程序的編輯在PC機(jī)上完成,而程序的調(diào)試運(yùn)行在Linux系統(tǒng)上的終端上完成,最終在開(kāi)發(fā)板上進(jìn)行調(diào)試。因此,需要在Linux服務(wù)器與開(kāi)發(fā)板這個(gè)客戶端實(shí)現(xiàn)通訊來(lái)交換信息。目前最常用的方法莫過(guò)于FTP方式。方法是首先在Linux終端上對(duì)源程序代碼進(jìn)行編譯,通過(guò)將編譯后的文件通過(guò)TFTP下載到開(kāi)發(fā)板上運(yùn)行。雖說(shuō)簡(jiǎn)單方便,但是致命的缺陷是下載速度慢導(dǎo)致效率低下,不能在線調(diào)試。因此,基于此我將在本文接下來(lái)討論一種更為高效的方式來(lái)實(shí)現(xiàn)信息的交換。這種交換方式叫做NFS[2]。
2.3Linux嵌入式平臺(tái)的架構(gòu)
Linux嵌入式平臺(tái)的架構(gòu)主要包括Linux服務(wù)器、普通局域網(wǎng)下的計(jì)算機(jī)客戶端以及嵌入式Linux開(kāi)發(fā)板系統(tǒng)。[3]總體設(shè)計(jì)思路如圖1所示。
圖1 總體設(shè)計(jì)圖
任意一臺(tái)PC電腦都可以作為L(zhǎng)inux服務(wù)器,在此使用的是Ubuntu操作系統(tǒng),在此系統(tǒng)上進(jìn)行內(nèi)核移植以及應(yīng)用程序的編輯以及編譯??蛻舳丝梢允嵌嗯_(tái)計(jì)算機(jī),多半搭載著windows操作系統(tǒng),完成基本工作,有時(shí)候根據(jù)需要與Linux服務(wù)器或者開(kāi)發(fā)板進(jìn)行連接。而嵌入式Linux開(kāi)發(fā)板系統(tǒng)則是用開(kāi)對(duì)應(yīng)用程序的最終開(kāi)發(fā),需要在服務(wù)器的基礎(chǔ)之上,搭建網(wǎng)絡(luò)文件系統(tǒng),將服務(wù)器上的一系列目錄掛載到開(kāi)發(fā)板系統(tǒng)上,進(jìn)而對(duì)相應(yīng)的程序進(jìn)行編譯以及運(yùn)行[4]。
2.4Linux操作系統(tǒng)的移植
本文實(shí)驗(yàn)使用的三星公司生產(chǎn)的s5pv210開(kāi)發(fā)板所搭載的操作系統(tǒng)就是嵌入式Linux,它是把標(biāo)準(zhǔn)的Linux操作系統(tǒng)進(jìn)行一系列修改后加入特定功能所形成的系統(tǒng)。然后將它最終移植到開(kāi)發(fā)板上運(yùn)行。系統(tǒng)的內(nèi)核移植分為引導(dǎo)程序、操作系統(tǒng)內(nèi)核移植以及根文件系統(tǒng)三大塊。
(1)引導(dǎo)程序(bootloader)
引導(dǎo)程序是操作系統(tǒng)內(nèi)核運(yùn)行之前的一段代碼,其最終目的就是啟動(dòng)內(nèi)核。[5]分為boot+loader兩階段。Boot即為初始化寄出的硬件設(shè)備,建立內(nèi)存空間映射圖,將系統(tǒng)的軟硬件環(huán)境帶到一個(gè)合適的狀態(tài)。Loader即是將操作系統(tǒng)內(nèi)核鏡像加載到內(nèi)存,之后跳轉(zhuǎn)到內(nèi)核所在的地址運(yùn)行。
(2)操作系統(tǒng)內(nèi)核
內(nèi)核的本質(zhì)是c語(yǔ)言函數(shù)的集合,是硬件的管理者。從應(yīng)用程序的角度來(lái)說(shuō),內(nèi)核是服務(wù)的提供者,有如下功能:第一為實(shí)現(xiàn)系統(tǒng)的調(diào)用,實(shí)現(xiàn)應(yīng)用程序和內(nèi)核的交應(yīng)。其次為對(duì)進(jìn)程的管理,進(jìn)程的創(chuàng)建、終止、通信和調(diào)度。除此之外還有實(shí)現(xiàn)對(duì)內(nèi)存的管理以及設(shè)備的管理。最后一點(diǎn)為虛擬文件系統(tǒng)和帶有網(wǎng)絡(luò)協(xié)議。
(3)根文件系統(tǒng)
根文件的內(nèi)容有根目錄”/”;bin文件目錄存放所有用戶都能使用的基本指令;sbin目錄存放的是系統(tǒng)命令,只有管理員才可以使用;usr目錄存放的是用戶的命令以及文檔;dev目錄存放的是設(shè)備文件,設(shè)備文件是Linux操作系統(tǒng)下特有的文件格式,在Linux操作系統(tǒng)下,所有設(shè)備操作都是通過(guò)訪問(wèn)設(shè)備文件來(lái)實(shí)現(xiàn)的。除此之外,還有etc等一系列文件。
2.5交叉編譯環(huán)境的建立
利用在計(jì)算機(jī)上的編譯軟件將源代碼生成在開(kāi)發(fā)板上運(yùn)行的最終代碼過(guò)程稱(chēng)為交叉編譯。[6]步驟分為編譯鏈接以及轉(zhuǎn)換三步。其編譯器涉及到arm-linux-gcc等。
NFS服務(wù)器在嵌入式開(kāi)發(fā)中非常常用,可以實(shí)現(xiàn)主機(jī)與開(kāi)發(fā)板上的文件共享。目標(biāo)系統(tǒng)通常作為NFS客戶機(jī)使用,Linux主機(jī)作為服務(wù)器,目標(biāo)系統(tǒng)使用NFS,將服務(wù)器上的目錄文件掛載到本地開(kāi)發(fā)板上,便可以直接運(yùn)行在服務(wù)器上的源程序了,與FTP這種方式相比,效率有了極大的提高。NFS在Linux服務(wù)器上的配置如下:
(1)安裝軟件包,#apt-get install nfs-kernel-server portmap
(2)配置#mkdir /nfs以及#vim /etc/exports,增加以下內(nèi)容為/home/ gec/nfs*(rw,sync,no_root,squash)和/home/gec/nfs(要共享的目錄)。
(3)使用重啟服務(wù)器命令”sudo service nfs-kernel-server restart”
(4)設(shè)定目錄及其權(quán)限。使用命令mkdir nfs,然后chmod 777-r nfs/.
(5)開(kāi)發(fā)板上操作如下:首先是要確定ip,確定后使用命令mounto nolock 192.168.x.x /home/gec/nfs /mt,mount的意思為掛載。最后就可以進(jìn) /mt進(jìn)行操作了。使用unmount /mt就可以取消掛載。
對(duì)于上述的NFS環(huán)境搭建好之后,我們就可以進(jìn)行服務(wù)器與客戶端通訊了,最終實(shí)現(xiàn)程序的開(kāi)發(fā)。
4.1程序開(kāi)發(fā)流程
若將Linux系統(tǒng)在windows下的虛擬機(jī)中實(shí)現(xiàn),則首先第一步為在windows下的代碼編輯器上編輯好代碼,然后通過(guò)samba方式將代碼共享到虛擬機(jī)上的Linux操作系統(tǒng),然后使用arm-linux-gcc進(jìn)行交叉編譯,將生成的可執(zhí)行文件通過(guò)NFS方式,最終開(kāi)發(fā)板上利用掛載好的服務(wù)器上的共享目錄進(jìn)行程序的編譯調(diào)試。具體步驟如圖2所示:
圖2 NFS實(shí)現(xiàn)步驟
完成上述所有步驟后,便可以將代碼燒寫(xiě)到Nandflash上了。
4.2NFS方式下的程序代碼例子
這個(gè)例子為實(shí)現(xiàn)s5pv210上的LCD屏幕圖片百葉窗顯示。以此說(shuō)明嵌入式Linux的程序開(kāi)發(fā)實(shí)現(xiàn)步驟。
第一步:程序的編輯??紤]到程序的簡(jiǎn)單明了,在此就不用windows下的代碼編輯器來(lái)編輯代碼,而是直接使用Linux下的vim。在Linux系統(tǒng)上創(chuàng)立的NFS共享目錄/home/gec/nfs下使用文本編輯器來(lái)編輯,程序的名字為bmp_show.c。輸入指令#vi bmp_show.c,完成代碼的編輯的后,保存退出編輯器。代碼如下:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <string.h>
#include <stdlib.h>
void func_blind(char *p_lcd, void * bmp)//百葉窗顯示
{
int k, j;
for(k=0; k<201; k+=20)
{
for(j=0; j<480; j++)
{
memcpy(p_lcd+800*4*j, bmp+800*4*j, 4*k);
memcpy(p_lcd+800*4*j+200*4, bmp+800*4*j+200*4, 4*k);
memcpy(p_lcd+800*4*j+400*4, bmp+800*4*j+400*4, 4*k);
memcpy(p_lcd+800*4*j+600*4, bmp+800*4*j+600*4, 4*k);
}
usleep(90000);
}
}
int bmp_show(char *filename)//圖片顯示
{
char *bmp = calloc(800*480, 4);char *p_lcd;
char buf[800*480*3];
int i, j, tem, x, y;
int lcd_fd = open(“/dev/fb0”, O_RDWR);//打開(kāi)LCD設(shè)備
int bmp_fd = open(filename, O_RDONLY);//打開(kāi)bmp格式文件
if(lcd_fd < 0)
{
perror("open failed!");
return -1;
}
//創(chuàng)建內(nèi)存映射,大小為800*480*4個(gè)字節(jié),可讀可寫(xiě),可被其它進(jìn)程共享
p_lcd = mmap(NULL, 800*480*4, PROT_READ|PROT_WRITE,MAP_SHARED, lcd_fd, 0);
if(p_lcd == NULL)
{
perror("mmap failed!");
return -1;
}
lseek(bmp_fd, 54, SEEK_SET);//從文件頭位置偏移54個(gè)字節(jié)
read(bmp_fd, buf, 800*480*3);//向bmp圖片讀取800*480*3個(gè)字節(jié)的數(shù)據(jù)放在buf里面
for(i = 0, j = 0; i < 800*480*3; i+=3, j+=4)//轉(zhuǎn)換為L(zhǎng)CD格式(RGBA)
{
bmp[j]= buf[i];// [R]
bmp[j+1]= buf[i+1];//[G]
bmp[j+2]= buf[i+2];//[B]
bmp[j+3]= 0x00;// [A]
}
for(y = 0; y < 240; y++)//反轉(zhuǎn)圖片
for(x = 0; x < 800*4; x++)
{
tem = bmp[x+(479-y)*800*4];
bmp[x+(479-y)*800*4]= bmp[x+y*800*4];
bmp[x+y*800*4]= tem;
}
func_blind(p_lcd, bmp);//百葉窗顯示
for(i = 0; i < 800*480*4; i++)//LCD內(nèi)存的操作
{
p_lcd[i]= bmp[i];//通過(guò)單字節(jié)賦值操作LCD內(nèi)存
}
//memcpy(p_lcd, bmp, 800*480*4);//使用memcpy操作LCD內(nèi)存
}
int main(int argc, char **argv)
{
bmp_show(argv[1]);//bmp顯示函數(shù)return 0;
}
第二步為代碼的編譯。使用交叉編譯工具鏈arm-linux-gcc bmp_show.c -o bmp_show,編譯完成后,會(huì)在/home/gec/nfs這個(gè)目錄下生成bmp_show這個(gè)可執(zhí)行文件。
第三步為將剛剛的可執(zhí)行文件掛載到開(kāi)發(fā)板上的共享目錄上。Ip配置好后,使用命令mount-o nolock 192.168.x.x /home/gec/nfs /mt,然后進(jìn)入到/mnt這個(gè)目錄下找到剛剛共享的可執(zhí)行文件。最后將程序運(yùn)行起來(lái)。
本文通過(guò)在三星公司生產(chǎn)的s5pv210的開(kāi)發(fā)板上搭建的嵌入式Linux系統(tǒng)平臺(tái)基礎(chǔ)上使用的NFS方式進(jìn)行程序開(kāi)發(fā),相比傳統(tǒng)的FTP模式的程序傳輸,大大提高了效率,具有一定的價(jià)值以及研究意義。
[1]郭昌建.淺析多系統(tǒng)共存[J].巢湖學(xué)院學(xué)報(bào),2005,7(3):93-94.
[2]M.Tim Jones.網(wǎng)絡(luò)文件系統(tǒng)與Linux[J].2011.
[3]張宇超.網(wǎng)絡(luò)計(jì)算機(jī)中嵌入式Linux操作系統(tǒng)體系結(jié)構(gòu)及相關(guān)技術(shù)研究[D].重慶大學(xué),2004.
[4]葉軍,朱華生.嵌入式Linux NFS方式下應(yīng)用程序的實(shí)現(xiàn)[J].微計(jì)算機(jī)信息,2007,23(8):74-75.
[5]陳寶君,張愛(ài)麗,仲崇權(quán),等.嵌入式系統(tǒng)的內(nèi)核啟動(dòng)過(guò)程分析[J].微計(jì)算機(jī)信息,2008,24(11).
[6]呂鵬.基于ARM的嵌入式Linux應(yīng)用程序開(kāi)發(fā)[J].計(jì)算機(jī)光盤(pán)軟件與應(yīng)用,2015(3):51-51.