版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、3.1 嵌入式Linux軟件開發(fā)工具下面將介紹開發(fā)嵌入式Linux應(yīng)用軟件所用到的一些常用工具,包括編輯工具vi、編譯工具gcc、MakeFile文件及調(diào)試工具gdb。 使用vi編輯器vi作為UNIX世界里極為普遍的全屏幕文本編輯器,幾乎可以說任何一臺(tái)UNIX機(jī)器都會(huì)提供這個(gè)軟。當(dāng)然作為UNIX家族的一份子的Linux也不會(huì)例外。Linux下雖然已經(jīng)發(fā)展處許多更新、更加好用的文本編輯器,但是卻不一定每一臺(tái)機(jī)器上都提供了這些額外的安裝軟件。所以,掌握了vi的編程,那我們可以在各種不同的機(jī)器上得心應(yīng)手的操作。這種編輯器還有一大好處是所有的命令按鍵都在手指范圍內(nèi),手不必離開主鍵盤就可輸入所有命令。v
2、i的原意是“Visual”,它是一個(gè)立即反應(yīng)的編輯程序。值簡(jiǎn)單地執(zhí)行“vi”指令就可以進(jìn)入vi的編輯環(huán)境。vi有3種狀態(tài),即可視命令模式、冒號(hào)命令模式及文本編輯模式。一般當(dāng)進(jìn)入vi時(shí),會(huì)首先進(jìn)入可視命令方式,這是vi的啟動(dòng)默認(rèn)模式。在這種模式下用戶輸入的任何內(nèi)容都被認(rèn)為是編輯命令。如按下“i”鍵就進(jìn)入插入方式,可從光標(biāo)左側(cè)輸入文本;如按下“a”鍵就進(jìn)入添加方式,可以在光標(biāo)右側(cè)輸入文本。在冒號(hào)命令方式下,所有命令都要以“:”開始,所輸入的字符系統(tǒng)均作命令來處理,如輸入“:q”代表退出,“:w”表示存盤。進(jìn)入文本編輯模式,這時(shí)用戶可以進(jìn)行所有文本的編輯操作。在文本編輯模式下,按下Esc鍵就可以回到
3、命令狀態(tài)。無論是創(chuàng)建新文件或修改舊文件,都可以使用vi,所需指令為:vi filemane如果文件是新的,就會(huì)在屏幕底部看到一個(gè)信息,告訴用戶正在創(chuàng)建新文件。如輸入命令:vi /tmp/test。若是新文件,就應(yīng)該看到如圖所示信息:圖 用vi命令創(chuàng)建文件經(jīng)vi創(chuàng)建的事例文件,一行開始處的波折號(hào)“”表示文件這一行是空行。如果文件早已存在,vi則會(huì)顯示文件的前24行中的內(nèi)容。這時(shí)用戶就可以使用下列命令進(jìn)入編輯模式:² 指令按鍵“i”:在光標(biāo)處前面插入正文,光標(biāo)后的文字隨追加的文字向后移動(dòng)。² 指令按鍵“I”:在光標(biāo)所在行開始處插入正文。² 指令按鍵“a”:在光標(biāo)所在位
4、置后面追加正文,光標(biāo)后的文字隨追加的文字向后移動(dòng)。² 指令按鍵“A”:在光標(biāo)所在行行尾追加正文。² 指令按鍵“o”:在光標(biāo)所在行下面新開一行,并進(jìn)入編輯狀態(tài)。² 指令按鍵“O”:在光標(biāo)上面新開一行,并進(jìn)入編輯狀態(tài)。下面對(duì)一些基本命令加以解釋:(1)光標(biāo)命令。² k、i、h、l:上、下、左、右光標(biāo)移動(dòng)命令。雖然也可以在L,inux中使用鍵盤右邊的4個(gè)光標(biāo)鍵,但是這4個(gè)命令還是非常有用的,因?yàn)檫@4個(gè)鍵正是右手在鍵盤上放置的基本位置。 ² nG:跳轉(zhuǎn)命令。n為行數(shù),該命令立即使光標(biāo)跳到指定行。² Ctrl+g:光標(biāo)所在位置的行數(shù)和列數(shù)報(bào)告。
5、² w、b:使光標(biāo)向前或向后跳過一個(gè)單詞。² O:移動(dòng)光標(biāo)到所在行的最前面,相當(dāng)于功能鍵Home o² $:移動(dòng)光標(biāo)到所在行的最后面,相當(dāng)于功能鍵End。² Ctrl+d:光標(biāo)向下移半頁。² Ctrl+f:光標(biāo)向下移一頁。² Ctrl+lu光標(biāo)向上移半頁。² Ctrl+b:光標(biāo)向上移一頁。² H:移動(dòng)到屏幕的第一行。² M:移動(dòng)到屏幕的中間行。² L:移動(dòng)到屏幕的最后行。(2)編輯命令。² i、I、a、A:在說明如何進(jìn)入編輯模式時(shí)已經(jīng)介紹。² r、R:r修改光標(biāo)所在字符,r后
6、接要修改的字符。R進(jìn)入取代狀態(tài),新增資料會(huì)覆蓋原先資料,直到按Esc鍵回到指令模式下為止。² cw、dw:改變(置換)/刪除光標(biāo)所在處的單詞的命令(c=change、d=delete)。² x、x:刪除光標(biāo)所在處后面/前面的字符。² d$、d0:刪除光標(biāo)所在處到行尾/行首的命令。² dd:刪除光標(biāo)所在行。² dw:刪除光標(biāo)處的單詞。² nx:刪除光標(biāo)處后n個(gè)字符。² nX:刪除光標(biāo)處前n個(gè)字符。² ndw:刪除光標(biāo)處后n個(gè)單詞(word)。² u:恢復(fù)前一次所做的操作,相當(dāng)于Word工具中的undo操作。
7、² y:復(fù)制操作(yank)。² p:粘貼操作(普通)。(3)查找/替換命令。² /string、?string:從光標(biāo)所在處向前或向后查找相應(yīng)的字符串的命令。² n:同一方向下重復(fù)檢索。² N:相反方向上重復(fù)檢索。² rchar:由char代替光標(biāo)處的字符。² Rtext:由text代替光標(biāo)處的字符。² Cwtext:由text取代光標(biāo)處的單詞。² Ctext:由text取代光標(biāo)處至該行結(jié)尾處。² CC:使整行空白,但保留光標(biāo)位置,開始輸入。² :s/stringl/string2/
8、g:在整個(gè)文件中替換“stringl”成“string2”。² 下面通過實(shí)例說明查找替換命令的使用:² /hello:向前查找hello字符。² ?goodbye:向后查找goodbye一詞。² /The*foot:向前查找The一詞所在的行以及The之后的某一點(diǎn)上的foot詞匯。² ?pPrint:向后查找print或Print單詞(注意在【,inux中大小寫是嚴(yán)格區(qū)分的)。² :s/Local/s/Remote/g:用Remote一詞替換文件中每一行的Local。(4)存盤/退出命令。在修改文件時(shí),如何存檔及退出指定文件都非常重要
9、。在vi內(nèi),使用存檔或退出的指令時(shí),先按冒號(hào)(:),進(jìn)入冒號(hào)命令模式,用戶就可以看見在屏幕左下方,出現(xiàn)冒號(hào)“:”,這表示vi已經(jīng)進(jìn)入冒號(hào)命令模式,在此可以完成存檔或退出等工作。以下是這種模式下的一些常用命令。² :q!:放棄任何改動(dòng)而退出vi,也就是強(qiáng)行退出。² :w:存檔不退出。² :w!:對(duì)于只讀文件強(qiáng)行存檔。² :wq:存檔并退出vi。² ::x:與wq的工作一樣。注意:在編輯模式下,不能輸入指令,必需先按下Esc鍵,返回命令模式。假若用戶不知身處何態(tài),也可以按下Esc鍵,這時(shí)不管處于何態(tài),都會(huì)返回命令模式。vi還可以同時(shí)編輯多個(gè)文件,它
10、的使用方法是:vi filelist。如同時(shí)編輯2個(gè)文件,復(fù)制一個(gè)文件中的文本并粘貼到另一個(gè)文件中,命令如下:vi file1 file2,回車yy,回車(在文件l的光標(biāo)處復(fù)制所在行):n,回車(切換到文件2(n=next)或者按Ctrl+ww,就在兩個(gè)文件間切換)p,回車(在文件2的光標(biāo)所在處粘貼所復(fù)制的行):n,回車(切換回文件1)如果要在vi執(zhí)行期間,轉(zhuǎn)到shell執(zhí)行,使用驚嘆號(hào)(!)將執(zhí)行系統(tǒng)指令。例如在vi的命令狀態(tài),列出當(dāng)前目錄內(nèi)容,可以輸入:!ls另一方面,用戶可以在主目錄中創(chuàng)建exrc環(huán)境文件,用set設(shè)置選項(xiàng),每次調(diào)用vi時(shí),都會(huì)讀入.exrc中的指令與設(shè)置。以下是exrc
11、環(huán)境文件的應(yīng)用實(shí)例:set wrapmarging=8set showmodeset autoindent gcc編譯器Linux的發(fā)行版本中包含很多的軟件開發(fā)工具,這些軟件開發(fā)工具中很多都是用于C和C+應(yīng)用程序開發(fā)的。Linux上可用的C編譯器是GNU C編譯器,它安裝自由軟件基金會(huì)的GPL條款自由發(fā)布,在Linux的發(fā)行關(guān)盤里面可以找到它?!癵cc”是GNU C編譯器的全稱,此編譯器中集中了C、C+和Objective C三個(gè)編譯版本,可以編譯他們的原程序。gcc是本編譯器的通用名,在強(qiáng)調(diào)編譯C程序時(shí)用的名字。當(dāng)強(qiáng)調(diào)編譯C+程序時(shí),使用的編譯器名稱為g+。gcc編譯器,不僅可以編譯Linu
12、x操作系統(tǒng)下運(yùn)行的應(yīng)用程序和Linux本身,還可以作交叉編譯,編譯運(yùn)行于其他CPU上的程序。可以作交叉編譯的CPU(或DSP)涵蓋了幾乎所有知名,一商的產(chǎn)品。用于嵌入式應(yīng)用的、眾所周知的CPU包括:Intel的i386、Intel960、AMD29K、ARM、M32、MIPS、M68K、ColdFire、PowerPC、68HC11/12、TI的TMS32等。詳細(xì)列表可到/reading網(wǎng)站查看。GNU gcc編譯器是一套完整的交叉C編譯器,包括:² C交叉編譯器gcc。² 交叉匯編工具as。² 反匯編工具0bidump c,
13、178; 連接工具ld。² 調(diào)試工具gbd??梢杂门幚砦募?。MakeFile將上述工具組合成方便的命令行形式。使用gcc編譯C程序生成可執(zhí)行文件有時(shí)似乎是一步完成的,但它其實(shí)要經(jīng)歷如下4個(gè)步驟:(1)預(yù)處理(Preprocessing)。這一步需要分析各種命令,如#define、#include、#ifdef等。gcc調(diào)用cpp程序來進(jìn)行預(yù)處理。(2)編譯(Compilation)。這一步將根據(jù)輸入文件產(chǎn)生匯編語言,由于通常是立即調(diào)用匯編程序,所以其輸出一般不保存在文件中,gcc調(diào)用ccl進(jìn)行編譯工作。(3)匯編(Assembly)。這一步中將匯編語言用作輸入,產(chǎn)生具有.o擴(kuò)展名的
14、目標(biāo)文件。gcc調(diào)用as進(jìn)行匯編工作。(4)連接(Linking)。在這一步,各目標(biāo)文件.o被放在可執(zhí)行文件的適當(dāng)位置上,該程序引用的函數(shù)也放到可執(zhí)行文件中。Gcc調(diào)用連接程序ld來完成最終的任務(wù)。gcc命令的基本用法為:gcc option filename。命令行選項(xiàng)指定的操作將在命令行上每個(gè)給出的文件上執(zhí)行。例如:gcc o prog main.c subr1.c subr2.c subr3.c。其中,“-o prog”指定輸出的可執(zhí)行文件名為prog,如果沒有知道-o參數(shù),gcc將使用默認(rèn)的可執(zhí)行文件名a.out。如果想單獨(dú)編譯每一個(gè)源文件,最后再進(jìn)行連接,可以調(diào)用如下命令:gcc -
15、c mian.cgcc -c subrl.cgcc -c subr2.cgcc -c sunbr3.cgcc -o prog main.o sunbrl.o sunbr2.o sunbr3.o其中,-c選項(xiàng)表示編譯產(chǎn)生目標(biāo)文件,但不連接,最后將所有目標(biāo)文件連接在一起,構(gòu)成可執(zhí)行文件。由于最后一個(gè)命令的輸入都是目標(biāo)文件,不需要編譯和連接,所以gcc就只調(diào)用連接工具ld。gcc的命令選項(xiàng)有許多項(xiàng),但經(jīng)常使用的幾個(gè)選項(xiàng)是:² -c只預(yù)處理、編譯和匯編源程序,不進(jìn)行連接。編譯器對(duì)每一個(gè)源程序都將產(chǎn)生一個(gè)后綴名為.o的目標(biāo)文件。² -o Exefile:確定輸出文件為Exefile,
16、如果沒有指定Exefile,默認(rèn)輸出為可執(zhí)行文件a.out。² -Dmacro或-Dmacro=defn:其作用類似于源代碼程序中的#define。例如:gcc c DHAVE_GDBM_DHELPFILE=”help” cdict.c² 其中,第一個(gè)-D選項(xiàng)定義宏HAVE_GDBM,在程序中可以用#ifdef去檢測(cè)它是否被設(shè)置;第二個(gè)-D選項(xiàng)將宏HELP-FILE定義為字符串“help”(由于反斜線的作用,引號(hào)實(shí)際上已經(jīng)成為該宏定義的一部分),這對(duì)于控制程序打開哪個(gè)文件是很有用的。² -O:對(duì)程序編譯進(jìn)行優(yōu)化,編譯程序試圖減少被編譯程序的長(zhǎng)度和執(zhí)行時(shí)間,但其編譯
17、速度比不進(jìn)行優(yōu)化慢,而且要求較多的內(nèi)存。在編譯嵌入式應(yīng)用軟件時(shí),如果主機(jī)的性能較好,可以打開這個(gè)選項(xiàng)。² -O2:允許比-O更好地優(yōu)化,編譯速度也較之更慢一些,但結(jié)果程序的執(zhí)行速度比較快。² -g:告訴gcc產(chǎn)生能被GNU調(diào)試器使用的調(diào)試信息以便調(diào)試程序。gcc提供了一個(gè)很多其他C編譯器里沒有的特性,即在gcc里能使-g和-O(產(chǎn)生優(yōu)化代碼)聯(lián)用。這點(diǎn)非常有用,因?yàn)槟茉谂c最終產(chǎn)品盡可能相近的情況下調(diào)試代碼。在同時(shí)使用這兩個(gè)選項(xiàng)時(shí)必須清楚所寫的某些代碼已經(jīng)在優(yōu)化時(shí)被gcc作了改動(dòng)。² -pg這個(gè)選項(xiàng)告訴gcc在程序里加入額外的代碼,執(zhí)行時(shí)產(chǎn)生gprof用的剖析信息以
18、顯式程序的耗時(shí)情況。² dir目錄加到搜尋頭文件的目錄列表中去,并優(yōu)先于在gcc中默認(rèn)的搜尋目錄。在有多個(gè)-I選項(xiàng)的情況下,按命令行中I選項(xiàng)的前后順序搜索。dir可以是相對(duì)路徑,如-I./inc等。 編寫Make File在Linux上寫程序的人大都接觸過Makefile,尤其是C語言來開發(fā)程序的人。用make來開發(fā)和編譯程序的確很方便,但是要寫一個(gè)Makefile就不是那么簡(jiǎn)單了。簡(jiǎn)單的來說,Makefile就是目標(biāo)、關(guān)聯(lián)和動(dòng)作三者所組成的一連串規(guī)則。而make會(huì)根據(jù)Makefile的規(guī)則來決定如何編譯和連結(jié)程序。實(shí)際上,make可以做到的不只是編譯和連結(jié)程序,Makefile還可
19、以做到自動(dòng)下載源程序包、解壓縮、打補(bǔ)丁、設(shè)定,然后編譯并安裝至系統(tǒng)中。如果一個(gè)適當(dāng)?shù)腗akeFile文件存在,當(dāng)改變某些源文件后,只要在shell下使用make命令就可以完成所有必需的重新編譯。make程序利用MakeFile文件中的數(shù)據(jù)和每個(gè)文件最近一次更改的時(shí)間來確定哪些文件需要更新。對(duì)于需要更新的文件,make程序使用MakeFile中定義的命令來更新。至于使用哪個(gè)MakeFile文件來更新,可以在make命令中用-f選項(xiàng)來指定。如果不指定,make程序?qū)⒃诋?dāng)前目錄下按下列順序?qū)ふ胰缦挛募篏UNMakeFile、MakeFile和MakeFile。最好是使用MakeFile,因?yàn)樗牡?/p>
20、一個(gè)字母是大寫的,通常被列在一個(gè)文件目錄的所有文件列表的最前面,便于查找。1. 編寫規(guī)則下面對(duì)組成MakeFile文件的一些規(guī)則加以說明。在這之前首先介紹目標(biāo)(target)及相關(guān)性的概念。² 目標(biāo)就是make程序要完成的一項(xiàng)任務(wù),目標(biāo)通常是一個(gè)文件的文件名,也有例外。² 相關(guān)性即一個(gè)目標(biāo)的完成依賴于其他一些目標(biāo)或文件。MakeFile文件中包含著一些目標(biāo),對(duì)于每一個(gè)目標(biāo),都提供了與這個(gè)目標(biāo)具有相關(guān)性的其他目標(biāo)或文件的名字,以及實(shí)現(xiàn)這個(gè)目標(biāo)的一組命令。它的書寫規(guī)則是:目標(biāo)屬性分隔符號(hào)依賴文件;命令列<tab>命令列與Linux下面的命令格式相同,中的內(nèi)容表示可選
21、,中的內(nèi)容表示可以出現(xiàn)多次。下面對(duì)幾個(gè)條目的意義進(jìn)行說明:² 屬性:表示該目標(biāo)文件的屬性。² 分隔符:用來分割目標(biāo)文件和依賴文件的符號(hào),如冒號(hào)“:”等。² 依賴文件:實(shí)現(xiàn)目標(biāo)所需要的文件的列表。² 命令列:重新生成目標(biāo)的命令,可以有多條命令。除第一條命令外,以后的每一條命令都必須以制表鍵Tab隔開。下面通過一個(gè)簡(jiǎn)單的MakeFile文件的應(yīng)用實(shí)例加以說明:exeProg: main.o subfunc.ogcc o exeProg main.o subfunc.omain.o: main.c main,hgcc c I.-o main.o main.cs
22、ubfunc.o:subfunc.cgcc c o subfunc.o subfunc.cclean:rm f*.o上面的MakeFile文件共定義了4個(gè)目標(biāo):exeProg、main.o、subfunc.o和clean。每個(gè)目標(biāo)都是從最左邊開始寫,后面跟一個(gè)冒號(hào)(:),如果這個(gè)目標(biāo)的實(shí)現(xiàn)依賴于其他的目標(biāo)或文件,把它們列在冒號(hào)的后面,并以空格隔開。然后另起一行開始寫實(shí)現(xiàn)這個(gè)目標(biāo)的一組shell命令。shell命令可以有若干行。注意:每個(gè)shell命令的第一個(gè)按鍵必須是字符或數(shù)字,不能以空格開頭,否則make就會(huì)顯示如下出錯(cuò)信息:MakeFile:2:*missing separator.Sto
23、p。一般情況下,調(diào)用make可以輸入:make targettarget是MakeFile文件中定義的目標(biāo),如果省略target,make就將更新MakeFile文件的第一個(gè)目標(biāo)。例如在上一個(gè)實(shí)例中,若輸入make命令不帶target參數(shù),將更新目標(biāo)exeProg。make在檢查一個(gè)目標(biāo)是否已經(jīng)過時(shí)并需要更新時(shí),采用的是按相關(guān)性遞歸的方法。make在構(gòu)建一個(gè)目標(biāo)之前要生成該目標(biāo)所依賴的所有文件,并遞歸地前進(jìn),從而確保這些文件都是新的。具體構(gòu)建目標(biāo)的過程如下:(1)如果一個(gè)目標(biāo)task不是作為文件而存在,那它就已經(jīng)過時(shí)了,命令maketask必定執(zhí)行該任務(wù)。 (2)make檢查所有與task有相
24、關(guān)性的目標(biāo)。對(duì)于不是MakeFile中定義的任務(wù),而只是文件的相關(guān)目標(biāo),則檢查相關(guān)目標(biāo)的生成日期是否比task文件的生成日期更近,如果有一個(gè)更近則task就過時(shí)了。對(duì)于MakeFile定義為任務(wù)的相關(guān)目標(biāo),則按同樣的方法檢查其是否過時(shí),如果任意一個(gè)過時(shí)了,都需要更新。(3)遞歸從底層向上,對(duì)所有已經(jīng)過時(shí)的目標(biāo)進(jìn)行更新,只有當(dāng)一個(gè)目標(biāo)所依賴的所有目標(biāo)都已經(jīng)更新后,這個(gè)目標(biāo)才被更新。通過上面的例子來說明目標(biāo)的更新過程。在這里假設(shè)修改r文件subfunc.c,可用以下命令更新目標(biāo)exeProg,即重新編譯可執(zhí)行文件exeProg。% make exeProg由于exeProg依賴于目標(biāo)main.o和
25、subfunc.o,所以必須檢查main.o和subfunc.o是否已經(jīng)過時(shí)。目標(biāo)文件main.o和源文件main.c和main.h,比較目標(biāo)文件main.o和源文件main.c、main.h的更新日期,如發(fā)現(xiàn)main.o比它所依賴的文件的日期更新,即不過時(shí)。再檢查目標(biāo)subfunc.o,它依賴文件subfunc.o,由于已經(jīng)修改了subfunc.c,它比subfunc.o更新,即subfunc.o過時(shí)了,從而依賴subfunc.o的所有目標(biāo)都過時(shí)了。應(yīng)該用在makfile文件中定義好的如下shell命令更新它:gcc c o subfunc.o subfunc.c由于目標(biāo)subfunc.o過
26、時(shí)并更新,導(dǎo)致目標(biāo)exeProg已經(jīng)過時(shí),要完成“make exeProg”的任務(wù),必須用定義exeProg的一組shell命令來更新它:gcc -o exeProg main.o subfunc.o如果是第一次編譯上面這個(gè)軟件,則因?yàn)閑xeProg、main.o和subfunc.o等目標(biāo)文件都不存在,按照規(guī)定,這時(shí)所有的目標(biāo)都是過時(shí)的,必須全部更新,而且必須從底而上執(zhí)行定義這些目標(biāo)的shell命令。在上面的例子中,還定義了一個(gè)目標(biāo)clean,輸入make clean命令將執(zhí)行:rm f *.oclean的目標(biāo)是MakeFile中常用的一種專用目標(biāo),即刪除所有的目標(biāo)模塊。輸入make clea
27、n命令時(shí),make程序?qū)⒉榭匆粋€(gè)名為clean的文件,如果該文件不存在(約定永遠(yuǎn)不在文件目錄中使用該名字作為文件名稱),make將執(zhí)行定義該目標(biāo)的所有命令。2宏和隱含規(guī)則為了簡(jiǎn)化命令的書寫,在:MakeFile中可以使用幾個(gè)預(yù)先定好的縮寫和定義一些宏(macro)。以下是幾個(gè)經(jīng)常用到的縮寫:² $:代表該目標(biāo)的全名。² $*:代表已經(jīng)刪除了后綴名的目標(biāo)名。² $<:代表該目錄的第一個(gè)相關(guān)目標(biāo)名。按照這樣的縮寫,上文中的例子可以改寫為:#樣一個(gè)使用縮寫符的MakeFile例子#以#開頭的一行是注釋行 exeProg:main.o subfunc.o gcc o
28、 $ prog.o subfunc.o main.o: main.c main.h gcc c I o $ $< subfunc.o: subfunc.c gcc c -o $ $*.c clean: rm f *.o這類縮寫對(duì)于編寫默認(rèn)的編譯規(guī)則是很有用的。GNU的make工具除提供建立目標(biāo)的基本功能之外,還有許多便于表達(dá)依建立目標(biāo)的命令特色。其中之一就是變量或宏的定義能力。如果要以相同的編編譯十幾個(gè)C源文件,而為每個(gè)目標(biāo)的編譯指定冗長(zhǎng)的編譯選項(xiàng)的話,將是非但利用簡(jiǎn)單的變量定義,可避免這種乏味的工作。#為編譯器定義一個(gè)宏名CC=gcc#定義編譯宏標(biāo)志CCFLAGS= -D _DEBJG
29、 g -m486#創(chuàng)建一個(gè)目標(biāo)文件test.o:test.c test.h$(CC) c $(CCFLAGS) test.c在上面的實(shí)例中,CC和CCFLAGS都是make的變量。GNU make通常稱之為變量,而其他UNIX的make工具稱之為宏,實(shí)際是同一個(gè)東西。在MakeFile中引用變量的值時(shí),只需在變量名之前添加$符號(hào),如上面的$(CC)和$(CCFLAGS)。如果在MakeFile文件中沒有給出從某一目標(biāo)的相關(guān)文件構(gòu)建這一目標(biāo)的命令,GNUmake包含有一些內(nèi)置的或隱含的規(guī)則,這些規(guī)則定義了如何從不同的依賴文件建立特定類型的目標(biāo)。例如,對(duì)下面的MakeFile文件中的內(nèi)容:#一個(gè)簡(jiǎn)
30、單的使用默認(rèn)規(guī)則的MakeFile例子exeProg:main.o subfunc.ogcc -o exeProg main.o subr.oclean:rm f *.oexeProg的相關(guān)目標(biāo)main.o和subfunc.o的構(gòu)造規(guī)則如果沒有定義,make程序?qū)⑹褂秒[含規(guī)則。默認(rèn)的隱含規(guī)則中可以生成目標(biāo)類型為o文件的相關(guān)文件類型有多種(如.c、cc、.C、.p、.f等)。make程序?qū)错樞蛘页龅谝粋€(gè)存在的或可以構(gòu)建的類型。例如,若它最先找到。main.c,它就使用隱含規(guī)則中的main.c構(gòu)建main.o,如果沒有,就依此類推。GNU make支持兩種類型的隱含規(guī)則,它們的表示方式為:后綴規(guī)
31、則(Suffix Rules):后綴規(guī)則是定義隱含規(guī)則的較老的風(fēng)格方法。后綴規(guī)則定義了將一個(gè)具有某個(gè)后綴的文件(例如c文件)轉(zhuǎn)換為具有另外一種后綴的文件(例如.o文件)的方法。每個(gè)后綴規(guī)則以兩個(gè)成對(duì)出現(xiàn)的后綴名定義。例如,將.c文件轉(zhuǎn)換為.o文件的后綴規(guī)則可定義為:.c.o:$(CC) $(CCFLAGS) $(CPPFLAGS) c o $ $<模式規(guī)則(Pattern Rules):這種規(guī)則更加通用,因?yàn)榭梢岳媚J揭?guī)則定義更加復(fù)雜的依賴規(guī)則。模式規(guī)則看起來非常類似于后綴規(guī)則,但在目標(biāo)名稱的前面多了一個(gè)“”號(hào),同時(shí)可用于定義目標(biāo)和依賴文件之間的關(guān)系,例如下面的模式規(guī)則定義了如何將任意
32、一個(gè)X.c文件轉(zhuǎn)換為X.o文件:%.c:%.o$(CC) $(CCFLAGS) $(CPPFLAGS) c o $ $<以上是MakeFile文件的大體編寫規(guī)范,對(duì)于比較復(fù)雜的軟件包,要自己編寫MakeFile文件也是一件令人煩惱的事。一般來說,這時(shí)軟件提供商會(huì)提供一個(gè)MakeFile的示例文件,在這個(gè)文件的基礎(chǔ)之上按照自己的要求進(jìn)行相應(yīng)的修改就容易多了。另外,也可以使用automake和autoconf軟件來生成MakeFile文件,具體使用方法請(qǐng)查看幫助文件。 debug工具GDB前面介紹了Linux系統(tǒng)下的基本開發(fā)工具,通過這些開發(fā)工具,應(yīng)該可以開發(fā)出您想實(shí)現(xiàn)的軟件。但開發(fā)出來的軟
33、件無可避免地會(huì)出現(xiàn)各種各樣的問題,在編譯源代碼的時(shí)候也可能出錯(cuò)。這時(shí)就需要一個(gè)功能強(qiáng)大的調(diào)試工具,在這里就將介紹在Linux中得到廣泛應(yīng)用的調(diào)試工具GDB。GDB是GNU的一個(gè)重要軟件,最早由Richard Stallman編寫。使用GDB的另一大好處是GDB支持嵌入式軟件的開發(fā)模式交叉調(diào)試,當(dāng)運(yùn)行g(shù)db的Linux平臺(tái)(宿主機(jī))通過串行端口(或網(wǎng)絡(luò)連接,或是其他的方式)連接到目標(biāo)板時(shí),gdb可以對(duì)運(yùn)行在目標(biāo)板上的應(yīng)用程序進(jìn)行調(diào)試。由于這個(gè)特性,許多新開發(fā)的嵌入式操作系統(tǒng)都把GDB移植到其上作為調(diào)試工具。GDB能夠觀察另一個(gè)程序在執(zhí)行時(shí)的內(nèi)部活動(dòng),或程序出錯(cuò)時(shí)發(fā)生了什么?GDB的主要功能有以下
34、幾點(diǎn):² 設(shè)置運(yùn)行環(huán)境和參數(shù),運(yùn)行指定程序。² 讓程序在指定條件下停止和運(yùn)行。² 在程序運(yùn)行停止后,檢查變量、內(nèi)存或寄存器的值,查看程序運(yùn)行情況。² 修改正在調(diào)試的程序的源代碼,這樣可以在線修正某個(gè)bug引起的問題,然后繼續(xù)查找下一個(gè)bug。GDB的使用可以直接在shell命令行下輸入gdb并按回車鍵,再在gdb命令行下指定要調(diào)試的程序;也可以用gdb filename在啟動(dòng)時(shí)指定要調(diào)試的程序名。如果正常啟動(dòng),屏幕將出現(xiàn)類似于以下的信息,并進(jìn)入GDB命令模式:GNU gdb Red Hat Linux 7.x(5.0rh_15)(MI_OUT)Copyr
35、ight 2001 Free Software Foundation,IncGDB is free software,covered by the GNU General Public License,and you are welcome to change it and/or distribute copies of it under certain conditionsType “show copying” to see the conditionsThere is absolutely no warranty for GDB.Type “show warranty” fordetail
36、sThis GDB was configured as “i386一redhatlinux”(gdb)GDB可以運(yùn)行在許多模式下,這些模式是在GDB運(yùn)行時(shí)在命令行作為選項(xiàng)指定的。下面將對(duì)這些模式進(jìn)行相應(yīng)的說明。² -nx或-n:不執(zhí)行任何初始化文件中的命令(一般GDB的初始化文件名gdbinit)。一般情況下在這個(gè)文件中的命會(huì)將所有 的命令行參數(shù)傳遞給GDB后執(zhí)行。² -quiet或-q:安靜模式。不輸出上面顯示的介紹和版本信息。這些信息在“批處理”中也將被跳過。² -batch:批處理模式。當(dāng)在批處理命令文件中的 所有命令都被執(zhí)行后,GDB將返回狀態(tài)0;如果執(zhí)行
37、過程出錯(cuò),將返回0值。² -cd DIRECTORY:把DIRECTORY作為GDB的工作目錄,這時(shí)工作目錄不再是當(dāng)前目錄(在一般情況下,GDB默認(rèn)把當(dāng)前目錄作為工作目錄)。² -b BIT/S:為遠(yuǎn)程調(diào)試設(shè)置串口波特率。² -tty設(shè)備名:使用其他設(shè)備作為程序的標(biāo)準(zhǔn)輸入輸出。這種模式對(duì)于嵌入式交叉調(diào)試很有用。在GDB啟動(dòng)后,就進(jìn)入GDB命令方式,這時(shí)就可以使用GDB的各種命令進(jìn)行調(diào)試了。下面對(duì)它的各種調(diào)試命令進(jìn)行詳細(xì)說明。為了使GDB能夠正常工作,必須使程序在編譯時(shí)包含調(diào)試信息。具體的調(diào)試信息包括程序里的每個(gè)變量的類型、在可執(zhí)行文件里的地址映射以及源代碼的行號(hào)等
38、。如果沒有這些信息,GDB就默認(rèn)到init.c中,這時(shí)就無法調(diào)試。若要使編譯時(shí)包含這些信息,只需在使用gcc時(shí)加-g選項(xiàng)即可。下面對(duì)常用的GDB命令加以說明。² 載入程序命令:file在GDB內(nèi),載入程序很簡(jiǎn)單,使用file命令。如要加載hello程序用file hello。當(dāng)然,程序的路徑名要正確。² 退出GDB命令:quit在GDB的命令方式下,輸入quit,就可以退出GDB。也可以輸入C -d來退出GDB。² 運(yùn)行程序命令:run當(dāng)在GDB中已將要調(diào)試的程序載入后,可以用run命令來執(zhí)行。如果程序需要參數(shù),可以在run指令后接著輸入?yún)?shù),就像在Shell下執(zhí)
39、行一個(gè)需要參數(shù)的命令一樣。² 查看程序信息命令:infoinfo指令用來查看程序的信息,它的參數(shù)非常多,但大部分不常用。一般用info指令最多的是用它來查看斷點(diǎn)信息:info br,這時(shí)可以得到所設(shè)置的所有斷點(diǎn)的詳細(xì)信息,包括斷點(diǎn)號(hào)、類型、狀態(tài)、內(nèi)存地址、斷點(diǎn)在源程序中的位置等。info source可以查看當(dāng)前源程序。² 列出源程序命令:list這個(gè)命令從頭開始將列出源程序代碼,重復(fù)使用這個(gè)命令會(huì)接著前一次繼續(xù)顯示。若要列出某個(gè)指定函數(shù):list FUNCTION。若以當(dāng)前源文件的某行為中間顯示一段源程序list LINENIJM,將顯示另一個(gè)文件的一段程序:list F
40、ILENAME:FUNCTION或list FILENAME:LINENUM。² 設(shè)置斷點(diǎn)命令:break這是最常用和最重要的命令,無論何時(shí),只要程序已被載入,并且當(dāng)前沒有正在運(yùn)行,修改、刪除斷點(diǎn)。設(shè)置斷點(diǎn)的命令是break。有許多種設(shè)置斷點(diǎn)的方法,如在函數(shù)入口設(shè)置斷點(diǎn):break FUNCTION;在當(dāng)前源文件的某一行上設(shè)置斷點(diǎn):break LINENUM;在另一個(gè)源文件的某一行上設(shè)置斷點(diǎn):break FILENAME:LINENUM;在某個(gè)地址上設(shè)置斷點(diǎn),當(dāng)調(diào)試的程序沒有源程序時(shí),可以用break *ADDRESS。除此之外,設(shè)置一個(gè)斷點(diǎn),讓它只有在某些特定的條件成立時(shí)程序才會(huì)停
41、下來,可以稱其為條件斷點(diǎn),它的命令格式breakif COND。COND是一個(gè)布爾條件表達(dá)式,語法與C語言中的一樣。條件斷點(diǎn)與一般的斷點(diǎn)不同之處是每當(dāng)程序執(zhí)行到斷點(diǎn)處,都要計(jì)算條件表達(dá)式,如果為真,程序才會(huì)停下來,否則程序會(huì)一直執(zhí)行下去。² 設(shè)置監(jiān)視點(diǎn)命令:watch當(dāng)調(diào)試一個(gè)很大的程序,并且在跟蹤一個(gè)關(guān)鍵的變量時(shí),發(fā)現(xiàn)這個(gè)變量不知在哪兒被改動(dòng)過,如何才能找到改動(dòng)它的地方?這時(shí)可以使用watch命令。簡(jiǎn)單地說,監(jiān)視點(diǎn)可以監(jiān)視某個(gè)表達(dá)式或變量,當(dāng)它被讀或被寫時(shí)讓程序停下來。watch命令的用法如下:watch EXPRESSIONwatch指令是監(jiān)視寫操作的,當(dāng)用戶想監(jiān)視某個(gè)表達(dá)式或變
42、量的讀操作的話,需要使用rwatch指令,具體用法是一樣的。² 顯示表達(dá)式值的命令:print最常用的檢查數(shù)據(jù)的方法是:print exp,print指令將打印exp表達(dá)式的值。默認(rèn)情況下,表達(dá)式的值的打印格式依賴于它的數(shù)據(jù)類型。但可以用一個(gè)參數(shù)/F來選擇輸出的打印格式。表達(dá)式exp中的變量必須是全局變量或當(dāng)前堆棧區(qū)可見的變量。否則GDB會(huì)顯示像下面的一條信息:No symbol ”variable” in current context² 單步執(zhí)行指令:step或next單步執(zhí)行指令有step和next。step可以跟蹤進(jìn)入一個(gè)函數(shù),而next指令則不會(huì)進(jìn)入函數(shù)。
43、8; 繼續(xù)執(zhí)行命令:continue當(dāng)程序被停下來后,查看了所需的信息后,如希望程序執(zhí)行下去,可輸入continue,這時(shí)程序?qū)?huì)繼續(xù)執(zhí)行下去。² 產(chǎn)生可執(zhí)行文件命令:make通過make不用退出GDB就可以重新產(chǎn)生可執(zhí)行文件。² shell命令不離開GDB就可以執(zhí)行UNIX shell命令。在嵌入式Linux軟件開發(fā)中,使用GDB交叉調(diào)試有兩種方式:² 目標(biāo)機(jī)上的嵌入式Linux系統(tǒng)包含GDB工具。這時(shí)可以利用TFTP把在宿主機(jī)上開發(fā)的應(yīng)用軟件用mount命令掛載到目標(biāo)機(jī)的一個(gè)開發(fā)目錄下,再在主機(jī)上啟動(dòng)minicom超級(jí)終端,登錄到目標(biāo)機(jī)上。啟動(dòng)目標(biāo)機(jī)的GDB程
44、序,運(yùn)行應(yīng)用程序,之后就可以對(duì)應(yīng)用程序進(jìn)行調(diào)試了,調(diào)試的信息可以在minicom中看到。我們的PXA270RP實(shí)驗(yàn)箱上應(yīng)用程序開發(fā)就屬于這種方式。² 目標(biāo)板中不支持GDB,這時(shí)就要在主機(jī)上運(yùn)行GDB,利用GDB的遠(yuǎn)程調(diào)試功能。在目標(biāo)板上也要有一個(gè)名為stub的伺服程序,這個(gè)程序的作用是接受GDB的調(diào)試命令,解釋執(zhí)行,并按命令要求把調(diào)試結(jié)果返回給GDB。例如,通過串口線的方式,在本地主機(jī)上輸入target remote /dev/ttyS0命令,本地主機(jī)就可通過窗口1和遠(yuǎn)程主機(jī)里面的stub程序相連接。當(dāng)然,對(duì)于不同的體系結(jié)構(gòu)的系統(tǒng),需要編寫不同的stub程序,在GDB的發(fā)布套件里面提
45、供了默認(rèn)stub文件,如針對(duì)Sparc機(jī)器的sparc-stub.c文件、針對(duì)m68000的m68k-stub.c的Intel 386的i386-stub.c文件。以上是GDB工具相關(guān)知識(shí)的介紹,在嵌入式Linux應(yīng)用軟件開發(fā)中,熟練地使用GDB是必要的,在以后的實(shí)例中也將繼續(xù)介紹GDB在項(xiàng)目中的實(shí)際應(yīng)用。3.2 嵌入式Linux驅(qū)動(dòng)程序開發(fā) 嵌入式系統(tǒng)設(shè)備驅(qū)動(dòng)Linux設(shè)備驅(qū)動(dòng)程序是內(nèi)核的一部分,它完成以下功能:對(duì)設(shè)備初始化和釋放;把數(shù)據(jù)從內(nèi)核傳送到硬件和從硬件讀取數(shù)據(jù);讀取應(yīng)用程序傳送給設(shè)備文件的數(shù)據(jù)和回送應(yīng)用程序請(qǐng)求的數(shù)據(jù);檢測(cè)和處理設(shè)備出現(xiàn)的錯(cuò)誤。也就是說設(shè)備驅(qū)動(dòng)擔(dān)當(dāng)著連接硬件和內(nèi)核的
46、橋梁的角色,如圖示:應(yīng)用程序文件系統(tǒng)操作系統(tǒng)設(shè)備驅(qū)動(dòng)程序硬件設(shè)備圖 設(shè)備驅(qū)動(dòng)與硬件、操作系統(tǒng)的關(guān)系設(shè)備驅(qū)動(dòng)直接與底層硬件通信,按照硬件設(shè)備的工作方式來讀寫設(shè)備寄存器,完成設(shè)備的輪詢、中斷處理、DMA通信,進(jìn)行物理內(nèi)存向虛擬內(nèi)存的映射,最終完成通信設(shè)備數(shù)據(jù)的收發(fā),顯示設(shè)備上文字和界面的顯示,存儲(chǔ)設(shè)備完成數(shù)據(jù)和文件的存儲(chǔ)記錄。在Linux系統(tǒng)下,系統(tǒng)調(diào)用是操作系統(tǒng)內(nèi)核和應(yīng)用程序之間的接口,設(shè)備驅(qū)動(dòng)程序是操作系統(tǒng)內(nèi)核和機(jī)器硬件之間的接口。Linux設(shè)備驅(qū)動(dòng)程序?yàn)閼?yīng)用程序屏蔽了硬件細(xì)節(jié),在應(yīng)用程序看來,Linux硬件設(shè)備只是一個(gè)設(shè)備文件,應(yīng)用程序可以像操作普通文件一樣對(duì)硬件設(shè)備進(jìn)行操作。每個(gè)設(shè)備驅(qū)動(dòng)程
47、序都具有以下幾個(gè)特性:² 具有一整套的和硬件設(shè)備通訊的例程,并且提供給操作系統(tǒng)一套標(biāo)準(zhǔn)的軟件接口;² 具有一個(gè)可以被操作系統(tǒng)動(dòng)態(tài)地調(diào)用和移除的自包含組件;² 可以控制和管理用戶程序和物理設(shè)備之間的數(shù)據(jù)流。 隨著當(dāng)前的IC制造業(yè)的發(fā)展使得芯片集成度越來越高,在ARM、PowerPC、MIPS等處理器內(nèi)部都集成了UART、I²C控制器、USB控制器、SDRAM控制器等,有的還集成了片內(nèi)RAM和Flash。在這里我們這里所說的設(shè)備驅(qū)動(dòng),主要是針對(duì)存儲(chǔ)器和外設(shè)(包括處理器內(nèi)部集成的存儲(chǔ)器和外設(shè)),而不是針對(duì)CPU核的。Linux下將存儲(chǔ)器和外設(shè)分為3大類:
48、78; 字符設(shè)備:必須以串行順序依次進(jìn)行訪問的設(shè)備,是順序的數(shù)據(jù)流設(shè)備,這些字符連續(xù)地形成一個(gè)數(shù)據(jù)流,如觸摸屏、鼠標(biāo)、終端等。² 塊設(shè)備:可以用任意順序進(jìn)行訪問,以塊為單位進(jìn)行操作,這種設(shè)備使用緩沖區(qū)來存放暫時(shí)的數(shù)據(jù),等待條件成熟以后,從緩存一次性寫入設(shè)備或從設(shè)備中一次性讀出放入到緩沖區(qū),如硬盤、軟驅(qū)等。² 網(wǎng)絡(luò)設(shè)備:通過BSD socket接口訪問的設(shè)備,在系統(tǒng)和驅(qū)動(dòng)程序之間定義有專門的數(shù)據(jù)結(jié)構(gòu)(sk_buff)進(jìn)行數(shù)據(jù)的傳遞。系統(tǒng)里支持對(duì)發(fā)送數(shù)據(jù)和接收數(shù)據(jù)的緩存,提供流量控制機(jī)制,提供對(duì)多協(xié)議的支持。字符設(shè)備不經(jīng)過系統(tǒng)的快速緩沖,而塊設(shè)備經(jīng)過系統(tǒng)的快速緩沖。但是塊設(shè)備和
49、字符設(shè)備并沒有明顯的界限,如Flash設(shè)備符合塊設(shè)備的特點(diǎn),但是我們?nèi)匀豢梢园阉鳛橐粋€(gè)字符設(shè)備來訪問。字符設(shè)備和塊設(shè)備的取得設(shè)計(jì)呈現(xiàn)出很大的差異,但是對(duì)于用戶而言,他們都使用文件系統(tǒng)的操作接口open()、write()、close()、read()等函數(shù)進(jìn)行訪問。在Linux系統(tǒng)中,網(wǎng)絡(luò)設(shè)備面向數(shù)據(jù)包的接收和發(fā)送而設(shè)計(jì),它并不對(duì)應(yīng)于文件系統(tǒng)的節(jié)點(diǎn)。內(nèi)核與網(wǎng)絡(luò)設(shè)備的通信和內(nèi)核與字符設(shè)備、塊設(shè)備的通信方式完全不同。 Linux設(shè)備驅(qū)動(dòng)原理設(shè)備驅(qū)動(dòng)程序在Linux內(nèi)核中占有極其重要的位置,它是內(nèi)核用于完成對(duì)物理設(shè)備的控制操作的功能模塊。除了CPU、內(nèi)存以及其他很少的幾個(gè)部分以外,所有的設(shè)備控制操
50、作都必須由與被控設(shè)備相關(guān)代碼驅(qū)動(dòng)程序來完成。否則設(shè)備就無法在Linux下正常工作,這就是驅(qū)動(dòng)程序開發(fā)成為L(zhǎng)inux內(nèi)核開發(fā)的主要工作的原因。在Linux內(nèi)核中,設(shè)備驅(qū)動(dòng)程序是一個(gè)獨(dú)立的黑盒子。它使某個(gè)特定的硬件可以響應(yīng)一個(gè)定義良好的內(nèi)部編程接口,同時(shí)完成隱藏設(shè)備的工作。用戶操作通過一組標(biāo)準(zhǔn)化的調(diào)用完成,而這些調(diào)用是和特定的驅(qū)動(dòng)程序無關(guān)的。將這些調(diào)用映射到作用于實(shí)際硬件的特定操作上,是設(shè)備驅(qū)動(dòng)程序的任務(wù)。這個(gè)編程接口能使得驅(qū)動(dòng)程序獨(dú)立于內(nèi)核的其他部分而建立,在需要的時(shí)候,可在運(yùn)行時(shí)“插入”內(nèi)核。這種模塊化的特點(diǎn),使得Linux驅(qū)動(dòng)程序的編寫非常簡(jiǎn)單。在Linux系統(tǒng)里,對(duì)用戶程序而言,設(shè)備驅(qū)動(dòng)程
51、序隱藏了設(shè)備的具體細(xì)節(jié),對(duì)各種不同設(shè)備提供了一致的接口,一般來說是把設(shè)備映射為一個(gè)特殊的設(shè)備文件(也有設(shè)備不作這樣的映射),用戶可以用訪問普通文件的方式來訪問控制硬件設(shè)備。Linux對(duì)硬件設(shè)備支持兩個(gè)標(biāo)準(zhǔn)接口:塊設(shè)備文件和字符設(shè)備文件,通過塊(字符)設(shè)備文件存取的設(shè)備稱為塊(字符)設(shè)備或具有塊(字符)設(shè)備接口。塊設(shè)備接口僅支持面向塊的I/O操作,所有I/O操作都通過在內(nèi)核地址空間中的I/O緩沖區(qū)進(jìn)行,它可以運(yùn)行幾乎在任意長(zhǎng)度和任意位置上的I/O請(qǐng)求,即提供隨機(jī)存取的功能。字符設(shè)備接口支持面向字符的I/O操作,它不經(jīng)過系統(tǒng)的快速緩存,所以它們負(fù)責(zé)管理自己的緩沖區(qū)結(jié)構(gòu),字符設(shè)備接口只支持順序存取的
52、功能,一般不能進(jìn)行任意長(zhǎng)度的I/O請(qǐng)求,而是限制I/O請(qǐng)求的長(zhǎng)度必須是設(shè)備要求的基本塊長(zhǎng)的倍數(shù)。顯然,程序所驅(qū)動(dòng)的串行卡只能提供順序存取的功能,屬于字符設(shè)備,因此后面的討論在兩種設(shè)備有所區(qū)別時(shí)都只涉及字符型設(shè)備接口,設(shè)備由一個(gè)主設(shè)備號(hào)和一個(gè)次設(shè)備號(hào)標(biāo)識(shí)。主設(shè)備號(hào)唯一標(biāo)識(shí)了設(shè)備類型,即設(shè)備驅(qū)動(dòng)程序類型,它是塊設(shè)備表或字符設(shè)備表中設(shè)備表項(xiàng)的索引,次設(shè)備號(hào)僅由設(shè)備驅(qū)動(dòng)程序解釋,一般用于識(shí)別在若干可能硬件設(shè)備中,I/O請(qǐng)求所涉及到的那個(gè)設(shè)備。設(shè)備程序驅(qū)動(dòng)程序可以分為三個(gè)主要組成:(1)自動(dòng)配置和初始化子程序,負(fù)責(zé)檢測(cè)所要驅(qū)動(dòng)的硬件設(shè)備是否存在和是否能正常工作。如果該設(shè)備正常,則對(duì)這個(gè)設(shè)備及其相關(guān)的設(shè)備
53、驅(qū)動(dòng)程序需要的軟件狀態(tài),進(jìn)行初始化。這部分驅(qū)動(dòng)程序僅在初始化的時(shí)候被調(diào)用一次。(2)服務(wù)于I/O請(qǐng)求的子程序,又稱為驅(qū)動(dòng)程序的上半部分。調(diào)用這部分是由于系統(tǒng)調(diào)節(jié)調(diào)用的結(jié)果。這部分程序在執(zhí)行的時(shí)候,系統(tǒng)仍認(rèn)為是和進(jìn)行調(diào)用的進(jìn)程屬于同一個(gè)進(jìn)程,只是由用戶態(tài)變成了核心態(tài),具有進(jìn)行此系統(tǒng)調(diào)用的用戶程序的運(yùn)行環(huán)境,因此可以在其中調(diào)用sleep()等與進(jìn)程運(yùn)行環(huán)境有關(guān)的函數(shù)。(3)中斷服務(wù)子程序,又稱為驅(qū)動(dòng)程序的下半部分。在UNIX系統(tǒng)中,并不是直接從中斷向量表中調(diào)用設(shè)備驅(qū)動(dòng)程序的中斷服務(wù)子程序,而是由UNIX系統(tǒng)來接收硬件中斷,再由系統(tǒng)調(diào)用中斷服務(wù)子程序,中斷可以產(chǎn)生在任何一個(gè)進(jìn)程運(yùn)行的時(shí)候,因此在中斷
54、服務(wù)程序調(diào)用的時(shí)候,不能依賴于任何進(jìn)程的狀態(tài),也就不能調(diào)用任何與進(jìn)程運(yùn)行環(huán)境有關(guān)的函數(shù)。因?yàn)樵O(shè)備驅(qū)動(dòng)程序一般支持同一類型的若干設(shè)備,所以一般在系統(tǒng)調(diào)用中斷服務(wù)子程序的時(shí)候,都帶有一個(gè)或多個(gè)參數(shù)。 Linux設(shè)備驅(qū)動(dòng)架構(gòu)作為Unix操作系統(tǒng)的一種變種,在Linux下編寫驅(qū)動(dòng)程序的原理和思想完全類似于其他的Unix系統(tǒng)。Linux所有的設(shè)備均作為文件來對(duì)待,這些文件一般被稱為特殊文件,這樣做的一個(gè)好處是使用戶或應(yīng)用程序可按操縱普通文件的方式進(jìn)行訪問控制硬件設(shè)備。在Linux環(huán)境下設(shè)計(jì)驅(qū)動(dòng)程序,思想簡(jiǎn)潔,操作方便,功能也很強(qiáng)大,但是支持函數(shù)少,只能依賴kernel中的函數(shù),有些常用的操作要自己來編寫
55、,而且調(diào)試也不方便。在Linux內(nèi)核中,設(shè)備驅(qū)動(dòng)程序是作為文件系統(tǒng)的一個(gè)模塊存在的,它向下負(fù)責(zé)和硬件設(shè)備的交互,向上通過一個(gè)通用的接口掛接到文件系統(tǒng)上,從而和系統(tǒng)的內(nèi)核等聯(lián)系起來。它是軟件概念和硬件設(shè)備間的一個(gè)抽象層,驅(qū)動(dòng)層在整個(gè)操作系統(tǒng)架構(gòu)中的作用如圖示:用戶應(yīng)用程序編程文件系統(tǒng)接口(C庫函數(shù)等)操作系統(tǒng)Linux文件系統(tǒng)磁盤/Flash文件系統(tǒng)塊設(shè)備驅(qū)動(dòng)字符設(shè)備驅(qū)動(dòng)進(jìn)程管理硬件設(shè)備網(wǎng)絡(luò)接口進(jìn)程調(diào)度內(nèi)存管理圖 驅(qū)動(dòng)程序的角色Linux中的設(shè)備驅(qū)動(dòng)程序有很多的分類方法,從能否動(dòng)態(tài)加載的角度看,可分為可動(dòng)態(tài)加載和卸載的內(nèi)核模塊和靜態(tài)鏈接的內(nèi)核設(shè)備驅(qū)動(dòng)程序兩種類型,不管是哪種類型,從結(jié)構(gòu)上看,整個(gè)
56、驅(qū)動(dòng)程序可分為三個(gè)部分:初始化設(shè)備;獨(dú)立于設(shè)備的接口;硬件設(shè)備I/O。其中硬件I/O部分是和具體硬件相關(guān)的部分,有三種通用機(jī)制可以實(shí)現(xiàn)CPU和外部設(shè)備的數(shù)據(jù)交換:輪詢、DMA、和中斷。從編程角度看,這三種類型有一定的差別,這部分的編程和其它操作系統(tǒng)驅(qū)動(dòng)程序的相應(yīng)部分有一定的相似性,在此不作深入的探討,在實(shí)際編寫時(shí)可參考有關(guān)硬件資料;獨(dú)立于設(shè)備的接口是設(shè)備驅(qū)動(dòng)程序和文件系統(tǒng)連接的橋梁,在Linux中,有很規(guī)范的接口;驅(qū)動(dòng)程序初始化部分負(fù)責(zé)將設(shè)備驅(qū)動(dòng)程序裝載到內(nèi)核或從內(nèi)核中卸載等,此處不詳述。3.3 嵌入式Linux程序開發(fā)初探 第一個(gè)linux C語言程序?yàn)榱朔奖阕x者學(xué)習(xí),我們先寫一個(gè)簡(jiǎn)單的He
57、lloWorld程序,這個(gè)程序的功能很簡(jiǎn)單,就是在linux下利用其本身自帶的編譯器來編寫一下簡(jiǎn)單的C語言程序,并生成可執(zhí)行文件,如圖所示,輸入指令如下:cd /homemkdir experiments /*在home文件夾下建立experiments文件夾*/cd experimentsvi HelloWorld /*利用linux系統(tǒng)的典型編輯器vi來編輯我們的程序*/圖 編輯第一個(gè)程序在編輯器中輸入程序如圖所示:圖 第一個(gè)helloworld程序下面就是編譯、連接和運(yùn)用我們的程序:gcc o HelloWorld HelloWorld.c /*使用linux自帶的編譯器編譯X86程序*/./HelloWorld /*運(yùn)行可執(zhí)行文件,輸出結(jié)果*/圖 運(yùn)行結(jié)果實(shí)驗(yàn)例程解析: 調(diào)用GNU C語言編譯器將我們的C語言源代碼轉(zhuǎn)換為可執(zhí)行文件HelloWorld,運(yùn)行這個(gè)程序,打印出歡迎信息。這只是一個(gè)簡(jiǎn)單的例子,如果不能正常編譯執(zhí)行,那么請(qǐng)檢查你的系統(tǒng)是否安裝了編譯器。可以注意到,我們執(zhí)行可執(zhí)行文件的時(shí)候在前面加了一個(gè)“./”,這樣操作是為了防止shell找不到此程序,在執(zhí)行程序的前面加上此符號(hào),就特別指示shell去執(zhí)行當(dāng)前目錄下給定名稱的程序。如果不加此符號(hào),則執(zhí)行的是主目錄下的程序,在這里我特別指出來,防止以后錯(cuò)誤的出現(xiàn)。 第一個(gè)嵌入式系統(tǒng)
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024汪育與配偶汪某離婚協(xié)議及子女婚嫁籌備費(fèi)用承擔(dān)合同3篇
- 2024房產(chǎn)抵押典當(dāng)借款協(xié)議版A版
- 2025年魯人新版八年級(jí)化學(xué)上冊(cè)月考試卷
- 二零二五年度婚前協(xié)議書:婚姻財(cái)產(chǎn)分配與權(quán)益確認(rèn)6篇
- 2024橋梁鋼結(jié)構(gòu)工程設(shè)計(jì)與施工合同模板3篇
- 二零二五年度人工智能產(chǎn)業(yè)干股入股協(xié)議書模板3篇
- 2024年浙科版選修3地理上冊(cè)月考試卷
- 2024年解除婚姻關(guān)系合同
- 2024年滬科版選修4地理上冊(cè)階段測(cè)試試卷
- xx省生物制造項(xiàng)目可行性研究報(bào)告
- 2023年歷屆華杯賽初賽小高真題
- 網(wǎng)絡(luò)安全培訓(xùn)-網(wǎng)絡(luò)安全培訓(xùn)課件
- 焦作市中佰宜佳材料有限公司年產(chǎn)15萬噸煅后焦項(xiàng)目環(huán)評(píng)報(bào)告
- GB/T 6913-2023鍋爐用水和冷卻水分析方法磷酸鹽的測(cè)定
- 項(xiàng)目部布置圖方案
- 珠海某啤酒廠拆除工程施工方案
- 《文明城市建設(shè)問題研究開題報(bào)告3000字》
- JJF 1357-2012濕式氣體流量計(jì)校準(zhǔn)規(guī)范
- 人教PEP版三年級(jí)上冊(cè)英語 Unit 2 教案 課時(shí)一
- GB/T 17554.1-2006識(shí)別卡測(cè)試方法第1部分:一般特性測(cè)試
- 玲龍醫(yī)用診斷X 射線系統(tǒng) XR 6000維修手冊(cè)
評(píng)論
0/150
提交評(píng)論