版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領
文檔簡介
前言調試程序,是軟件開發(fā)過程中的一個必不可少的環(huán)節(jié)。這篇帖子,匠人試著來整理一下一些調試的技巧。說到“技巧”,這個詞自從被所長批臭之后,匠人就嚇得不敢再提,生怕一不小心就暴露了思想的淺薄和眼光的局限,呵呵。所以咱們不叫“技巧”,干脆低調點,就叫“雕蟲小技”吧。這里所討論的“調試”技巧,有些是必須結合開發(fā)工具本身的功能來實現(xiàn),而有些可以通過燒錄芯片來驗證。各種開發(fā)工具,提供的功能多少強弱也不盡相同,這些方法也未必都能套用。僅供參考吧。最后說明一下,這是沒有草稿的帖子,匠人仍然以不定期連載的方式,邊寫邊發(fā)邊改??赡芙Y構會比較混亂。歡迎大家一起參與討論。磨刀不誤砍柴功在調試之前,需要掌握以下一些基本功:1、熟悉當前的開發(fā)(調試)環(huán)境,比如:設置斷點、單步運行、全速運行、終止運行,查看RAM、查看堆棧、查看IO口狀態(tài)……總之,要熟練掌握基本操作的方法,并深刻了解其中意義。2、 了解芯片本身的資源和特性。3、 了解一點匯編語言的知識。(本來匠人是準備寫“精通”的,但考慮到現(xiàn)狀,還是“放低”這方面的要求罷了)。4、 掌握基本的電路知識和排錯能力。(軟件調試有時也會牽涉到硬件原因??偛荒苓B三極管的好壞都不能識別吧?)5、 萬用表、示波器、信號發(fā)生器……這些工具總該會用吧?6、 搜索、鑒別資料的能力。(內(nèi)事問百度、外事問古狗、有事沒事上21ic網(wǎng))7、 與人溝通,描述問題的能力。(調試36計的最后一計——就是向他人討教。當然,你得把話說明白才行)差不多了,如果上述7把砍柴刀磨好了,就可以開始調試了。接下來,請調入你的程序……優(yōu)先調試人機界面面對程序中的一大堆模塊,無從下手是嗎?好吧,匠人告訴你,先調顯示模塊,然后是鍵盤。為什么要先調顯示模塊?道理很簡單,我們說“眼睛是心靈的窗戶”,同樣,“顯示是程序的窗戶”。一旦把顯示模塊調試好了,就可以通過這個窗口,偷窺(天吶,這兩個居然是敏感字!)程序內(nèi)部的數(shù)據(jù)和狀態(tài)了。然后緊接著,就是調試鍵盤模塊。有了這個按鍵,我們就可以人工干預程序的運行了?!裁矗愕某绦驔]有顯示和按鍵?——這位童鞋,你真不幸,請去檢查一下自己的人品和星座運程先。謝謝。實在是沒顯示?再看看系統(tǒng)有蜂鳴器嗎?如果僥幸有的話,也能湊合著發(fā)發(fā)提示聲音吧?或者,有串口嗎?可以考慮借助PC端的串口調試軟件來收發(fā)數(shù)據(jù),這也是一個間接的人機交流方法。總而言之,要盡快建立人機交流界面。四、慢鏡頭的威力四、2009年春晚捧紅了魔術師劉謙(這位老兄名“謙”,其實一點都不謙虛——長的帥不是錯,出來拽就是罪過了?。补雌鹆舜蠹覍δg的濃厚興趣,如何識破那些快速的眼花繚亂的魔術手法呢?很簡單,用慢鏡頭回放即可。據(jù)說劉謙那個橡皮筋魔術的手法就是被人如此識破的?;氐轿覀儐纹瑱C上來。我們知道,單片機的運行速度,一般都是在幾M到幾十M(當然,也有為了節(jié)能而采用幾十K的低速)。不管怎么樣,這個速度都遠遠超出了我們?nèi)搜勰軌蚍直娴乃俣取Q劬σ徽?也許幾M條指令已經(jīng)執(zhí)行過去了。比如說數(shù)碼管顯示(假設有4位數(shù)碼管)。平時我們看到數(shù)碼管同時點亮著,但是實際上,這4個數(shù)碼管是逐個掃描的。在任意一個時刻,只有一位數(shù)碼管被點亮。在微觀上,我們可以進一步把每位數(shù)碼管的掃描動作細分為以下幾個步驟:1、關閉上一位數(shù)碼管的位選信號;2、輸出當前位數(shù)碼管的段選信號;3、開啟當前位數(shù)碼管的位選信號;4、 啟動1ms延時;5、 延時結束后,指針移動到下一位數(shù)碼管,并重復上述4個步驟,如此周而復始。你看,這樣是不是就像用一個慢鏡頭在分解顯示掃描的動作了?那么如何實現(xiàn)這個慢鏡頭呢?方法很多:1、單步運行(需要仿真器支持);2、 在每一步分動作之后設立斷點(需要仿真器支持);3、 在每一步分動作之后插入足夠的延時,讓我們?nèi)庋劭梢钥辞宄@些分動作(不需要仿真器,適合燒片測試);通過慢鏡頭的反復回放,我們就可以發(fā)現(xiàn),到底是哪一個分動作出現(xiàn)了問題。這個技巧,不僅僅適用于調試顯示程序,也適用于按鍵掃描或其它模塊。只要一個功能可以被細分為若干的動作,那么這一招“慢鏡頭分解法”都是可以使用的。五、 給程序安裝個黑匣子某年某月的某一天,一架飛機以優(yōu)美的拋物線形狀,一頭栽到海里去了……幾天后,人們找到了飛機的黑匣子,里面記錄了飛行員的最后一句話:“天吶,我看到火星人了!……”以上空難情節(jié)我們經(jīng)常會通過新聞看到吧(當然,最后一句是匠人版的科幻情節(jié))??纯?,飛機的黑匣子可以記錄并再現(xiàn)現(xiàn)場,多么神奇!歐耶!我們在調試程序時,也可以借鑒這個方法,給程序按裝一個黑匣子。程序中的黑匣子其實就是一個在內(nèi)存中開辟的隊列。隊列的原理我們很清楚,先進先出,后進后出(與飛機黑匣子的特性相同)。比如說吧,假設我們的系統(tǒng)在工作中,某個輸入量的采樣值經(jīng)常受到不明原因的擾動。我們要摸清這種擾動的規(guī)律,以便對癥下藥。但是這種擾動稍縱即逝。我們的困擾是:程序正常運行時看不出規(guī)律,單步走又難以捕捉擾動。怎么辦?有沒有辦法,把擾動記錄下來?當然可以。我們可以利用系統(tǒng)里剩余的RAM,開辟一塊單元,做成隊列。并寫段測試程序,定時把新采樣值壓入隊列。然后我們讓程序運行,在需要的(任意)時刻,讓程序停下來。這時,隊列里記錄的就是最新一批采樣數(shù)據(jù)。只要隊列的深度足夠大,我們就可以找出擾動的規(guī)律來?!裁?,你問我什么叫隊列?——匠人曰“天吶,我看到火星人了!……”六、 在程序中設卡伏擊,攔截流竄犯警察抓流竄犯的場面我們都很熟悉了。一般的方法,就是以案發(fā)現(xiàn)場為中心,在犯罪分子逃竄的必經(jīng)路口,設卡盤查。有道是天網(wǎng)恢恢疏而不漏,叫你插翅也飛不過去。有時,程序中也會出現(xiàn)這樣一個“流竄犯”,它就是PC指針。對于一個未經(jīng)調試的不成熟的程序來說,導致PC指針跑飛的因素很多,我們逐條列舉并分析之:1、 電磁干擾(如果不是在現(xiàn)場,那么這一條可以暫時不考慮。因為在調試環(huán)境下一般不會有干擾);2、 程序結構錯亂(喜歡用jmp或goto類指令的尤其要注意這點);3、 堆棧溢出或錯亂,導致PC指針出錯;4、 PC指針被錯誤改寫(有些芯片PC指針存儲單元和其它RAM單元的訪問方法是一樣的,很容易被誤寫);
5、數(shù)據(jù)錯誤,導致程序沒有按照預期路徑運行;6、看門狗溢出(原因一般是因為看門狗設置不當、喂狗不及時、程序堵塞或者程序死循環(huán));7、中斷被意外觸發(fā);8、外部電路問題,比如電源不穩(wěn)等等;9、其它……當我們開始懷疑PC指針時,我們首先要做的是確認PC指針是否跑飛了,其次要找到PC指針跑飛的證據(jù)。我們可以在不同的分支路口,或者在我們懷疑的地方,設立斷點,看程序是否走了不該經(jīng)過的路徑。舉個例子,比如我們懷疑程序運行中看門狗發(fā)生了溢出復位,那么很簡單,我們只需要在初始化入口設立一個斷點,讓程序運行。正常情況下,程序只會經(jīng)過一次該斷點。如果再次經(jīng)過該斷點被攔截,那么我們就可以初步確診“看門狗發(fā)生了溢出復位”。再舉個例子,比如程序中某個環(huán)節(jié)有A、B兩個分支,正常時只走A分支,不正常時才走B分支。那么我們可以在B分支設立斷點,程序一旦異常,走入B分支,就可以被攔截下來。程序被攔截下來后,我們可以勘察現(xiàn)場,查看RAM區(qū)內(nèi)容和程序剛走過的路徑,從中分析導致程序PC指針錯亂的原因。當然,并不是每一次伏擊守候都能一舉擒獲流竄犯(敵人是“狡猾”的,呵呵)。這就需要我們多一份耐心和技巧。通過不斷調整斷點位置來改變攔截地點。逐漸逼近并找到根源(流竄犯的老巢),然后一舉拿下。七、 向獵人學習挖坑設陷阱的技術上一回說到,在程序中設卡(斷點),可以攔截流竄犯(程序流程錯誤)。實際上,斷點的功能可強大了,不但可以攔截程序流程錯誤,也可以攔截數(shù)據(jù)錯誤。當然,這需要一些輔助手段。還是以前面提到的一個例子來說。比如某個采樣值(當然,也不一定是采樣值,在這里也可以是RAM中任意單元中的值)受到未明因素影響,經(jīng)?!皝y跳”。這種數(shù)據(jù)出錯的原因,可能如下:1、 計算錯誤(比如溢出),導致結果出錯;2、 被其它程序段誤改寫;3、 其它原因……當數(shù)據(jù)出錯后,我們希望能夠在最快時間內(nèi),讓程序停下來,這樣才能有效查出是哪一段程序出了問題。有些調試環(huán)境本身可以捕捉數(shù)據(jù)錯誤,并產(chǎn)生斷點中斷。這當然最好不過。但是如果調試環(huán)境本身不提供這種捕捉功能,那么就需要我們自己來制造機關了。看看獵人是是如何做的:他們會在獵物經(jīng)過的地方,挖個坑,上面蓋上浮土。當小型動物經(jīng)過時,浮土不會塌陷。而當體重較大的動物經(jīng)過時,它們的體重就會壓垮浮土,掉進獵人的陷阱。獵人的這個陷阱機關,妙就妙在是它“智能”的,會根據(jù)動物的體重進行篩選。輕巧的小白兔來了——放過,笨重的大狗熊來了——捕獲!歐耶!好了,回到程序中來,假設我們要監(jiān)控的那個RAM單元,正常值域為0~9;那么我們可以寫一段測試代碼,判斷數(shù)值是否>9,根據(jù)判斷結果執(zhí)行兩個分支,并在那條錯誤的分支路徑上設置斷點。如果數(shù)據(jù)沒有出錯,程序會一直運行(小白兔請放心過去);直到數(shù)據(jù)錯誤發(fā)生,斷點會自動停下來(大狗熊給我拿下)。我們可以把這段測試程序,插入在“狗熊出沒”的地方,“守株待兔”(其實“守坑待熊”)。接下來的事情,就跟上回說的抓流竄犯原理差不多了?!裁?,你喜歡吃兔肉?不喜歡吃熊掌?——你也太沒有愛心了,唉。。。。。八、在程序中設置竊聽器八、1、你的定時中斷頻率是否等于設想的那個值?2、你的主程序循環(huán)一次花了多少時間?3、你的程序中某一次復雜計算需要耗費多少時間?4、你的程序里某個動作發(fā)生的具體時刻是什么時候?5、……——也許你不關心這些時間,那么你就不必看這一回了。但是——1、當我們的計時時鐘發(fā)生偏差時,我們希望知道定時中斷是否正常發(fā)生了;2、當我們的程序任務較多,并已經(jīng)導致任務堵塞時,我們需要知道主程序運行一圈的時間是多少,以便我們合理分割任務,避免堵塞;3、同樣,為了避免任務堵塞,我們要了解那些復雜計算所消耗的時間,并采取必要的措施(優(yōu)化算法、分時間片執(zhí)行、調整執(zhí)行頻率)來保證系統(tǒng)的實時性;4、當程序中某些動作與其它動作或狀態(tài)存在時間上的關聯(lián)時,我們必須嚴格控制它的執(zhí)行時機,確保它在正確的時刻被執(zhí)行到;5、……我們?nèi)绾尾拍軓耐獠浚瑢@些這些發(fā)生在程序內(nèi)部的時間(時刻)進行精準的測量?我們當然不能鉆到芯片里面去監(jiān)視每一條指令的運行情況。但是,我們可以學習一下克格勃,給程序安裝個竊聽器。具體方法:1、首先,你需要一臺示波器。沒有的話,可以去偷、去搶、去騙??傊?,最終你搞定了這臺示波器,歐耶。2、其次,你的芯片上要有一個空余的輸出口用作測試口。沒有的話,就拆東墻補西墻吧,先把不相關功能的10口挪用一下啦??傊?,最終你搞定了這個測試□,歐耶。3、 接下來,你可以在你要“監(jiān)聽”的程序段中,寫一小段程序,對那個測試口取反(或者輸出一個脈沖)。4、 最后讓程序全速運行起來,你就可以用示波器來監(jiān)聽程序的運行狀況了。以本回開始舉的幾個例子來分析:1、 如果要測試定時中斷頻率,只要在中斷中對這個測試口取反,即可通過示波器觀測中斷頻率;2、 如果要測試主程序運行周期,只要把取反指令放在主程序循環(huán)圈中,即可;3、 如果要測試一次復雜計算(或其它動作)需要消耗多少時間,我們只需在計算之前把測試口變?yōu)楦唠娖?,等到計算結束后立即把輸出口恢復到低電平,這段高電平的時間長度,即為計算消耗時間;4、 如果想知道兩個動作之間的延時時間,我們也可以按照上一條方法一樣,在兩個動作發(fā)生前把測試口分別取一次反。就可以通過示波器輕松測試出來。5、 根據(jù)實際案例的具體情況,我們可以把這種竊聽技術變換出更多花樣。比如我們可以用兩個10口做測試□,同步檢測兩個事件的發(fā)生時刻,并測量其相互時間關系。等等……6、 引申開去,這個測試口不僅僅可以檢測時間,也可以用來檢測內(nèi)部數(shù)據(jù)的變化。比如當某個數(shù)據(jù)的值發(fā)生“越界”時,輸出一個高電平(平時為低電平)。等到我們?nèi)〉梦覀兿胍臏y試數(shù)據(jù),我們可以把這個臨時的測試口功能撤銷。同時,那些測試代碼也可一并刪除或屏蔽??偨Y:把程序內(nèi)在的、不直觀的、快速的一些狀態(tài)變化,通過io口傳遞出來,以便我們觀測。一一這就是我們這一回所講的“竊聽器”調試技巧的精髓?!?,請勿把“竊聽器”安裝在女生宿舍哦!——那樣的話,匠人豈不就成為教唆犯了。罪過,罪過。。。。。九、九、快鏡頭加速前面已經(jīng)講過慢鏡頭,這回再講快鏡頭。慢鏡頭的作用的把程序的運行節(jié)奏降低,以便我們能夠“一幀一幀”地觀測程序的運行狀態(tài)。而快鏡頭的作用,則相反,就是讓程序的運行節(jié)奏變快,讓我們驗證一些原本需要消耗較多等待時間的功能。比如說,一個定時功能,定時范圍是可調的,為1~24小時。如果我們要去驗證,總不能傻等1~24小時吧?怎么辦呢?快鏡頭來了。我們知道程序中的時間,是靠一級一級的計時器累計上來的。比如一個程序中分別有“時、分、秒”三個計時器單元。依次計數(shù),逢60進一?!懊搿庇嫕M60次了,則“分”+;1“分”計滿60次了,則“時”+;1“時”計數(shù)超過設定值了,我們就可以判定定時結束。那么我們只要修改一下“分”到“時”的進位關系。比如改成:“分”+;1“分”計滿1次(原本是60次)了,則“時”+。1這樣一來,整個定時系統(tǒng)速度就比原來提高60倍。測試起來就很省時間了。當然,測試完成后,記得要把剛才做的測試代碼改回原樣哦。舉一反三,“快鏡頭”技巧,不僅僅用在定時方面,也可以用在計數(shù)方面。通過對數(shù)據(jù)的變化“加速”,來加快我們的測試速度?!裁?,你喜歡磨洋工,愿意花24小時去測試那個定時功能?——哈哈,放心,我不會告訴你的老板的——除非他使出美人計來對付我。歐耶!十、拉閘睡覺!統(tǒng)一管理調試代碼前面介紹的幾種方法,需要在程序中增加一些臨時性的調試代碼。有些調試代碼是無害的,比如只是一些延時指令,或者是在不使用的10口上有一些輸出而已。但另一些調試代碼,與正式要求的程序功能是相沖突的。那么這些代碼在完成調試之后就應該被刪除或屏蔽掉。那么會不會出現(xiàn)意外,把本該被刪除的代碼漏刪了?結果埋下禍害?——如果調試代碼少,出錯的概率比較低,只要認真仔細點還好辦;但是如果程序中的調試代碼寫得比較多,那么確實很擔心會發(fā)生這種問題。或者另一種情況,就是前腳把調試代碼刪除或屏蔽掉,后腳發(fā)現(xiàn)還需要再調試,又要重新輸入或打開那些代碼?如何管理這些代碼呢?這個我們要向宿舍管理員學習了。他們是這么做的,給所有房間安裝一個總電閘。到了晩上11點就把總閘一拉,看書的、打牌的、喝酒的、胡侃的、泡妞的、夜游的、Y們都給我老老實實睡覺去吧!程序中,這樣的總閘也是可以通過條件編譯的方式來實現(xiàn)的。就像這樣://#defineTEST_MD//調試狀態(tài)標志(在調試時打開,正式燒錄芯片時屏蔽)//在編寫調試代碼時,采用下面的形式:#ifdefTEST_MD//如果是調試狀態(tài),則編譯這段代碼#else//如果不是調試狀態(tài),則編譯這段代碼#endif一個總閘,把管理簡單化了。歐耶!一、十一、刪繁就簡,從最
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 輕描淡寫的瞬間作文6篇
- 2024年離婚協(xié)議書模板:適用于無共同財產(chǎn)情況
- 2024年行政合同優(yōu)益權研究:合同標的、屬性與改革探討
- 2024排水溝勞務分包合同范本
- 2024年生物制藥專利技術許可使用合同
- 2025年度杭州中介房屋出租合同5篇
- 2024年金融反擔保補充協(xié)議書版B版
- 2025版文化創(chuàng)意產(chǎn)品授權合作合同2篇
- 二零二五年度二手車抵押交易安全保障合同范本2篇
- 2024年航空器材采購墊資合同協(xié)議書模板
- 六年級上冊數(shù)學應用題分類練習100道
- 土方開挖過程中的文物保存方案
- 臨時安全用電要求安全培訓
- 水稻田稻鴨共棲技術要點
- 肺功能科室工作報告
- 如何訓練寶寶獨立就寢
- 血常規(guī)報告單
- 寶寶大便觀察及護理課件
- 學校最小應急單元應急預案
- 一年級第一學期口算題(20以內(nèi)口算天天練-15份各100題精確排版)
- 公司月度安全生產(chǎn)綜合檢查表
評論
0/150
提交評論