嵌入式系統除錯診斷方法
嵌入式系統開發過程實際上就是一個除錯診斷的過程,而且除錯診斷將一直伴隨著一個產品的終身,即使是最成熟的產品也偶爾會出現這樣或那樣的問題,這都需要開發人員去診斷、排查。
嵌入式系統的除錯包括硬體除錯、軟體除錯以及綜合除錯。硬體除錯一般是指系統剛開發出來時上電前後的檢查,包括:
1)上電前檢查電源和地是否短路,目視檢查是否有虛焊、漏焊;
2)上電後檢查時鐘線上的頻率和波形、幅度是否正常,各電源電壓是否穩定正常,各晶片溫度是否正常,各指示燈是否正常。
軟體除錯一般是指保證硬體一切正常的情況下驗證程式執行的時序是否正確,邏輯和結果是否與設計要求相符,能否滿足功能和效能要求等。軟體除錯的方法有很多,包括:
1)用指示燈跟蹤除錯;
2)用串列埠列印除錯;
3)用簡單的偵錯程式進行彙編程式碼級除錯;
4)用比較高階的偵錯程式進行原始碼級除錯;
5)用模擬器進行硬體模擬。
上述單純的硬體除錯或軟體除錯都是相對比較簡單的,困難的是綜合除錯。下面我先舉一些自己在工作中曾經碰到的疑難問題,然後再從中歸納出一些一般的除錯方法和注意事項。
例 1:我們自主設計製作的PPC860(Motorola)網路引擎平臺的除錯已接近尾聲,同一批生產的4塊板子都透過了全部軟體測試,於是又去焊了第二批,可是在第二批板子中有1塊板子的FEC不能正常工作,我們幾個軟體和硬體工程師使用了各種手段,重新看了多遍晶片手冊,還是沒找出原因,於是把板子發回工廠重新焊接BGA,可是回來問題還是照樣存在,沒辦法最後打算將這塊板子當作個樣處理,把板子上的晶片都焊下來。按常理來說這種做法很符合邏輯,因為元器件都是一樣的,板子也是一批的,那就可能是這塊板子的某個地方焊接不好,但又不好查,反覆重新焊接可能會把主機板焊壞。後來有人從PPC860晶片上用放大鏡都要睜大眼睛才能看清的字元上(據說我國第一代國產高階處理器晶片“寒心”就是某“科學家”將“摩托”同一型別晶片上的這些字母磨掉後刻上“寒心一號”搖身一變造出來的!!!)發現這塊板子的CPU版本號是“D4”,而其他板子的CPU版本號是“D3”,可晶片手冊上並沒有這兩個版本之間的比較說明,從網上找到PPC860的勘誤手冊,發現在PPC860TZP50D4版本中,ECNTRL暫存器增加了一個叫FEC_PIN_MUX的位(bit2)來控制FEC各管腳的複用功能,如果要使用FEC就必須將該位設定為1,所以要在FEC的相關程式中加上ECNTRL |= 0x00000004語句行。
例2:當我除錯業餘自制的MC68VZ328板子時,電路板硬體檢查沒有問題,用Code warrior透過串列埠往flash中燒製編譯好的uClinux程式也一切正常,但是重新上電,發現串列埠沒有任何資料,用萬用表檢查(當時自己沒有示波器等“先進裝置”)也沒查出結果,然後每天上下班把這塊板子放在包裡,沒事就拿出來瞪大眼睛看看,看著也不免窩火,但有一天卻發現一個標著電阻符號的地方卻焊上了電容,回到家把電阻換上去再上電,串列埠一下就列印出uClinux的啟動資訊,呵,那滋味,比喝了蜂蜜都甜,當然當時也是因為沒有太多經驗,如果這問題放現在,估計一天內肯定解決掉。另外在初次除錯自制的S3C4510開發板時,就是不能從串列埠輸出字元,費了半天時間才發現把串列埠電平轉換晶片 max3232cse的第6腳上的旦電容極性焊反了。
例3:在除錯SB1250嵌入式伺服器主機板時,由於使用的是DDR1代記憶體條,資料線和時鐘線上串並聯的去耦電容電阻相當多,第一批焊回來的板子幾乎沒有一塊能夠順利進入CFE(BIOS)選單介面的,檢查時鐘波形和電源與借用的 DEMO板相比都很好,我把主機板上DDR DIM槽周圍的那些去耦電阻電容都全部用烙鐵重新過一遍錫,嘿嘿,還真管用,這種方法屢試不爽,而且在後面除錯PCI和HT匯流排時使用這招也很有用,可能是因為SB1250系統是高頻電路,對焊接要求比較高,稍微有一點漏焊或者虛焊都不行,我是這樣認為的。
例4:在一個使用實時時鐘晶片 SD2000的應用系統中,經常會出現讀出的時間被複位到 “2000年1月1日”的情況,我用自己編寫的測試程式經過多次測試發現,按照SD2000晶片手冊中的時序進行連續讀寫確實會經常出現復位現象,好像是晶片錯把讀寫時序當成了復位操作時序,而且每次必出,所以我感覺到晶片本身應該有Bug,於是告訴同事可能是晶片本身有問題,讓他跟廠家聯絡,但因為這個晶片在老產品中用了比較長的時間,所以同事不太認同我的看法,但還是與SD2000廠家取得了聯絡,廠家經過兩天專門強化測試後通知我們“SD2000本身確實有Bug,可能因為干擾導致晶片復位到2000年1月1日”。
例5:在用PNX1700(DSP)處理器設計成的音影片開發平臺上,常會出現CVBS輸出黑白影像(應該是彩色)或顏色不正常現象,於是先詳細閱讀CVBS輸出晶片AVS3169的手冊,然後用示波器測量3169晶片的時鐘管腳,在測量的過程中經常會出現顏色恢復正常的現象,再做多次測試發現這種現象是由於將場同步VSYNC訊號與相鄰的資料線Data7短路造成的,再測試發現將VSYNC與其他資料線(Data[0:6])任一根短接一下都可以恢復正常,再用影片時鐘訊號CLK與資料線短接一下有時也能恢復正常,但有時也不能恢復,所以懷疑是影片場同步訊號有問題。順著這根線索查了一下AVS3169的VSYNC訊號與PNX1700的連線方式,發現在用CVBS輸出時,PNX1700上與AVS3169的VSYNC訊號相連的引腳是輸出QVCP_VSYNC訊號,檢查VO輸出模式設定沒有問題,再查QVCP的設定,看哪個暫存器能控制QVCP_SYNC訊號,發現在QVCP_CONTROL(0x10e020)暫存器中有對HSYNC和VSYNC的控制,用命令線上修改了直接相關的該暫存器中4個位的值,但沒有任何效果,再在整個PNX1700晶片手冊中查詢關鍵字VSYNC,發現在398頁有對QVCP VSYNC設定要求的描述:該暫存器的bit1(Master)要求設成1,即從模式,而我們現在是設成0,即主模式,我把該位改成1後螢幕出現黑屏,沒有任何顯示,再把這位恢復到0,竟然出現了顏色,屢試不爽,仔細研究這個暫存器的bit1和bit0分別是控制螢幕時鐘發生器(STG)工作模式(主/ 從)和STG的復位,分析覺得在系統上電後對QVCP初始化之前先把QVCP的STG置成從模式並且復位STG,然後再用原有的初始化程式,這樣應該可以解決影片訊號的時鐘和資料不同步問題,所以在主程式中初始化QVCP之前加入MMIO(0x10e020) = 0x20050006行,測試果然不再出現上述問題,問題解決;並順勢延伸一下,以前用SAA7105做CVBS輸出時偶爾也會出現螢幕頂部顯示不正常問題應該與這個問題一樣,所以用上述相同的方法修改程式後對SAA7105 CVBS輸出進行強化測試(每8秒鐘重新啟動一次,強化測試3天),結果沒有再出現顯示不正常現象;
例6:同樣是PNX1700音影片開發平臺上遇到的問題,VGA輸出時OSD選單會抖動,最先想到的方法是把OSD的scaler改用QVCP來做而不是MBS來做,這樣在1500上會減輕 OSD抖動現象,幾乎不出,但在1700上測試效果還是很不好,抖動仍然很厲害,後來安排同事將1500種DDR時鐘的工作頻率從166MHz提高到 200MHz,並告訴他需要改哪個模組的哪幾個暫存器,這時正好是用VGA做影片輸出(一般情況是用CVBS做影片輸出,但因為此時正在跟蹤VGA中 OSD抖動問題,所以用了VGA輸出模式)來調DDR工作頻率的,在同事修改DDR暫存器過程中我卻發現OSD怎麼不抖了,仔細研究同時修改過的暫存器相關位的定義,發現在DDR模組中有兩個暫存器與DDR仲裁相關,一個是ARB_HRT_WINDOW(0x65184,DDR仲裁硬體實時視窗),另一個是ARB_CPU_WINDOW(0x65188,DDR仲裁CPU視窗),將這兩個暫存器分別設定成ARB_HRT_WINDOW = 0xffff及ARB_CPU_WINDOW = 0x0就不會出現OSD抖動,因為在這種設定情況下DDR對DMA的佔有權高於CPU對DDR的擁有權,DDR可以搶斷CPU,原來的設定使CPU可以搶斷DDR佔有DMA。其實在發現問題VGA中的OSD抖動問題之初我也找過與memory相關的暫存器設定,因為根據以前經驗和習慣思維,DDR配置暫存器只是負責DDR部分,而memory與CPU之間關係的暫存器應該在系統暫存器中,所以沒有去查詢DDR配置暫存器,可是在這一例子中卻偏偏在DDR配置暫存器中。
從上述幾個例子中我們可以總結歸納以下幾點除錯方法和注意事項:
1)加深理解法:加深理解包括加深對硬體和軟體的理解,加深對硬體的理解主要是詳細閱讀相關的晶片資料手冊,而加深對軟體的理解是因為現在開發嵌入式系統並不是所有程式都需要自己編寫,很多都是已經做好的,直接從網上獲取或者採購獲得,但這些軟體不一定是完全針對我們自己的目標板的,所以在使用過程中經常會發現一些問題,特別是底層軟體,而一旦出現問題,開發人員首先必須瞭解出現問題的程式碼。只有建立在對相關硬體和軟體深入理解的基礎上才可能做出更符合實際的判斷,才可能更好地解決問題。
2)比較法:比較的方法有很多,比如將同樣的軟體放在兩個類似但不相同的硬體平臺上執行比較現象;將兩個不同版本的軟體放在同一個硬體平臺上執行比較現象;將相同的軟體放到相同批次但不同的兩個硬體平臺上執行比較現象。對於一些不是很隱蔽的問題透過比較法通常能得到不錯的效果。
3)分解法:當碰到分析起來比較複雜、可能有很多因素的問題時,可以把問題分成解幾個小問題來測試診斷,比如編寫幾個單獨的小測試程式對各種可能因素進行排查測試,根據這些測試結果再進行科學判斷。
4)軟硬體結合法:這種方法是需要一定靈感和悟性的。比如上面的例5,在測試過程中,可以在不破壞硬體的前提下臨時改變一下硬體的狀態(比如該例中將資料線和時鐘線短路),看問題現象會不會有所變化,如果有,那麼多做類似試驗找出變化規律和關鍵因素,然後再進行分析解決。在底層軟體開發中,對於時序要求嚴格的硬體模組的軟體程式設計要特別注意,一旦程式的時序出了問題,而這部分軟體已經與其他系統軟體融合到一起,那麼這種軟體讓別人去檢查是很難查出問題的。
5)診斷、排故要建立在大量實驗的基礎之上,要多動手,不能光知道臆想,不願實際操作,還美其名曰“善於思考和分析”。嵌入式系統開發是一門實踐性很強的科學,需要在實踐中總結出事物客觀規律,從而更好地認識和利用它們,讓它們更好地按我們的意圖工作。
6)嵌入式系統開發除錯要求開發人員有嚴謹細緻的工作態度,決不放過除錯過程中發現的任何一點蛛絲馬跡,因為它很可能就是開啟潘多拉寶盒的鑰匙。
7)要有實事求是的工作作風,要有敢於懷疑一切的精神和勇氣,我們理當尊重權威和前人的科技成果,但當出現矛盾時我們更應該相信實驗結果,這樣科學才會進步。
8)要勇於挑戰自我,拋開習慣性思維和成見,拓寬思路,多角度分析問題。
9)嵌入式系統開發特別是底層軟體和作業系統核心開發因為需要同時跟軟體和硬體打交道,所以是一件比較艱苦的工作,很有挑戰性。即使我們各方面都做得非常好,考慮得非常細緻周全,目標系統仍然可能跟我們開一些小小的玩笑,我們經常會碰到一個非常小的問題困擾我們幾天甚至幾周的時間,這期間我們可能茶飯不思、夜不能寐,因此嵌入式系統底層軟體開發人員不但要有平和的心態,且具備一定的耐心和毅力,還要有勇於克服一切困難的勇氣和信心!只要我們做得足夠好,那麼可能解決一個具體疑難的過程帶有一定偶然性,但我們終將排除所有阻礙!
所以說,嵌入式系統除錯過程就是一個更加深入瞭解我們的目標系統以及系統中的每個單元模組特性的過程,就是一個鍛鍊我們的邏輯思維和分析推理能力的過程,就是一個開拓思路、向習慣思維和權威挑戰的過程,就是一個培養嚴謹細緻的工作態度和實事求是工作作風的過程,就是一個鍛鍊我們耐力和毅力的過程,最終是一個學習進步的過程!
嵌入式系統除錯診斷能力的提升是一個長期實踐、積累、提高的過程!
——本文節選自王洪輝老師的《》一書
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/13164110/viewspace-557745/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 嵌入式系統除錯Uboot串列埠互動除錯除錯boot串列埠
- Arthas線上java程式診斷工具 線上除錯神器Java除錯
- 整車EOL診斷系統
- 整車EOL 診斷系統
- ECS控制檯診斷系統
- DIY工程寶,網路診斷,攝像頭除錯除錯
- 診斷通用售後系統 — DGA
- 如何診斷RAC系統中的
- Win10系統下網路診斷在哪_win10系統如何使用網路診斷Win10
- Win10系統使用疑難解答診斷提示診斷策略服務已被禁用的解決方法Win10
- 程式設計除錯和診斷的五大規則程式設計除錯
- win10系統下啟用診斷策略服務的方法Win10
- 等待事件效能診斷方法事件
- win10系統如何禁用診斷工具Win10
- Win10系統下網路故障診斷功能的使用方法Win10
- AS斷點除錯斷點除錯
- 作業系統診斷工具truss, pstack, and pmap作業系統
- 【記錄】Linux 系統故障診斷與排除Linux
- Oracle 系統效能變慢常規處理診斷及定位處理方法Oracle
- 痞子衡嵌入式:嵌入式Cortex-M系統中斷延遲及其測量方法簡介
- webstorm 斷點除錯WebORM斷點除錯
- 系統硬碟診斷維護工具TechTool Pro 14中文硬碟
- 某物流系統資料庫故障診斷案例分析資料庫
- 吃透 JVM 診斷方法與工具使用JVM
- 使用error stack診斷特定錯誤資訊Error
- AIX新裝系統不斷進入診斷模式解決辦法AI模式
- Win10系統怎麼利用系統診斷來檢查電腦Win10
- B站大資料系統診斷實踐-SQLSCAN篇大資料SQL
- 公司某資料子系統定期cpu過高的診斷
- 如何診斷RAC系統中的'gc cr multi block request'?GCBloC
- 一張圖記住常用Linux系統效能診斷工具Linux
- 嵌入式Linux的除錯方案Linux除錯
- Pycharm的斷點除錯PyCharm斷點除錯
- js斷點除錯心得JS斷點除錯
- 除錯——條件斷點除錯斷點
- 嵌入式系統要如何學習?帶你瞭解嵌入式系統學習方法
- 【PHP Whoops】錯誤&異常 診斷元件PHPOOP元件
- 嵌入式安卓開發使用LLDB進行斷點除錯C/C++程式碼安卓LLDB斷點除錯C++