嵌入式系統(tǒng)設(shè)計(jì)與開發(fā)教程 課件 第3章 Linux系統(tǒng)編程基礎(chǔ)-2_第1頁
嵌入式系統(tǒng)設(shè)計(jì)與開發(fā)教程 課件 第3章 Linux系統(tǒng)編程基礎(chǔ)-2_第2頁
嵌入式系統(tǒng)設(shè)計(jì)與開發(fā)教程 課件 第3章 Linux系統(tǒng)編程基礎(chǔ)-2_第3頁
嵌入式系統(tǒng)設(shè)計(jì)與開發(fā)教程 課件 第3章 Linux系統(tǒng)編程基礎(chǔ)-2_第4頁
嵌入式系統(tǒng)設(shè)計(jì)與開發(fā)教程 課件 第3章 Linux系統(tǒng)編程基礎(chǔ)-2_第5頁
已閱讀5頁,還剩49頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

嵌入式系統(tǒng)的組成外圍硬件嵌入式處理器操作系統(tǒng)應(yīng)用程序軟件系統(tǒng)開發(fā)環(huán)境編譯下載和調(diào)試系統(tǒng)引導(dǎo)中間軟件硬件系統(tǒng)第7章linux編程基礎(chǔ)

編寫簡單的C語言程序,使用gcc編譯器將程序編譯為可執(zhí)行程序QtopiaCore應(yīng)用程序設(shè)計(jì)

利用qt平臺(tái),編寫可視化的GUIAPP第3章Linux系統(tǒng)編程基礎(chǔ)#include<stdio.h>intmain(void){intx;printf(“Helloworld!\n”);return0;}源程序:hello.c如何變成可執(zhí)行的程序?嵌入式應(yīng)用的生成編譯(Compile)是指從高級(jí)語言轉(zhuǎn)換成匯編語言的過程。從本質(zhì)上編譯是一個(gè)文本轉(zhuǎn)換的過程(從文本文件到文本文件)。編譯包含了C語言的語法解析和生成匯編語言兩個(gè)步驟。匯編(Assemble)是指從匯編語言程序生成目標(biāo)系統(tǒng)的二進(jìn)制代碼(機(jī)器代碼)的過程。相對(duì)于編譯過程的語法解析,匯編的過程相對(duì)簡單。這是因?yàn)閷?duì)于一款特定的處理器,其匯編語言和二進(jìn)制的機(jī)器代碼是一一對(duì)應(yīng)的。鏈接(Link)過程將匯編成的多個(gè)機(jī)器代碼組合成一個(gè)可執(zhí)行程序。一般來說,通過編譯和匯編過程,每一個(gè)源文件將生成一個(gè)目標(biāo)文件。鏈接器的作用就是將這些目標(biāo)文件組合,組合的過程包括了代碼段、數(shù)據(jù)段等部分的合并,以及添加相應(yīng)的文件頭。GNUTools綜述GNUTools是Linux環(huán)境下的開發(fā)工具,用于代碼的生成。GNUTools的重要組成部分是GCC。GCC

是GNUCompilerCollection的縮寫,是一個(gè)非常優(yōu)秀的跨平臺(tái)編譯器集合,支持x86、ARM、MIPS和PowerPC等多種目標(biāo)平臺(tái),支持C、C++、Java、ADA、Fortran和Pascal等多種高級(jí)語言。GNUTools綜述文件類型擴(kuò)展名文件說明文本文件*.cC語言源文件*.C/*.cxx/*.cppC++語言源文件*.i預(yù)處理后的C語言源文件*.ii預(yù)處理后的C++語言源文件*.s*.S匯編語言*.h頭文件二進(jìn)制文件.o目標(biāo)文件.so動(dòng)態(tài)庫.a靜態(tài)庫GNUTools綜述

預(yù)處理

編譯

匯編

鏈接編譯原理gcc/g++在執(zhí)行編譯的時(shí)候,只要分四個(gè)階段:階段功能工具生成文件預(yù)處理完成宏定義和include文件展開等工作預(yù)處理器無(.i)編譯根據(jù)編譯參數(shù)進(jìn)行不同程度的優(yōu)化,編譯成匯編代碼;gcc匯編文件.s匯編用匯編器把匯編代碼進(jìn)一步生成目標(biāo)代碼匯編器as目標(biāo)文件.o鏈接用連接器把生成的目標(biāo)代碼和系統(tǒng)或用戶提供的庫連接起來,生成可執(zhí)行文件鏈接器ld可執(zhí)行文件使用gcc和不同的參數(shù)統(tǒng)一編譯、匯編和鏈接過程gcc編譯格式:編譯器名稱[option][filename]…編譯器:gcc:linux默認(rèn)的c編譯器g++:linux默認(rèn)的c++編譯器arm-linux-gcc:arm開發(fā)板的c編譯器,需要安裝編譯原理gcc常用編譯選項(xiàng):-E

只運(yùn)行C預(yù)編譯器cpp,不生成文件-S

只把文件編譯成為匯編代碼-c

只生成object文件,不鏈接-o

生成指定的輸出文件

gcc一般的用法gcc–其他選項(xiàng)要處理的文件-o輸出文件階段功能命令生成文件預(yù)處理完成宏定義展開等工作gcc-Ehello.c–ohello.i無(.i)編譯編譯成匯編代碼;gcc-Shello.i–ohello.s匯編文件.s匯編生成目標(biāo)代碼gcc-chello.s–ohello.o目標(biāo)文件.o鏈接用連接器把生成的目標(biāo)代碼gcchello.o–ohello可執(zhí)行文件#include<stdio.h>intmain(void){printf(“Helloworld!\n”);return0;}gcc編譯gcc-chello.c–ohello.o從.c到.o:從.c到

可執(zhí)行程序一步到位:gcchello.c–ohellogcc-chello.c–ohello.ogcchello.o-ohello從.c到.o,->可執(zhí)行程序:gcc編譯錯(cuò)誤類型第一類∶C語法錯(cuò)誤錯(cuò)誤資訊∶文件中第n行有語法錯(cuò)誤(syntexerrror)。這種類型的錯(cuò)誤,一般都是C語言的語法錯(cuò)誤,檢查源代碼文件中第n行及該行之前的程序,有時(shí)也需要對(duì)該文件所包含的頭文件進(jìn)行檢查。第二類∶頭文件錯(cuò)誤錯(cuò)誤資訊∶找不到頭文件。這類錯(cuò)誤是源代碼文件中的包含頭文件有問題,可能的原因有頭文件名錯(cuò)誤、指定的頭文件所在目錄名錯(cuò)誤等,也可能是錯(cuò)誤地使用了雙引號(hào)和尖括號(hào)。gcc編譯錯(cuò)誤類型第三類∶檔案庫錯(cuò)誤錯(cuò)誤資訊∶連接程序找不到所需的函數(shù)庫,例如∶ld:-lm:Nosuchfileordirectory這類錯(cuò)誤是與目標(biāo)文件相連接的函數(shù)庫有錯(cuò)誤,可能的原因是函數(shù)庫名錯(cuò)誤、指定的函數(shù)庫所在目錄名稱錯(cuò)誤等。第四類∶未定義符號(hào)錯(cuò)誤資訊∶有未定義的符號(hào)(Undefinedsymbol)。這類錯(cuò)誤是在連接過程中出現(xiàn)的,可能有兩種原因∶一是使用變量但沒有定義;二是未定義的符號(hào)是庫函數(shù),在源程序中使用了該庫函數(shù),而連接過程中還沒有給定相應(yīng)的函數(shù)庫的名稱,可修改gcc連接選項(xiàng)中的-l和-L項(xiàng)。gcc編譯/*main.c*/#include"hello.h"intmain(void){hello();return0;}/*hello1.c*/#include<stdio.h>inthello(void){printf("Helloworld!\n");return0;}/*hello1.h*/inthello(void);可執(zhí)行程序:

hello1一步完成:gccmain.chello1.c-ohello1多步完成:gcc-cmain.c-omain.ogcc-chello1.c-ohello1.ogccmain.ohello1.o-ohello1練習(xí)1:輸入三角形的三條邊的長,判斷是否構(gòu)成等邊三角形、等腰三角形、直角三角形、普通三角形,還是不能構(gòu)成三角形練習(xí)2:輸入一個(gè)整數(shù)n和一個(gè)字符c,輸出菱形圖案,菱形圖案由字符c構(gòu)成,圖案總共2n+1行如輸入:3*輸出:

*

***?

*****?*******?

*****?

***?

*gcc常用編譯選項(xiàng):-w

不生成任何警告信息

-Wall

生成所有級(jí)別的警告信息gcc–ohello–whello.cgcc–ohello–Wallhello.c/***hello.c******/#include<stdio.h>intmain(void){floatx,y;x=2.0;printf(“x=%f\n”,x);}gcc編譯gcc優(yōu)化編譯選項(xiàng):-O0

不進(jìn)行代碼優(yōu)化處理.默認(rèn)值-O,O1

進(jìn)行一般優(yōu)化,在盡可能快的編譯時(shí)間內(nèi)優(yōu)化代碼-O2

進(jìn)一步優(yōu)化,時(shí)間減少但是不增加代碼量,一般在內(nèi)核編譯時(shí)使用

-O3

較-O2進(jìn)一步優(yōu)化,以增大機(jī)器代碼為代價(jià)gcc–ohello1–O1hello.cgcc–ohello2–O2hello.cgcc–ohello3–O3hello.cgcc編譯/***********optimize.c************/#include<stdio.h>intmain(void){doublecounter;doubleresult;doubletemp;for(counter=0;counter<2000.0*2000.0*2000.0/20.0+2020;counter+=(5-1)/4){temp=counter/1979;result=counter;}printf("result=%lf\n",result);return0;}gcc–ooptimize1optimize.cgcc–ooptimize2–O2optimize.cgcc–ooptimize3–O3optimizehello.ctime./optimize1time./optimize2time./optimize3gcc常用編譯選項(xiàng):-lLIBRARY指定鏈接時(shí)需要的其它函數(shù)庫“LIBRARY”-IDIR指定額外的頭文件搜索路徑DIR-LDIR指定額外的庫函數(shù)搜索路徑DIR-g

生成可被gdb使用的標(biāo)準(zhǔn)調(diào)試信息gcc編譯gcc編譯/*main.c*/#include"hello.h"intmain(void){hello();return0;}/*hello.c*/#include<stdio.h>inthello(void){printf("Helloworld!\n");return0;}/*hello.h*/inthello(void);main.chello.chello.h存放在同一個(gè)目錄下-IDIR指定額外的頭文件搜索路徑DIR一步完成:gccmain.chello.c-ohello源程序:main.c

hello.c多步完成:gcc-cmain.c-omain.ogcc-chello.c-ohello.ogccmain.ohello.o-ohello可執(zhí)行程序:

hellogcc編譯-IDIR指定額外的頭文件搜索路徑DIR/*main.c*/#include<hello.h>intmain(void){hello();return0;}/*hello.c*/#include<hello.h>inthello(void){printf("Helloworld!\n");return0;}/*hello.h*/inthello(void);main.chello.c存放在同一個(gè)目錄下hello.h存放另外一個(gè)目錄下:incgcc編譯-IDIR指定額外的頭文件搜索路徑DIR一步完成:gccmain.chello.c-ohello–I./inc多步完成:gcc-cmain.c-omain.o–I./incgcc-chello.c-ohello.o–I./incgccmain.ohello.o-ohellogcc編譯-IDIR指定額外的頭文件搜索路徑DIR/******sinx.c*******/#include<stdio.h>#include<math.h>intmain(void){floatx,y;x=2.0;y=sin(x);printf(“sin(2.0)=%f\n”,y);return0;}gccsinx.c–osinx-Wall-lm-lLIBRARY指定鏈接時(shí)需要的其它函數(shù)庫“LIBRARY”這些庫存放在系統(tǒng)指定的目錄中-lm表示要使用libm.a庫文件和sinx.o鏈接成為可執(zhí)行程序/****libtest.h存放于myinc目錄****///字符串頭尾翻轉(zhuǎn)externvoidreverse_string(charstr[]);//每4個(gè)字符翻轉(zhuǎn)externvoidflip_string(charstr[]);mylib目錄中放了libtest.a庫#include<stdio.h>#include<libtest.h>intmain(void){charstr[20]="abcd12345";printf("orgstring:%s\n",str);reverse_string(str);printf("newstring:%s\n",str);return0;}編譯時(shí)需用-L./mylib指明庫所在的目錄,同時(shí)使用

-ltest指明是用什么庫編譯時(shí)用-I./myinc

指明位置-IDIR指定額外的頭文件搜索路徑DIR-LDIR指定額外的庫函數(shù)搜索路徑DIRgccuselib.c–ouselib–ltest–I./myinc–L./mylib練習(xí):下載libtest.a庫文件和libtest.h頭文件,分別保存在mylib和myinc目錄下,編寫測(cè)試完成頭文件中的函數(shù)的程序。練習(xí)1、熟悉gcc的使用:新建一個(gè)helloworld程序,對(duì)該文件進(jìn)行編譯、匯編、鏈接,生成可執(zhí)行文件。2、建立一個(gè)10個(gè)數(shù)的數(shù)組,找出數(shù)組中第二大和第二小的數(shù),并輸出。編寫該程序,存放為main.c,并編譯成可執(zhí)行程序,運(yùn)行程序。3、在第2題程序的基礎(chǔ)上,新建一個(gè)文件func.c,在該文件中寫出兩個(gè)函數(shù),分別完成尋找數(shù)組的最大值和最小值功能。在main.c中調(diào)用該函數(shù)。編譯成可執(zhí)行程序,運(yùn)行程序。makefile/*main.c*/#include"hello.h"intmain(void){hello();return0;}/*hello.c*/#include<stdio.h>inthello(void){printf("Helloworld!\n");return0;}/*hello.h*/inthello(void);make和makefilemake是一個(gè)工具,一個(gè)編譯管理工具?;蛘哒fmake是一個(gè)命令。用來解決大項(xiàng)目的程序編譯管理問題。make的執(zhí)行依賴于一個(gè)叫做makefile(Makefile)的文件。makefile規(guī)則target:file1file2…//依賴關(guān)系(tab)<command>//編譯命令依賴關(guān)系:執(zhí)行編譯命令前,檢查file1、file2是否被修改過,如果被修改了,才執(zhí)行編譯命令makefile:hello

:hello.c//依賴關(guān)系 gcc–ohellohello.c

//編譯命令參考makefile:makefile規(guī)則/*main.c*/#include"hello.h"intmain(void){hello();return0;}/*hello.c*/#include<stdio.h>inthello(void){printf("Helloworld!\n");return0;}/*hello.h*/inthello(void);makefile規(guī)則makefile:myprog:main.ohello.o//依賴關(guān)系 gcc–omyprog

main.ohello.o//編譯命令main.o:main.chello.h//依賴關(guān)系 gcc–cmain.c//編譯命令hello.o:hello.chello.h//依賴關(guān)系 gcc–chello.c//編譯命令clean: rmmyprogmain.ohello.oMakefile的運(yùn)行

編寫makefile后,在makefile同一個(gè)目錄下運(yùn)行命令make,即可執(zhí)行makefile中的編譯命令。

如果文件的命名不是makefile或者M(jìn)akefile,則需要在make后加入?yún)?shù)格式如下:make–ffilename。make命令運(yùn)行過程1、在makefile所在目錄下運(yùn)行make命令,系統(tǒng)會(huì)自動(dòng)找到makefile中第一個(gè)目標(biāo)(myprog),并以此為最終目標(biāo)文件。2、如果目標(biāo)文件不存在,或者所依賴的文件比目標(biāo)文件的更新時(shí)間更晚,則執(zhí)行該目標(biāo)下的命令重新生成目標(biāo)文件。4、clean:如果與第一個(gè)目標(biāo)(myprog)無關(guān)的目標(biāo),則需要顯式輸入makeclean3、如果依賴的文件不存在,則會(huì)執(zhí)行對(duì)應(yīng)的命令生成依賴文件。Make規(guī)則

make的依賴性,make會(huì)一層又一層地去找文件的依賴關(guān)系,直到最終編譯出第一個(gè)目標(biāo)文件。

在找尋的過程中,如果出現(xiàn)錯(cuò)誤,比如最后被依賴的文件找不到,那么make就會(huì)直接退出,并報(bào)錯(cuò),而對(duì)于所定義的命令的錯(cuò)誤,或是編譯不成功,make根本不理,make只管文件的依賴性。makefile規(guī)則/*main.c*/#include"hello.h“#include“printstar.h”intmain(void){hello();print_star(2,3);return0;}/*hello.c*/#include<stdio.h>inthello(void){printf("Helloworld!\n");return0;}/*hello.h*/inthello(void);/*printstar.c*/#include<stdio.h>include“printstar.h”voidprint_star(unsignedm,unsignedn){unsignedi,j;for(i=0;i<m;i++){for(j=0;j<n;j++)printf(“*”);printf(“\n”);}return;}/*printstar.h*/Voidprint_star(unsignedm,unsignedn);Makefile怎么寫?Makefile變量的使用makefile規(guī)則makefile:myprog:main.ohello.o//依賴關(guān)系 gcc–omyprog

main.ohello.o//編譯命令main.o:main.chello.h//依賴關(guān)系 gcc–cmain.c//編譯命令hello.o:hello.chello.h//依賴關(guān)系 gcc–chello.c//編譯命令clean: rmmyprogmain.ohello.oedit:main.okbd.ocommand.odisplay.o\insert.osearch.ofiles.outils.o cc-oeditmain.okbd.ocommand.odisplay.o\insert.osearch.ofiles.outils.omain.o:main.cdefs.h cc-cmain.ckbd.o:kbd.cdefs.hcommand.h cc-ckbd.ccommand.o:command.cdefs.hcommand.h cc-ccommand.cdisplay.o:display.cdefs.hbuffer.h cc-cdisplay.cinsert.o:insert.cdefs.hbuffer.h cc-cinsert.csearch.o:search.cdefs.hbuffer.h cc-csearch.cfiles.o:files.cdefs.hbuffer.hcommand.h cc-cfiles.cutils.o:utils.cdefs.h cc-cutils.cclean: rmeditmain.okbd.ocommand.odisplay.o\insert.osearch.ofiles.outils.o變量定義

為了makefile的易維護(hù),在makefile中可以使用變量。makefile的變量也就是一個(gè)字符串,理解成C語言中的宏可能會(huì)更好。objects=main.okbd.ocommand.odisplay.o\insert.osearch.ofiles.outils.o變量定義:變量使用:$(objects)edit:main.okbd.ocommand.odisplay.o\insert.osearch.ofiles.outils.o gcc-oeditmain.okbd.ocommand.odisplay.o\insert.osearch.ofiles.outils.omain.o:main.cdefs.h

gcc-cmain.ckbd.o:kbd.cdefs.hcommand.h gcc-ckbd.ccommand.o:command.cdefs.hcommand.h gcc-ccommand.cdisplay.o:display.cdefs.hbuffer.h gcc-cdisplay.cinsert.o:insert.cdefs.hbuffer.h gcc-cinsert.csearch.o:search.cdefs.hbuffer.h gcc-csearch.cfiles.o:files.cdefs.hbuffer.hcommand.h gcc-cfiles.cutils.o:utils.cdefs.h gcc-cutils.cclean: rmeditmain.okbd.ocommand.odisplay.o\insert.osearch.ofiles.outils.o

objects=main.okbd.ocommand.odisplay.o\insert.osearch.ofiles.outils.oedit:$(objects) gcc-oedit$(objects)main.o:main.cdefs.h gcc-cmain.ckbd.o:kbd.cdefs.hcommand.h gcc-ckbd.ccommand.o:command.cdefs.hcommand.h gcc-ccommand.cdisplay.o:display.cdefs.hbuffer.h gcc-cdisplay.cinsert.o:insert.cdefs.hbuffer.h gcc-cinsert.csearch.o:search.cdefs.hbuffer.h gcc-csearch.cfiles.o:files.cdefs.hbuffer.hcommand.h gcc-cfiles.cutils.o:utils.cdefs.h gcc-cutils.cclean: rmedit$(objects)makefile規(guī)則/*main.c*/#include"hello.h"intmain(void){hello();return0;}/*hello.c*/#include<stdio.h>inthello(void){printf("Helloworld!\n");return0;}/*hello.h*/inthello(void);hello:main.ohello.o//依賴關(guān)系 gccmain.ohello.o–ohellomain.o:main.chello.h//依賴關(guān)系 gcc-Wall–O2–cmain.c–omain.ohello.o:hello.chello.h//依賴關(guān)系 gcc-Wall–O2–chello.c–ohello.oclean: rm–rhellomain.ohello.oCC=gccobjs=main.ohello.oCFLAGS=-Wall–O2

hello:$(objs) $(CC)$(objs)–ohellomain.o:main.chello.h $(CC)$(CFLAGS)–cmain.c-omain.ohello.o:hello.chello.h $(CC)$(CFLAGS)–chello.c–ohello.oclean: rm–rhello$(objs)修改后的makefile:ARM編譯器hello:main.ohello.o gccmain.ohello.o–ohellomain.o:main.chello.h gcc-Wall–O2–cmain.c–omain.ohello.o:hello.chello.h gcc-Wall–O2–chello.c–ohello.oclean: rm–rhellomain.ohello.o原來的makefile:CC=arm-linux-gcc幾個(gè)常用的變量$@:擴(kuò)展為當(dāng)前規(guī)則的目標(biāo)文件名$<:擴(kuò)展為當(dāng)前規(guī)則的依賴文件列表中的第一個(gè)文件名$^:擴(kuò)張為當(dāng)前規(guī)則的所有依賴文件(自動(dòng)除去重復(fù)文件)CC=gccobjs=main.ohello.oCFLAGS=-Wall–O2

hello:$(objs) $(CC)–ohello$(objs)main.o:main.chello.h $(CC)$(CFLAGS)–cmain.c-omain.ohello.o:hello.chello.h $(CC)$(CFLAGS)–chello.c–ohello.oclean: rm–rhello$(objs)CC=gccobjs=main.ohello.oCFLAGS=-Wall–O2

hello:$(objs) $(CC)–o$@$^main.o:main.chello.h $(CC)$(CFLAGS)–c$<-o$@hello.o:hello.chello.h $(CC)$(CFLAGS)–c$<–o$@clean: rm–rhello$(objs)練習(xí)一使用變量,修改程序的makefile/*main.c*/#include"hello.h“#include“printstar.h”intmain(void){hello();print_star(2,3);return0;}/*hello.c*/#include<stdio.h>inthello(void){printf("Helloworld!\n");return0;}/*hello.h*/inthel

溫馨提示

  • 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ì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論