導(dǎo)航編程方法_第1頁(yè)
導(dǎo)航編程方法_第2頁(yè)
導(dǎo)航編程方法_第3頁(yè)
導(dǎo)航編程方法_第4頁(yè)
導(dǎo)航編程方法_第5頁(yè)
已閱讀5頁(yè),還剩9頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

1、導(dǎo)航編程方法1. 引言我們中的大多數(shù)人通常編寫運(yùn)行在PC機(jī)上的軟件,如數(shù)據(jù)庫(kù)應(yīng)用、圖像處理、Internet應(yīng)用等,而缺乏編寫嵌入式軟件的經(jīng)驗(yàn)。不幸(遺憾)的是,我們不得不編寫運(yùn)行在導(dǎo)航機(jī)上的程序。在編寫這樣的程序之前,我們需要了解我們將要進(jìn)行的工作和以往的工作有哪些不同,我們所習(xí)慣的編程方法哪些可以繼續(xù)使用,哪些必須改變。2. 內(nèi)存PC機(jī)的一個(gè)最大的優(yōu)勢(shì)是我們可以認(rèn)為有無限多的內(nèi)存,大多數(shù)的PC機(jī)有64M的內(nèi)存,而且Windows提供了虛擬內(nèi)存機(jī)制,使編程者可以任意地使用內(nèi)存,而在導(dǎo)航機(jī)上,我們一共只有4M或8M的內(nèi)存可以使用,這要求我們必須認(rèn)真地考慮在編碼時(shí)如何節(jié)省內(nèi)存,甚至?xí)龅綖榱斯?jié)省

2、內(nèi)存而犧牲效率的情況。 l 不要使用小塊內(nèi)存使用小塊內(nèi)存會(huì)增加系統(tǒng)在管理、檢查內(nèi)存狀態(tài)上的開銷;同時(shí),使用小塊內(nèi)存過多很容易出現(xiàn)內(nèi)存碎塊,盡管系統(tǒng)有內(nèi)存碎塊整理的功能,但還是會(huì)增大系統(tǒng)負(fù)擔(dān)。因此,我們強(qiáng)烈反對(duì)使用小塊內(nèi)存。推薦的使用方法:Ø 當(dāng)僅使用少量且事先知道大小的內(nèi)存時(shí),可以以變量或數(shù)組的形式申請(qǐng)。Ø 當(dāng)時(shí)用內(nèi)存量較大,使用的大小事先(編碼時(shí))不知道,必須動(dòng)態(tài)申請(qǐng)的內(nèi)存時(shí),應(yīng)該先申請(qǐng)一塊較大內(nèi)存塊,使用時(shí)通過計(jì)算確定每一小塊的內(nèi)存地址。l 用數(shù)組實(shí)現(xiàn)鏈表在程序中使用鏈表有時(shí)是必須的,也可以給編程帶來很多方便。但使用鏈表實(shí)施必要分配多塊內(nèi)存,在鏈表進(jìn)行插入、刪除等操作時(shí)

3、還要進(jìn)行內(nèi)存的申請(qǐng)和釋放操作,在導(dǎo)航系統(tǒng)這樣一個(gè)資源非常有限的系統(tǒng)里,這樣做會(huì)占用大量系統(tǒng)時(shí)間,給系統(tǒng)帶來不必要的負(fù)擔(dān)。那么我們?cè)鯓硬拍芗仁褂面湵淼膬?yōu)點(diǎn),同時(shí)又避免給系統(tǒng)增加不必要的麻煩呢?針對(duì)這個(gè)目的,我們認(rèn)為:用數(shù)組實(shí)現(xiàn)鏈表是一個(gè)比較好的方式。實(shí)現(xiàn)方式:結(jié)構(gòu)體數(shù)組,在每個(gè)元素的結(jié)構(gòu)體中保存Next/Previous節(jié)點(diǎn)的下標(biāo)。l 不用的內(nèi)存要及時(shí)釋放或解鎖理由很簡(jiǎn)單:導(dǎo)航系統(tǒng)的資源(尤其是內(nèi)存)非常有限,占用不再需要的內(nèi)存會(huì)導(dǎo)致其他任務(wù)無法取得所需的內(nèi)存,影響導(dǎo)航系統(tǒng)的性能甚至功能的實(shí)現(xiàn)。l 不要保存(非固定)內(nèi)存塊的指針導(dǎo)航系統(tǒng)中的內(nèi)存屬性有很多種,在OS的講座中想必已經(jīng)介紹了。其中除了

4、Fixed這種屬性的內(nèi)存塊之外,其他內(nèi)存塊的指針(地址)并非在任何時(shí)候都是有效的。如果保存了一個(gè)內(nèi)存塊的指針,而這個(gè)內(nèi)存塊再?zèng)]有被這個(gè)指針的持有者意識(shí)到的情況下被移動(dòng)或被刪除了的話,再次企圖使用這個(gè)指針來訪問這個(gè)內(nèi)存塊是非常危險(xiǎn)的,可能導(dǎo)致任何不可預(yù)期的后果(輕則數(shù)據(jù)不正常,重則整個(gè)系統(tǒng)會(huì)崩潰)。l 堆棧的使用l 內(nèi)存泄漏(系統(tǒng)需要長(zhǎng)時(shí)間運(yùn)行)l 結(jié)構(gòu)體定義原則是從小到大的順序定義結(jié)構(gòu)體成員struct Sample_AintiMember1;charcMember2;short siMember3;intiMember4;struct Sample_AcharcMember2;short s

5、iMember3;intiMember4;intiMember1;*注意區(qū)別l 關(guān)于內(nèi)存塊的屬性特征及其適用范圍是否已在OS的講座中介紹了?有沒有必要強(qiáng)調(diào)一下?l 介紹了RSM,及與其它普通內(nèi)存池的區(qū)別,使用目的.RSM的內(nèi)存是屬于RX830操作系統(tǒng)后增加的一部分,主要的目的是為系統(tǒng)提供某些時(shí)候(偶爾),較少時(shí)間需要使用大量?jī)?nèi)存的機(jī)制.主要用于具有Cache屬性的內(nèi)存使用方式.RSM內(nèi)存池并不是一個(gè)完整的(或者說連續(xù)的)內(nèi)存,生成時(shí)只是在系統(tǒng)中進(jìn)行登記,分配內(nèi)存塊時(shí)的機(jī)制是從全部的用戶內(nèi)存池(1號(hào)內(nèi)存池)中分配.l 介紹了內(nèi)存的屬性,相應(yīng)的區(qū)別,使用目的.在本節(jié)介紹時(shí),由于大家對(duì)lock,un

6、lock使用不是很清楚,因此強(qiáng)調(diào)一遍.分為固定,可移動(dòng),可拋棄三種屬性.固定屬性的內(nèi)存一般在系統(tǒng)初始化時(shí)進(jìn)行分配,因?yàn)槿绻谝院蟮倪\(yùn)行中隨機(jī)分配會(huì)導(dǎo)致內(nèi)存碎片,所以要求在運(yùn)行中分配的固定的內(nèi)存一定要第一時(shí)間釋放. 處于Unlock時(shí)(如果不釋放(Release)它的handle有效和地址全局有效.可移動(dòng)的內(nèi)存處于Unlock時(shí)(如果不釋放(Release)它的handle有效,但是地址無效.可拋棄的內(nèi)存處于Unlock時(shí)(如果不釋放(Release)它的地址無效, handle狀態(tài)不明,需要先進(jìn)行Refer.主要用于Cache.內(nèi)存塊同時(shí)可以Lock多次,也就是說可以多個(gè)任務(wù)同時(shí)使用一個(gè)內(nèi)存塊

7、,因此要特別注意使用的任務(wù)不要發(fā)生write和read兩種操作,只能有一種.另外,要嚴(yán)格保證Lock和Unlock得成對(duì)使用,否則會(huì)發(fā)生無法正常釋放及地址非法的現(xiàn)象.l SCL(Sequenceable Collection Light)數(shù)組詳細(xì)的使用方法請(qǐng)向劉超(電話:64047,E-mail:liuchaoneu-)咨詢。3. 多任務(wù)準(zhǔn)確地說這并不是PC機(jī)和導(dǎo)航機(jī)編程的區(qū)別,因?yàn)樵赑C機(jī)上也經(jīng)常會(huì)編寫多線程、多進(jìn)程的軟件,但我們中的大多數(shù)人沒有做過這樣的工作,因此在這里列舉了一些多任務(wù)編程的注意事項(xiàng)。l 保護(hù)公用的數(shù)據(jù)在多任務(wù)系統(tǒng)中,經(jīng)常會(huì)出現(xiàn)多個(gè)任務(wù)需要訪問同一個(gè)數(shù)據(jù)的情況,這時(shí)我們就必

8、須對(duì)這些數(shù)據(jù)進(jìn)行保護(hù),通常的方法是用Semaphore來實(shí)現(xiàn)。例如:intiCount;HandleSemaphore_iCount;TaskA_Main()os_iWaitSemaphore(Semaphore_iCount,);iCount+;os_iSignalSemaphore(Semaphore_iCount,);TaskB_Main()os_iWaitSemaphore(Semaphore_iCount,);iCount-;os_iSignalSemaphore(Semaphore_iCount,);以上是從嚴(yán)格意義上來說,但是有時(shí)候?yàn)榱讼到y(tǒng)的要求(例如性能),如果確信對(duì)全局變量進(jìn)

9、行操作的任務(wù)不會(huì)有沖突,也可以不使用保護(hù)機(jī)制.例如:他們使用了禁止中斷的形式.另外也會(huì)有其他的形式,但暫時(shí)想的還不是很清楚.l 時(shí)刻意識(shí)到有其他任務(wù)在運(yùn)行(例子)l Mail和Event Flag任務(wù)間通信有Event Flag和Mail兩種方式,其主要區(qū)別是Mail可以攜帶數(shù)據(jù)。一般來說,每個(gè)任務(wù)組有一個(gè)處理事件的任務(wù),等待事件并做簡(jiǎn)單處理或分發(fā)給其他任務(wù),沒有事件發(fā)生時(shí)這個(gè)任務(wù)要進(jìn)入Wait狀態(tài)。為保證信息不發(fā)生堵塞,這個(gè)任務(wù)對(duì)一個(gè)事件的處理必須簡(jiǎn)單。由于任務(wù)必須主動(dòng)取Mail,因此發(fā)送Mail的同時(shí)要設(shè)置Event Flag來通知受信方。(由受信方來輪巡也可以)注意點(diǎn):1)Mail的Si

10、ze定義2)Mail中可以采取查詢的方式.另外注意Os simulator和Rx830的區(qū)別:在后者中evnet,semaphore,mail都允許使用查詢方式,在前者中不允許.l Plug In機(jī)制有兩個(gè)任務(wù)A和B,任務(wù)B要求任務(wù)A在某種條件下通知任務(wù)B,這時(shí)可以采用Plug In機(jī)制。為實(shí)現(xiàn)Plug In,任務(wù)A要維護(hù)一張表,并提供可以將一個(gè)Event插入表中的函數(shù)。任務(wù)B在需要等待任務(wù)A的通知時(shí),創(chuàng)建Event,并通過調(diào)用任務(wù)A提供的函數(shù)將此Event插入到表中,然后等待任務(wù)A來Set Flag。一般地說,任務(wù)A可以為一種事件創(chuàng)建一個(gè)表,不同的任務(wù)(B、C、D)都需要等待同一事件時(shí),它們

11、向表中登錄不同的Event(或同一Event的不同F(xiàn)lag)。這樣,當(dāng)?shù)氖录l(fā)生時(shí),任務(wù)A只需要Set表中的所有Flag就可以了。任務(wù)A還應(yīng)該提供Plug Out函數(shù),讓其他任務(wù)取消其登錄的事件,這樣當(dāng)事件發(fā)生時(shí)任務(wù)A就不用通知相應(yīng)的任務(wù)了。典型應(yīng)用:MM用的Postman。任務(wù)A為Postman,任務(wù)B為Map,Map進(jìn)入Navi方式時(shí),向Postman登錄最新自車位置的請(qǐng)求。當(dāng)Postman產(chǎn)生新的自車位置時(shí),通知Map并把新位置發(fā)給Map。當(dāng)Map進(jìn)入Scroll方式時(shí),不再需要最新自車位置,可以撤消請(qǐng)求。今后,會(huì)有其他任務(wù)(如RG)也要求得到最新的自車位置,它可以登錄另一個(gè)事件。l 輪

12、巡和等待(中斷)在導(dǎo)航系統(tǒng)中的通信主要有兩種方式:輪巡和等待。輪巡是接收者主動(dòng)去查詢是否有請(qǐng)求/數(shù)據(jù);而等待是接收者在有請(qǐng)求/數(shù)據(jù)時(shí)被發(fā)送者發(fā)送的EventFlag等的同步對(duì)象激活。(關(guān)于輪巡和等待的優(yōu)缺點(diǎn)和適用的范圍請(qǐng)補(bǔ)充)這里只補(bǔ)充他們的區(qū)別:等待的主要使用的目的時(shí)達(dá)到同步,是真正意義的事件驅(qū)動(dòng),只有事件發(fā)生時(shí)才會(huì)有下一步的動(dòng)作.Polling指的是每隔一定時(shí)間就要做一個(gè)(或一些)動(dòng)作.(例如中斷)或者在等待某個(gè)事件時(shí),一定時(shí)間沒有滿足所需要的接續(xù)動(dòng)作.(例如Time Out 處理).4. 指針在PC機(jī)上,Windows有良好的內(nèi)存保護(hù)機(jī)制,如果一段代碼向非法的地址寫入數(shù)據(jù),馬上會(huì)引發(fā)異常

13、,并且能定位到錯(cuò)誤的代碼行,使編程者順利地找出錯(cuò)誤的原因。而在導(dǎo)航機(jī)上,異常的產(chǎn)生可能會(huì)滯后,以至于發(fā)生異常時(shí)已經(jīng)無法判斷真正的原因,因此需要對(duì)指針操作格外小心。l 初始化l 合法性判斷5. 調(diào)試代碼導(dǎo)航機(jī)的調(diào)試效率比較低,原因有以下幾個(gè)方面:調(diào)試工具不夠強(qiáng)大;多任務(wù)給調(diào)試帶來困難;修改-編譯-鏈接-加載-調(diào)試的過程繁瑣而耗時(shí);導(dǎo)航機(jī)內(nèi)存少(又是內(nèi)存!),以至于不能把所有的代碼加上調(diào)試信息這是一個(gè)致命的弱點(diǎn)。l 使用Assert在導(dǎo)航系統(tǒng)中,可以象在VC+中一樣,使用ASSERT來檢查數(shù)據(jù)的有效性,但使用時(shí)請(qǐng)注意:不要在ASSERT語句中寫有效代碼!這是因?yàn)锳SSERT語句,包括寫在括號(hào)中的任

14、何內(nèi)容,在實(shí)際生成Release版本后是不執(zhí)行的,這樣導(dǎo)致的后果不言自明。例如:如下代碼:ASSERT(iGetDataBlk()= TE_OK );在程序Release后與NULL;是等價(jià)的。如果要檢查函數(shù)運(yùn)行的結(jié)果,應(yīng)該用如下方式:iRet = iGetDataBlk();ASSERT(iRet = TE_OK);l 檢查參數(shù)l 對(duì)指針或地址的參數(shù)要進(jìn)行參數(shù)檢查,而且,如不改變,最好加constl 返回錯(cuò)誤碼在導(dǎo)航程序中,大量的函數(shù)都以錯(cuò)誤碼作為返回值,這樣可以向使用者告知本函數(shù)處理的狀態(tài):是正常結(jié)束、沒有內(nèi)存還是出現(xiàn)了未知的錯(cuò)誤等。通過檢查返回值可以決定下一步的處理:是繼續(xù)運(yùn)行、整理內(nèi)存

15、還是掛起系統(tǒng)等。對(duì)我們即使的發(fā)現(xiàn)錯(cuò)誤和解決問題,保證導(dǎo)航系統(tǒng)的正常動(dòng)作是有幫助的。注意:調(diào)用有返回值的函數(shù)后一定要檢查其返回值是否正常以決定今后的處理,在實(shí)際開發(fā)中,曾經(jīng)出現(xiàn)過這樣的錯(cuò)誤:被調(diào)函數(shù)返回錯(cuò)誤“沒有數(shù)據(jù)”,這時(shí)內(nèi)存中的信息為一隨機(jī)值,但調(diào)用者沒有判斷就使用了該數(shù)據(jù),導(dǎo)致功能無法正常完成。l 加打印信息導(dǎo)航系統(tǒng)的調(diào)試相信大家都已經(jīng)有了一定的認(rèn)識(shí),目前的導(dǎo)航系統(tǒng)沒有非常好的實(shí)機(jī)調(diào)試環(huán)境,而添加調(diào)試信息需要重新編譯,且不能加得太多(會(huì)導(dǎo)致.out文件過大無法加載),這就要求我們?cè)谡{(diào)試的過程中學(xué)會(huì)使用打印信息,將一些認(rèn)為可疑的變量的值、函數(shù)的返回值等通過打印語句(ptprintf)輸出到P

16、artner調(diào)試器中顯示,作為程序調(diào)試的一個(gè)參考。但使用打印信息時(shí)請(qǐng)注意:盡量避免在執(zhí)行頻率非常高的地方加入打印信息,否則可能會(huì)導(dǎo)致導(dǎo)航機(jī)CPU負(fù)載過大,Partner出現(xiàn)“Target CPU Hang-UP”的錯(cuò)誤,影響調(diào)試。6. 其他問題l 關(guān)于const變量l 變量定義的位置其實(shí)這是一個(gè)標(biāo)準(zhǔn)C的規(guī)則:但是我們?cè)诮?jīng)常使用VC等支持C+的編譯器之后可能會(huì)忽略,即變量的定義應(yīng)該在程序塊的開頭位置(變量定義和 “”之間不能有執(zhí)行程序。例如:int iIndex = 0;GetIndex(&iIndex);short sLowIndex;sLowIndex = iIndex &

17、0xff;可以如下int I;for(;)int b;這樣的代碼在導(dǎo)航系統(tǒng)的編譯時(shí)是不能通過的。l 文件系統(tǒng)方面有沒有需要注意的?l Dispatch and Interrupt?Dispatch:是否可以對(duì)性能有絕對(duì)要求的部分,或瞬間資源(內(nèi)存)使用很大的程序使用,但是要避免里面含有引起任務(wù)調(diào)度的代碼,例如:semaphore等,ptprintf也包括.l Os_vBreak?主要用于調(diào)試,可通過棧察看調(diào)用函數(shù)的調(diào)用情況.l 強(qiáng)調(diào)任務(wù)棧和函數(shù)棧,os_iStackErrorCheck?l RecievceMessage中參數(shù)為T_TMOUT,time = 0時(shí)的注意點(diǎn)l 函數(shù)中static變

18、量的使用注意點(diǎn)尤其和多個(gè)任務(wù)相關(guān)時(shí),因?yàn)槿绻麤]有特殊判斷函數(shù)中static變量只和函數(shù)的調(diào)用發(fā)生關(guān)系,這樣如果使用它來進(jìn)行判斷特定任務(wù)會(huì)有問題.l event flag 的位模式要注意.l 函數(shù)參數(shù)檢查&不改變的地址參數(shù)使用constl task dispatch,通信,調(diào)度順序.通信方法:Mail,外部變量+Event等.l 注意Union的使用例如:typedef struct char acMemA20; Struct_A;typedef struct char acMemB20;intiMem2; Struct_B;typedef union Struct_AstA;Struct_BstB;Union_Test;void vSampleFunc(Void)Struct_AstStructA1,*pstA2;Struct_B*pstB;Union_T

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(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)論