亚洲免费av电影一区二区三区,日韩爱爱视频,51精品视频一区二区三区,91视频爱爱,日韩欧美在线播放视频,中文字幕少妇AV,亚洲电影中文字幕,久久久久亚洲av成人网址,久久综合视频网站,国产在线不卡免费播放

        ?

        使用C語言編寫高效嵌入式軟件的教學(xué)探討

        2008-12-31 00:00:00劉曉升
        計(jì)算機(jī)教育 2008年18期

        文章編號:1672-5913(2008)18-0123-02

        摘要:“嵌入式應(yīng)用技術(shù)”課程的一個教學(xué)難點(diǎn)是培養(yǎng)學(xué)生編寫高效嵌入式C語言程序的能力,本文從教學(xué)角度講述了如何讓學(xué)生理解嵌入式軟件時空要求的苛刻性、編寫高質(zhì)量代碼所需的基礎(chǔ)知識以及C語言代碼的常用優(yōu)化方法。

        關(guān)鍵詞:嵌入式軟件;C語言;代碼優(yōu)化

        中圖分類號:G642 文獻(xiàn)標(biāo)識碼:B

        隨著嵌入式系統(tǒng)在汽車電子、工業(yè)控制、智能家居等領(lǐng)域的廣泛使用,大專院校的計(jì)算機(jī)、電子、通信、自動化控制等理工科專業(yè)都開設(shè)了“嵌入式應(yīng)用技術(shù)”課程,編寫高效的嵌入式C語言程序是嵌入式基礎(chǔ)課程學(xué)習(xí)的一個重要環(huán)節(jié),也是一個教學(xué)難點(diǎn)。嵌入式系統(tǒng)受其使用的硬件以及運(yùn)行環(huán)境的限制,對程序運(yùn)行的空間和時間要求非常嚴(yán)格,需要對嵌入式應(yīng)用程序進(jìn)行性能優(yōu)化,以滿足嵌入式應(yīng)用的性能需求。本文結(jié)合作者多年實(shí)際嵌入式系統(tǒng)開發(fā)經(jīng)驗(yàn)及嵌入式應(yīng)用技術(shù)課程教學(xué)體會,探討如何培養(yǎng)學(xué)生編寫高效嵌入式軟件的能力。

        1培養(yǎng)學(xué)生編寫高效嵌入式軟件的意識

        嵌入式系統(tǒng)是以應(yīng)用為中心,以計(jì)算機(jī)技術(shù)為基礎(chǔ),并且軟硬件可裁剪,適用于應(yīng)用系統(tǒng)對功能、可靠性、成本、體積、功耗有嚴(yán)格要求的專用計(jì)算機(jī)系統(tǒng),其核心是嵌入式微處理器。嵌入式系統(tǒng)是一種性價(jià)比很高的應(yīng)用系統(tǒng),為了提高性價(jià)比,一方面在硬件上要進(jìn)行合理配置,另一方面需要提高軟件的效率,充分發(fā)揮硬件的特性,這兩個方面是相輔相成的。但是剛剛接觸嵌入式系統(tǒng)的學(xué)生會缺乏這方面的認(rèn)識,他們往往習(xí)慣于PC機(jī)的程序設(shè)計(jì),很少考慮程序的優(yōu)化。嵌入式系統(tǒng)的運(yùn)算速度、內(nèi)存容量和PC機(jī)相比,差距太大。例如作者在實(shí)現(xiàn)一款方位測定系統(tǒng)時,選用Freescale的MC908MR8作為主控芯片,其最高總線速度為8MHZ、內(nèi)存為256字節(jié)、程序存儲空間才8K。面對這種有限的硬件資源,要實(shí)現(xiàn)高效,一定要區(qū)別于常規(guī)的PC機(jī)編程,要合理使用有限的硬件資源,對每一個內(nèi)存空間的分配、每一條程序語句以及每一個算法都要進(jìn)行仔細(xì)斟酌。

        為了提高學(xué)生對于嵌入式軟件的認(rèn)識,作者在“嵌入式應(yīng)用技術(shù)”課程教學(xué)中特別設(shè)計(jì)了一些教學(xué)案例。例如,假定16位整型數(shù)值X和Y是直角三角形的兩邊,編程求解Y邊所對應(yīng)角的度數(shù)(精確到1度,基于MC908MR8芯片)。當(dāng)時學(xué)生很納悶,這種問題太簡單了,一條C語句就可以實(shí)現(xiàn)了:

        JiaoDu=atan(Y/X)*180/PI;

        的確,通過調(diào)用內(nèi)部函數(shù)atan可以實(shí)現(xiàn)上述功能,但這種方法在低端嵌入式軟件中是一種很糟糕的方法。在MT-IDE For Freescale HC08的集成開發(fā)環(huán)境中,通過查看list列表文件,這條語句編譯后,需要占用8038~8B04,2764字節(jié)的程序存儲空間。假如將這條語句用在上述的方位測定系統(tǒng)中,一條語句就要占MR8三分之一的存儲空間,2764/(8*1024)≈0.33,這是一件很可怕的事情。再仔細(xì)查看list文件,內(nèi)部函數(shù)atan在實(shí)現(xiàn)時使用浮點(diǎn)運(yùn)算,通過泰勒展開式來實(shí)現(xiàn)的,而通常的8位、16位微處理器沒有協(xié)處理器,對于浮點(diǎn)運(yùn)算的處理效率是非常低的。因此,從嵌入式軟件的角度來審視這條語句,它是一個不好的選擇。假如采用查表的思想,將atan(χ) *180/PI預(yù)先計(jì)算出來,建一張表,根據(jù)χ值的不同,查表就可以很快地計(jì)算出角度。通過這種實(shí)例,學(xué)生體會到了高質(zhì)量的嵌入式軟件需要區(qū)別于PC機(jī)的程序設(shè)計(jì)。

        2深入理解匯編語言是編寫高效嵌入式軟件的基礎(chǔ)

        匯編語言是學(xué)習(xí)嵌入式系統(tǒng)的基礎(chǔ),使用匯編程序的優(yōu)點(diǎn)是執(zhí)行效率高,時序控制精確。在剛開始學(xué)習(xí)嵌入式系統(tǒng)時,要克服畏懼匯編語言的心理,一定要先使用匯編語言編寫一些程序,在這個過程中可以深刻理解單片機(jī)的各種概念,特別是指令系統(tǒng)。最近幾年微控制器的發(fā)展很快,其資源有了極大的豐富,但其運(yùn)算速度、存儲容量和PC機(jī)還是有天壤之別,所以在面向低端的嵌入式編程時,對資源的利用還需要精打細(xì)算。通過匯編語言編程,可以更深層次了解微控制器資源的分配情況,養(yǎng)成“節(jié)約”資源的習(xí)慣。同時,掌握了匯編語言,對于以后使用C語言程序時,會恰當(dāng)?shù)剡x擇C語言語句。另外,C語言對編譯器的依賴性較強(qiáng),不同的編譯器編譯出來的目標(biāo)代碼差別較大,通過查看編譯產(chǎn)生的匯編文件,可以提高C語言編程技巧,優(yōu)化C語言程序。

        在上述的實(shí)例中,假如需要分解出角度值(JiaoDu)的百位、十位及個位,通常的編程方法如下:

        BaiWei= JiaoDu /100;

        ShiWei =(JiaoDu %100)/10;

        GeWei= JiaoDu %10;

        這種方法是可行的,但通過閱讀編譯后的list文件,就會發(fā)現(xiàn)它的不足。

        在執(zhí)行除法和求模的運(yùn)算時,調(diào)用了內(nèi)部子程序“__divmodu_16X16_16”進(jìn)行16進(jìn)制的除法和求模運(yùn)算。通過閱讀該子程序的匯編代碼,發(fā)現(xiàn)除法運(yùn)算是通過減法來實(shí)現(xiàn)的, “JiaoDu /100”是每次將JiaoDu減去100,直到JiaoDu小于100為止,循環(huán)減的次數(shù)是商。假如JiaoDu=299°,則“JiaoDu /100”需要進(jìn)行2次循環(huán)減法,“(JiaoDu %100)/10”需要進(jìn)行2+9=11次循環(huán)減法,“JiaoDu %10” 需要進(jìn)行9循環(huán)減法,每一次減法需要大約80個指令周期,則上述程序需要(2+11+9)*80=1760個指令周期,很顯然這是一段效率極低的程序。

        假如熟悉Freescale HC08的指令系統(tǒng),其中有一條除法指令:DIV,7個指令周期,它是將寄存器H和A組成的16位數(shù)除以寄存器X(8位數(shù)),除法運(yùn)算后,商存儲在A中,余數(shù)存儲在H中,即DIV是16位數(shù)除以8位數(shù),商必須是8位。而編譯器在編譯時不知道相除的結(jié)果是否是8位,所以不能使用DIV指令。但在本問題中,由于JiaoDu的范圍是0~360,上述除法運(yùn)算完全可以使用DIV指令。采用C語言中嵌入下面的匯編子程序,可以大大提高程序的執(zhí)行效率。

        __DivMod16X8_8:

        ;(1)進(jìn)棧

        PSHH

        PSHX

        PSHA

        ;(2)百位數(shù)

        LDHX_JiaoDu

        TXA

        LDX#100

        DIV

        STA_BaiWei

        PSHH

        ;(3)十位數(shù)和個位數(shù)

        PULA;H-->A

        CLRH

        LDX#10

        DIV

        STA_ShiWei

        PSHH

        PULA

        STA_GeWei

        ;(4)出棧

        PULA

        PULX

        PULH

        RTS

        用這段程序分解出角度值(JiaoDu)的百位、十位及個位僅僅需要60個指令周期。

        3掌握嵌入式C語言代碼優(yōu)化方法

        3.1數(shù)據(jù)類型的選用

        嵌入式C語言編程不同于一般C語言編程的一個顯著特點(diǎn),就是要和程序存儲器資源結(jié)合起來,雖然其提供的數(shù)據(jù)類型十分豐富,但是只有bit和char等數(shù)據(jù)類型是機(jī)器語言直接支持的數(shù)據(jù)類型,用此類數(shù)據(jù)類型的語句所生成的代碼較短;而其它的數(shù)據(jù)類型如整型、浮點(diǎn)型等數(shù)據(jù)要有一定的內(nèi)部程序或內(nèi)部函數(shù)的支持,相對來說用該類數(shù)據(jù)類型的語句生成的代碼要長。有些C語言程序表面上看起來十分的簡單,但在實(shí)際編譯時,生成的代碼卻相當(dāng)長。因此要按照實(shí)際需要,盡量選用占用存儲空間少的數(shù)據(jù)類型,可以大大的減少所生成的代碼長度。例如在08C中用不同的數(shù)據(jù)類型定義i時,語句

        for(i=0;i<10;i++);

        經(jīng)編譯后生成的代碼長度如表1所示。

        在位操作時選用表2中的語句,可以達(dá)到和匯編相同的執(zhí)行效率。

        3.2使用查表,簡化數(shù)學(xué)計(jì)算

        在程序中盡量不進(jìn)行非常復(fù)雜的運(yùn)算,特別是避免浮點(diǎn)數(shù)的運(yùn)算。對于這些消耗時間和資源的運(yùn)算,可以預(yù)先將函數(shù)值計(jì)算出來,置于程序存儲區(qū)中,以后程序運(yùn)行時直接查表即可,這樣就減小了程序執(zhí)行過程中重復(fù)計(jì)算的工作量。

        在前面所述的計(jì)算JiaoDu值的計(jì)算公式就可以建立以(250*Y/X)的值為表項(xiàng),把Y擴(kuò)大250倍,再除以X,再四舍五入,建立整數(shù)值的一維線性表:

        const unsigned char TanTable[]={0,4,9,13,17,22,26,31,35,

        40,44,49,53,58,62,67,72,76,81,86,

        91,96,101,106,111,117,122,127,133,139,144,150,156,162,169,175,182,188,195,202,210,

        217,225,233,241,250};

        一維線性表的下標(biāo)就是atan(Y/X)*180/PI所對應(yīng)的角度,假如250*Y/X=12,則角度值為3°。這里的表只有0~45°,其原因在于數(shù)學(xué)函數(shù)tan(Y/X)= 90°-tan(X/Y)。所以在編寫程序的時候,靈活地采用一些數(shù)學(xué)方法會對程序帶來方便。

        3.3多分支語句的優(yōu)化

        C語言中有“if—else if”和“switch/case”兩種多分支語句,將最可能發(fā)生的情況放在第一個,最不可能的情況放在最后一個,可以提高分支語句的執(zhí)行速度。

        switch/case語句似乎比if—else if鏈更容易理解,用起來更方便,但引入switch/case語句的初衷并非為了可讀性和便利,而是處于效率的考慮。如果要檢測10個單獨(dú)表達(dá)式的if—else if鏈,所有的情況都互相排斥,并且概率相等,那么程序平均要執(zhí)行5次比較才能碰到值位true的表達(dá)式。在匯編語言中,通過查找表及間接跳轉(zhuǎn),可以花費(fèi)固定時長將控制轉(zhuǎn)往若干不同位置之一,而與情況的數(shù)目無關(guān)。這種代碼使用switch/case表達(dá)式的值作為地址表的索引,間接跳轉(zhuǎn)到表項(xiàng)指定的語句處。當(dāng)情況多于4種時,switch/case比if—else if鏈更快。但是依據(jù)這種方法,switch/case語句有嚴(yán)重缺陷,對表達(dá)式的最小值到最大值中的每個可能的值都必須有表項(xiàng)。所以當(dāng)表達(dá)式的值不連續(xù)且間隔較大時,不適合于使用switch/case,編譯器很難對這種情況做優(yōu)化處理。

        3.4循環(huán)體的優(yōu)化

        循環(huán)體是程序設(shè)計(jì)和優(yōu)化的重點(diǎn),對于一些不需要循環(huán)變量參加運(yùn)算的模塊,可以把它放到循環(huán)的外面。對于次數(shù)固定的循環(huán)體,for 循環(huán)比while 循環(huán)效率更高,減計(jì)數(shù)循環(huán)比增計(jì)數(shù)循環(huán)速度快。

        實(shí)際運(yùn)行時,每次循環(huán)需要在循環(huán)體外加兩條指令:一條減法指令(減少循環(huán)計(jì)數(shù)值) 和一條條件分支指令。這些指令稱為“循環(huán)開銷”。在Freescale HC08 處理器上,減法指令需要1個周期,條件分支指令需要3個周期,這樣每個循環(huán)另加了4個周期的開銷。可以采用循環(huán)展開的方法來提高循環(huán)運(yùn)行的速度,即:重復(fù)循環(huán)主題多次,并按同樣的比例減少循環(huán)次數(shù)來減小循環(huán)的開銷,以增加代碼尺寸來換取程序的運(yùn)行速度。

        4小結(jié)

        C語言作為一種通用的高級語言,語言簡潔、緊湊,運(yùn)算符豐富,程序具有很好的移植性,同時,C語言在開發(fā)速度、軟件可靠性以及軟件質(zhì)量等方面都有著明顯的優(yōu)勢。因此,C語言適合于嵌入式系統(tǒng)的程序設(shè)計(jì)。但是,如何讓學(xué)生用好C語言,編寫高效的嵌入式軟件,還需要教師在課程教學(xué)中滲透高效C語言編程思想,并通過實(shí)例強(qiáng)化代碼優(yōu)化的方法。只有當(dāng)學(xué)生真正領(lǐng)悟了嵌入式軟件的內(nèi)涵,將代碼優(yōu)化的方法和手段應(yīng)用到實(shí)際的程序設(shè)計(jì)中,才能編寫出高質(zhì)量的嵌入式軟件,從而達(dá)到嵌入式基礎(chǔ)課程的培養(yǎng)目標(biāo)。

        參 考 文 獻(xiàn)

        [1] 王宜懷,劉曉升. 嵌入式應(yīng)用技術(shù)基礎(chǔ)教程[M]. 北京:清華大學(xué)出版社,2005.

        [2] 王軍安. 淺析嵌入式系統(tǒng)的軟件優(yōu)化設(shè)計(jì)[J]. 計(jì)算機(jī)工程與應(yīng)用,2004:102-103.

        [3] 劉劍鳴. 嵌入式程序設(shè)計(jì)中C/C++代碼的優(yōu)化[J]. 微計(jì)算機(jī)信息(測控自動化),2003,19(12).

        [4] 韓東海 譯. 編程卓越之道(第二卷):運(yùn)用底層語言思想編寫高級語言代碼[M]. 北京:電子工業(yè)出版社,2006.

        国产激情视频白浆免费| 亚洲人成网77777色在线播放| 欧美丰满熟妇bbbbbb| 性大片免费视频观看| 一区二区三区日本大片| 在线观看一区二区三区视频| 国产人妻鲁鲁一区二区| 全部孕妇毛片丰满孕妇孕交| 国模无码视频专区一区| 日本人妻三级在线观看| 欧美v国产v亚洲v日韩九九| 无码av免费一区二区三区试看| 国产熟女亚洲精品麻豆| 青青草绿色华人播放在线视频 | 精品一区二区在线观看免费视频| 在线观看成人无码中文av天堂| 日本夜爽爽一区二区三区| 久久久久无码精品国| 成人国产精品三上悠亚久久 | 国产精品后入内射日本在线观看 | 亚洲一区二区三区国产精品视频| 国产精品一区二区av麻豆日韩| 久久久久久人妻一区精品| 四虎永久在线精品免费观看地址| 91精品国产乱码久久久| 亚洲av不卡免费在线| 欧美 丝袜 自拍 制服 另类 | 亚洲av成人一区二区三区色| 精品国产亚洲级一区二区| 亚洲亚洲人成综合网络| 国内精品人妻无码久久久影院94| 熟女不卡精品久久av| 国产无遮挡aaa片爽爽| 长腿校花无力呻吟娇喘的视频| 国产伦码精品一区二区| 日韩中文字幕素人水野一区| 国内精品视频在线播放不卡| 91亚洲无码在线观看| 国产一区二区三区在线观看蜜桃 | 国产成人a∨激情视频厨房| 日本大片免费观看完整视频|