第4章嵌入式Linux程序開發(fā)基礎(chǔ)_第1頁
第4章嵌入式Linux程序開發(fā)基礎(chǔ)_第2頁
第4章嵌入式Linux程序開發(fā)基礎(chǔ)_第3頁
第4章嵌入式Linux程序開發(fā)基礎(chǔ)_第4頁
第4章嵌入式Linux程序開發(fā)基礎(chǔ)_第5頁
已閱讀5頁,還剩107頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

第4章

嵌入式Linux程序開發(fā)基礎(chǔ)本章要點1、嵌入式Linux編譯器GCC的使用2、“文件包含”處理3、Make命令和Makefile文件4、嵌入式Linux匯編語言程序設(shè)計基礎(chǔ)知識5、LinuxShell編程方法6、位運算4.1嵌入式Linux編譯器4.1.1Linux下C語言編譯過程1、編輯器2、編譯鏈接器3、調(diào)試器4、項目管理器4.1.2GCC編譯器1、GCC編譯器GCC編譯器能將C、C++語言源程序、匯編語言源程序和目標(biāo)程序編譯、連接成可執(zhí)行文件,如果沒有給出可執(zhí)行文件的名字,GCC將自動生成一個名為a.out的文件。2、GCC的執(zhí)行過程預(yù)處理(也稱預(yù)編譯,Preprocessing)、編譯(Compilation)、匯編(Assembly)和連接(Linking)。System->Administration->SoftwareSources3、GCC的基本用法和選項GCC最基本的用法∶

gcc[options][filenames]-c:只編譯,不連接成為可執(zhí)行文件。-ooutput_filename:確定輸出文件的名稱為output_filename,同時這個名稱不能和源文件同名。-g:產(chǎn)生符號調(diào)試工具(GNU的gdb)所必要的符號資訊,要想對源代碼進行調(diào)試,我們就必須加入這個選項。-O:對程序進行優(yōu)化編譯、鏈接,采用這個選項,整個源代碼會在編譯、鏈接過程中進行優(yōu)化處理,產(chǎn)生的可執(zhí)行文件的執(zhí)行效率較高。4.2“文件包含”處理1、頭文件在C語言中,需要利用頭文件來定義結(jié)構(gòu)、常量以及聲明函數(shù)的原型。大多數(shù)C的頭文件都存放在/usr/include及其子目錄下。引用以上目錄中的頭文件在編譯的時候無需加上路徑,但如果程序中引用了其他路徑的頭文件,需要在編譯的時候用–I參數(shù)。2、“文件包含”處理“文件包含”處理,意思是把另外一個源文件的內(nèi)容包含到本程序中來。其作用是減少編寫程序的重復(fù)勞動,即把一些要重復(fù)使用的東西,編寫到一個“頭文件”(*.h)中,然后在程序中用#include命令來實現(xiàn)“文件包含”的操作。例如:∑n=1+2+3+……+100求和運算。1

#include<stdio.h>2

intmain(){3

intx=100,s=0,i=1;5

while(i<=x)

{6

s=s+i;7

i++;8

}9

printf("sum=%d\n",s);10

return0;11

}為了讓加法部分能重復(fù)使用,將加法部分寫成一個函數(shù)intsum(intn)。

intmysum(intn)

{

inti=1,ss=0;

while(i<=n){

ss=ss+i;

i++;

}

return(ss);

}再在主函數(shù)中調(diào)用它1

#include<stdio.h>2

intmysum(intn);3

intmain()4

{5

intx=100;6

ints=0;7

s=mysum(x);8

printf("sum=%d\n",s);9

return0;10

}注意:上述程序中的第2行語句

intmysum(intn);是必不可少的。由于mysum(intn)函數(shù)的定義是從第11行語句開始,而調(diào)用mysum(intn)函數(shù)的語句在第7行。因此,要在調(diào)用之前聲明這個函數(shù)。下面進一步將程序中具有獨立功能的mysum()函數(shù)分割出來。該程序可分割為下列3個程序:mysum.h、mysum.c和ex_sum.c。(1)程序mysum.h:1/*mysum.h*/2intmysum(intn);(2)程序mysum.c:1./*mysum.c*/2.intmysum(intn)3.{4. inti=1,ss=0;5. while(i<=n){6. ss=ss+i;7. i++;8.

}9. return(ss);10.}(3)主程序ex_sum.c:1./*ex_sum.c*/2.#include<stdio.h>3.#include"mysum.h"4.intmain()5.{6. intx=100;7. ints=0;8. s=mysum(x);9. printf("sum=%d\n",s);10. return0;11.}在Linux環(huán)境下,執(zhí)行編譯程序命令:

gccex_sum.cmysum.c-osum此命令將ex_sum.c和mysum.c編譯成一個在Linux環(huán)境下的可執(zhí)行文件sum。在Linux環(huán)境下運行可執(zhí)行文件sum,

./sum結(jié)果如下:

sum=50504.3

Make命令和Makefile工程管理4.3.1認(rèn)識Make編寫一個Makefile文件如下:sum:ex_sum.omysum.o gccex_sum.omysum.o-osumex_sum.o:ex_sum.c gcc-cex_sum.cmysum.o:mysum.cmysum.h gcc-cmysum.c注意,“gccex_sum.cmysum.c-osum”前面不是空格,而是按下“tab”鍵的符號位。將其保存為:makefile,文件名沒有后綴。然后,在Linux環(huán)境下執(zhí)行make,其運行結(jié)果如下:

#make

gcc-cex_sum.c

gcc-cmysum.c

gccex_sum.omysum.o-osum將ex_sum.c和mysum.c編譯成在Linux環(huán)境下的可執(zhí)行文件sum。

Makefile是一個配置文件Makefile中通常包含如下內(nèi)容:需要由make工具創(chuàng)建的目標(biāo)體,通常是目標(biāo)文件或可執(zhí)行文件;要創(chuàng)建的目標(biāo)體所依賴的文件;創(chuàng)建每個目標(biāo)體時需要運行的命令。Makefile的格式為:

target:dependency_files

command示例main:main.omytool1.omytool2.o

gcc-omainmain.omytool1.omytool2.omain.o:main.c

gcc-cmain.cmytool1.o:mytool1.cmytool1.h

gcc-cmytool1.cmytool2.o:mytool2.cmytool2.h

gcc-cmytool2.c該程序有mytool1.h、mytool2.h、mytool1.c、mytool2.c等文件需要編譯。編寫Makefile文件:再次運行make,這時,make會自動檢查相關(guān)文件的時間戳。首先,在檢查“main”、“main.o”、“mytool1.o”和“mytool2.o”這3個文件的時間戳之前,它會向下查找那些把“main.o”、“mytool1.o”或“mytool2.o”作為目標(biāo)文件的時間戳。如果這些文件中任何一個的時間戳比它們新,則用gcc命令將此文件重新編譯。這樣,make就完成了自動檢查時間戳的工作,開始執(zhí)行編譯工作。這也就是Make工作的基本流程。4.3.2Makefile變量為了進一步簡化編輯和維護Makefile,make允許在Makefile中創(chuàng)建和使用變量。變量是在Makefile中定義的名字,用來代替一個文本字符串,該文本字符串稱為該變量的值。在Makefile中的變量定義有兩種方式:一種是遞歸展開方式,另一種是簡單方式。遞歸展開方式的定義格式為:VAR=var。簡單擴展方式的定義格式為:VAR:=var。

Make中的變量無論采用哪種方式定義使用時格式均為:$(VAR)。例如OBJS=main.omytool1.omytool2.oCC=gccmain:$(OBJS)$(CC)$(OBJS)-omainmain.o:main.c

$(CC)-cmain.cmytool1.o:mytool1.cmytool1.h

$(CC)-cmytool1.cmytool2.o:mytool2.cmytool2.h

$(CC)-cmytool2.c進一步簡化OBJS=main.omytool1.omytool2.oCC=gccmain:$(OBJS)$(CC)$^-o$@main.o:main.c

$(CC)-c$<-o$@mytool1.o:mytool1.cmytool1.h

$(CC)-c$<-o$@mytool2.o:mytool2.cmytool2.h

$(CC)-c$<-o$@4.3.3Makefile規(guī)則Makefile的規(guī)則是Make進行處理的依據(jù),它包括了目標(biāo)體、依賴文件及其之間的命令語句。一般的,Makefile中的一條語句就是一個規(guī)則。1.隱式規(guī)則在使用Makefile時,有一些語句經(jīng)常使用,而且使用頻率非常高的東西,隱式規(guī)則能夠告訴make使用默認(rèn)的方式來完成編譯任務(wù),這樣,當(dāng)用戶使用它們時就不必詳細(xì)指定編譯的具體細(xì)節(jié),而只需把目標(biāo)文件列出即可。Make會自動按隱式規(guī)則來確定如何生成目標(biāo)文件。例如OBJS=main.omytool1.omytool2.oCC=gccmain:$(OBJS)$(CC)$^-o$@2.模式規(guī)則模式規(guī)則規(guī)定,在目標(biāo)文件的定義時需要用“%”字符?!?”的意思是表示一個或多個任意字符,與文件名匹配。例如:“%.c”表示以“.c”結(jié)尾的文件名(文件名的長度至少為3),而“s.%.c”則表示以“s.”開頭,“.c”結(jié)尾的文件名(文件名的長度至少為5個字符)。例如OBJS=main.omytool1.omytool2.oCC=gccmain:$(OBJS)$(CC)$^-o$@%.o:%.c$(CC)-c$<-o$@4.3.4make命令的使用4.4嵌入式Linux匯編語言程序設(shè)計匯編語言的優(yōu)點是執(zhí)行速度快,可以直接對硬件進行操作。嵌入式Linux系統(tǒng)下用匯編語言編寫程序有兩種不同的形式:1、完全匯編代碼2、內(nèi)嵌匯編代碼4.4.1嵌入式Linux匯編語言格式1、嵌入式Linux匯編語言程序結(jié)構(gòu)在嵌入式Linux匯編語言程序中,程序是以程序段(Section)的形式呈現(xiàn)的。程序段是具有特定名稱的相對獨立的指令或數(shù)據(jù)序列。程序段分為代碼段(CodeSection)和數(shù)據(jù)段(DataSection)兩種類型。代碼段的主要內(nèi)容為執(zhí)行代碼,而數(shù)據(jù)段則存放代碼段運行時需要用到的數(shù)據(jù)。一個匯編語言程序至少要有一個代碼段。2、嵌入式Linux匯編語言的語法格式嵌入式Linux匯編語言的語法格式和DOS/Windows下的匯編語言語法格式有較大的差異。DOS/Windows下的匯編語言代碼都是Intel格式,而嵌入式Linux的匯編語言代碼采用的是AT&T格式,兩者在語法格式上有著很大的不同(1)在AT&T匯編格式中,寄存器名要加上'%'作為前綴;而在Intel匯編格式中,寄存器名不需要加前綴。2、嵌入式Linux匯編語言的語法格式(2)在AT&T匯編格式中,用‘$’前綴表示一個立即操作數(shù);而在Intel匯編格式中,立即數(shù)的表示不用帶任何前綴。(3)AT&T和Intel格式中的源操作數(shù)和目標(biāo)操作數(shù)的位置正好相反。在Intel匯編格式中,目標(biāo)操作數(shù)在源操作數(shù)的左邊;而在AT&T匯編格式中,目標(biāo)操作數(shù)在源操作數(shù)的右邊。

2、嵌入式Linux匯編語言的語法格式(4)在AT&T匯編格式中,操作數(shù)的字長由操作符的最后一個字母決定,后綴‘b’、‘w’、‘l’分別表示操作數(shù)為字節(jié)(byte,8比特)、字(word,16比特)和長字(long,32比特);而在Intel匯編格式中,操作數(shù)的字長是用“byteptr”和“wordptr”等前綴來表示的。

(5)在AT&T匯編格式中,絕對轉(zhuǎn)移和調(diào)用指令(jump/call)的操作數(shù)前要加上'*'作為前綴,而在Intel格式中則不需要。

2、嵌入式Linux匯編語言的語法格式(6)在AT&T匯編格式中,內(nèi)存操作數(shù)的尋址方式是section:disp(base,index,scale)而在Intel匯編格式中,內(nèi)存操作數(shù)的尋址方式為:section:[base+index*scale+disp]4.4.2嵌入式Linux匯編程序示例【例4-3】編寫一個最簡單的AT&T格式的匯編程序。用編輯工具編寫如下匯編源程序,并將其保存為hello.s。#hello.s

.data

#數(shù)據(jù)段聲明

msg:.string"Hello,world!\n"#要輸出的字符串

len=.-msg

#字串長度

.text

#代碼段聲明

.global_start

#指定入口函數(shù)

_start:

#在屏幕上顯示一個字符串

movl$len,%edx

#參數(shù)三:字符串長度

movl$msg,%ecx

#參數(shù)二:要顯示的字符串

movl$1,%ebx

#參數(shù)一:文件描述符(stdout)

movl$4,%eax

#系統(tǒng)調(diào)用號(sys_write)

int

$0x80

#調(diào)用內(nèi)核功能

#退出程序

movl$0,%ebx

#參數(shù)一:退出代碼

movl$1,%eax

#系統(tǒng)調(diào)用號(sys_exit)

int

$0x80

#調(diào)用內(nèi)核功能【例4-4】用Intel格式編寫一個與例1相同的簡單匯編程序。;hello.asmsection.data

;數(shù)據(jù)段聲明

msgdb“Hello,world!”,0xA;要輸出的字符串

lenequ$-msg

;字串長度

section.text

;代碼段聲明

global_start

;指定入口函數(shù)_start:

;在屏幕上顯示一個字符串

movedx,len

;參數(shù)三:字符串長度

movecx,msg

;參數(shù)二:要顯示的字符串

movebx,1

;參數(shù)一:文件描述符(stdout)

moveax,4

;系統(tǒng)調(diào)用號(sys_write)

int0x80

;調(diào)用內(nèi)核功能

;退出程序

movebx,0

;參數(shù)一:退出代碼

moveax,1

;系統(tǒng)調(diào)用號(sys_exit)

int0x80

;調(diào)用內(nèi)核功能4.4.3編譯嵌入式Linux匯編程序1、匯編命令[root@localhostasm]#as-ohello.ohello.s2、鏈接命令[root@localhostasm]#ld-s-ohellohello.o3、運行程序[root@localhostasm]#

./hello4.5嵌入式Linuxshell編程shell是用戶與Linux系統(tǒng)間的接口程序,它允許用戶向操作系統(tǒng)輸入需要執(zhí)行的命令。當(dāng)用戶在終端窗口輸入命令,系統(tǒng)會利用解釋器解釋這些命令從而執(zhí)行相應(yīng)的操作。完成這一解釋功能的機制就是shell。shell編程就是把shell命令編寫成可執(zhí)行的腳本文件。4.5.1

shell語法基礎(chǔ)1、shell腳本文件(1)shell腳本文件結(jié)構(gòu)

shell腳本文件結(jié)構(gòu)格式是固定的,看一個示例:

#!

/bin/bash

echo“HelloWorld!”

將文件保存為hello.sh。

shell腳本文件的第1行必須以符號“#!”開頭。使用/bin/bash解釋器來解釋并執(zhí)行程序。

(2)編譯shell腳本文件編譯shell腳本文件的命令為:

chmod+x[文件名]例如:

chmod+xhello.sh(3)執(zhí)行已經(jīng)編譯過了的shell腳本文件

[root@localhostshell]#./hello.sh(4)shell腳本文件的注釋語句以#開頭的語句表示注釋。但腳本第一行用“#!”開頭的語句不是注釋,而是說明shell腳本文件的解釋器。2、shell的變量及配置文件shell腳本文件的變量共有3種:用戶變量、環(huán)境變量、系統(tǒng)變量。(1)用戶變量變量賦值

a="helloworld"(賦值號=的兩側(cè)不允許有空格)獲取變量的值獲取變量的值時,要在變量前面添加“$”符號。例如:

echo$a(2)環(huán)境變量由關(guān)鍵字export說明的變量叫做環(huán)境變量。(3)系統(tǒng)變量常用系統(tǒng)變量:

$0當(dāng)前程序的名稱

$n當(dāng)前程序的第n個參數(shù),n=1,2,…9

$*當(dāng)前程序的所有參數(shù)(不包括程序本身)

$#當(dāng)前程序的參數(shù)個數(shù)(不包括程序本身)

$$當(dāng)前程序的PID

$!

執(zhí)行上一個指令的PID(好像不行?)

$?

執(zhí)行上一個指令的返回值4.5.2

shell的流程控制語句1、條件語句條件if語句的格式為:if(條件表達式)then#語句塊fi2、循環(huán)語句for(循環(huán)變量=初值;循環(huán)條件表達式;循環(huán)變量增量)do#循環(huán)體語句塊done4.5.3

shell編程示例【例4-5】編寫顯示20以內(nèi)能被3整除的數(shù)的shell腳本程序。#!/bin/bashfor((i=1;i<20;i++))doif((i%3==0))thenecho$ifidone將其保存為test1.sh。然后再編譯并執(zhí)行程序。[root@localhostshell]#chmod+xtest1.sh[root@localhostshell]#./test1.sh369121518【例4-6】編寫一個“按任意鍵繼續(xù)......”的shell腳本程序。#!/bin/bashget_char(){stty-echosttyrawddif=/dev/ttybs=1count=12>/dev/nullstty-rawsttyecho}echo“Pressanykeytocontinue......”get_char/dev/null表示空設(shè)備塊大小bs為1,數(shù)目也為1將其保存為test2.sh。然后再編譯并執(zhí)行程序。[root@localhostshell]#chmod+xtest2.sh[root@localhostshell]#./test2.shPressanykeytocontinue......4.6位運算4.6.1位運算符C語言提供了六種位運算符:

&(按位與)、|(按位或)、^(按位異或)、~(取反)、<<(左移)、>>(右移)。1、按位與運算按位與運算:只有對應(yīng)的兩個二進位均為1時,結(jié)果位才為1,否則為0。參與運算的數(shù)以補碼方式出現(xiàn)。

例如:9&5可寫成算式如下:可見9&5=1。按位與運算通常用來對某些位清0或保留某些位。例如把a的高八位清0,保留低八位,可作a&0x00ff運算(0x00ff的二進制數(shù)為0000000011111111)。

main(){

inta=9,b=5,c;

c=a&b;

printf("a=%d/nb=%d/nc=%d/n",a,b,c);

}2、按位或運算只要對應(yīng)的二個二進位有一個為1時,結(jié)果位就為1。例如:9|5可寫算式如下:可見9|5=13。main(){

inta=9,b=5,c;

c=a|b;

printf("a=%d/nb=%d/nc=%d/n",a,b,c);

}

3、按位異或運算當(dāng)兩對應(yīng)的二進位相異時,結(jié)果為1。例如9^5:

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論