Sunday, March 26, 2006

Debugging Embedded Systems

在 Embedded System 除錯,和在 PC Software 除錯,概念上是相通的,那就是要運用科學的方法,其步驟如下:

  1. 仔細觀察:從可重複的(repeatable)實驗中蒐集資料。
  2. 提出假設:根據蒐集到的資料提出假設、架構理論模型。
  3. 設計實驗:設計實驗以證明或推翻假設。
  4. 進行實驗。
  5. 重複以上過程:如果實驗結果不能支持假設,那假設便是錯的,所以要再重複整個過程。

這個「觀察 -> 假設 -> 實驗 ->……觀察 -> 假設 -> 實驗……」的過程,運用到除錯上就是:

  1. 想辦法使 bug 發生的情況穩定下來,讓 bug 是可重現的(reproducible),把揭發這個 bug 所需要最簡單的情境找出來。
  2. 判斷 bug 的根源。
  3. 根據對 bug 的判斷,修正程式碼。
  4. 測試修正後的程式。
  5. 如果 bug 還在,不是誤判 bug 的成因了,就是還有其他 bug 沒剔除,所以要重複上述過程。

至此,情況已經很明顯了,為了 debug ,我們要讓 Embedded System 很容易被測試,很容易對問題蒐集必要的資料:

在 Programming 方面,要注意的東西跟一般的軟體開發並無不同。在開發階段,就要仔細設計,要有一個方便我們日後測試及除錯的程式架構,要讓程式本身是 testable 及 tunable 。相關的議題可以參考 Extreme Programming 的方法。

此外,由於 Embedded System 跟 hardware 間種種本質性的糾葛,我們還要借助一些下列的工具。

[高階工具]

在閱讀這一章節前,也可以參考 Renesas 的 H8/300L SLP Series Application Note〈Effective Usage of Hardware Development Tool〉。

Simulators

Simulator 跟 Virtual Machine 很像,可以讓我們在 host machine (通常是 PC )上執行 microcontroller, uC 程式。一般 PC 軟體開發環境所用的單步執行及中斷點也都可以在 simulator下用,其最大的缺點是模擬得還不夠多,大多只提供 CPU 的模擬,未包括週邊的模擬。

在 target hardware 還沒 ready ,就必須開始撰寫程式的場合, simulator 可以讓我們對 target uC 作前期的試驗。

此外,如果發現「target processor 的行為與 data book 描述的不同」,也可以讓程式在 simulator 上執行看看。如果在 simulator 上執行無誤,就表示硬體出了問題。

Resident Debuggers

Resident Debugger 又稱作 Debug Monitor 或 ROM monitor ,它在 uC上執行程式時,可以把執行過程秀到 host machine (通常是 PC)上。 跟 simulator 最大的不同是 resident debugger 讓程式在真正的 target machine 上跑。缺點是需要「偷」用 target machine 的資源:包括耗掉一個 communication port 來和 host 溝通;佔用一個 interrupt 來處理單步執行;還要用掉一小塊的記憶體來放 resident debugger 自己。

Resident Debugger 提供程式碼下載、執行控制、中斷點、單步執行、修改 register 和 memory 等。因為 resident deubgger 是 target code 的一部分,只有當你的應用程式執行時,它才會工作。如果你想檢查 CPU 和應用程序的狀態,你就必須停下應用程序,再次進入 resident debugger。

Emulators

Emulator 是連接到 target hardware ,且可以跟 host 通訊的 Embedded System 。和 resident debugger 比起來, emulator 最大的優點是不必佔用 target machine 的資源。

ROM Emulator

用來模仿 target board 上的 ROM 。不但具有 resident debugger 的所有功能,還具備不佔用 target machine 資源的優點。

In-Circuit Emulator, ICE

Resident Debugger 雖然是監看軟體狀態的得力助手,但只有 ICE 可以讓我們在程式執行時檢視處理器的狀態。ICE 有自己的 RAM, ROM, processor 及軟體,本身就是一套嵌入式系統,功能強大,但價錢也頗為昂貴。在高階除錯的場合,沒有其他工具可以與 ICE 匹敵。

resident debugger 只可以設定程式除錯的軟體 break point , ICE 可以讓我們根據多種 hardware event 而設定硬體的 break point 。

On-Chip Emulator, OnCE

On-Chip Emulator, OnCE 又稱作 On-Chip Debugger, OCD 。Background Debug Monitor, BDM 和 Joint Test Action Group, JTAG 是 OnCE 在 target chip 上提供的兩種最常見的介面。在 ICE 太過昂貴下, OnCE 是個不錯的選擇。

[低階工具]

三用電表(Multimeter)

量測電源電壓是否符合標準
判斷某兩點是否相通
測量電阻值

示波器(Oscilloscope)

判斷訊號或電源電壓準位
判斷某一輸出訊號是否與其他輸出訊號短路
量測週期性訊號的波形(通常是類比訊號)
若有 Storage 功能,則可以抓取非週期性訊號(數位訊號大多是非週期的)
若有雙軌跡,還可以比較訊號變化的延遲時間

邏輯筆(Logic Probe)

可以用來判斷 TTL 或 CMOS 電路某個接點是 logic 1, logic 0, 非 1 非 0 或 time pulse 等狀態。

邏輯分析儀(Logic Analyzer)

我們可以把邏輯分析儀想像成具有數位儲存功能的示波器;且有 24, 32 甚至 48, 64 個輸入通道;針對要看的信號,還能設定觸發條件(上升緣、下降緣、低準位、高準位,甚至脈衝的個數等)。

[其他技巧]

如果 uC 能多告訴我們一些事情,那對 debug 是很有幫助的。以下就列出一些有用的途徑讓 uC 開口說話:

Serial Port

當 bug 發生時,如果能在幾個可疑的地方 print out 一些東西,把程式執行的情形 log 起來,我們就可以利用這份 log 來歸納很多事情。

可能的話,請把 uC 的 UART 和 PC 的 serial port 第一時間 link 起來。我們甚至該讓 uC 跟 host 透過 serial port 作雙向的互動,這可以讓我們透過 command 來執行 uC 上特定的程式片段,縮小測試範圍。

GPIO

我們也可以讓 uC 透過 I/O port 向我們招手。常用的技巧是讓 I/O port 在各個情況下丟出不同代碼,再搭配 Logic Analyzer ,作為特定的 trigger 點。

LED

在適當的時機把 LED 點起來,也可以慢慢告訴我們一些事。

LCD

讓 uC 把要說的話,寫到 LCD 上也是不錯的選擇。

Memory

在利用 serial port 作 log 行不通的時候,把東西 log 到 EEPROM 或 battery-backed SRAM 等 memory 中都是可行的作法,如果事後可以解讀出來的話……

Tags: [] []

3 comments:

Anonymous said...

還有一種除錯法是用binary search,
假如阿寬常常用RS232 debug,應該知道
我在說什麼...(^_^)

Yukuan said...

binary search 除錯,是用來「縮小範圍,以確認錯誤發生在程式的那一部份」。一般 PC AP 的除錯也在用。跟 RS232 debug 沒有直接關係。

Andrew said...

阿寬寫的好,小弟看了真是有感覺~~