對於即時系統,如何調試是一個很難解決的問題,包括對系統核心的調試,對驅動程式的調試,對應用程式的調試等。對於應用程式,通常各整合式開發環境都提供了常規的單步跟蹤等調試手段。而對於另兩個的調試,Platform Builder除了為我們提供了常規的斷點跟蹤等手段以外,還和系統的來源程式配合使用了一種新的調試手段——Debug Zones調試區。 通常,我們都是利用OutpubDebugString函數來實現調試資訊的輸出的,但是由於系統底層的調試資訊非常繁多,如果這樣大量的調試資訊用於即時輸出的話一定會影響到系統的效能和即時性,也就影響到了系統的運行。如果有一種方式能允許開發人員自己選擇輸出哪些調試資訊,不輸出哪些調試資訊的話,那麼就可以讓開發人員只看到關心的調試資訊,而把諸如鍵盤按鍵、滑鼠移動等無用的調試資訊隱去,則可以更好的提高開發效率,迅速找到問題所在。 調試區就是為瞭解決以上提出的問題的,對某一個驅動程式,它規定好自己向外輸出的調試資訊的分類,比如初始化時的資訊,出錯時的資訊,釋放時的資訊,啟用時的資訊等,然後分成幾個調試區,在現有的CE版本中最多允許16個調試區。開發人員通過Platform Builder中Target菜單下的CE Debug Zones命令來決定想要得到哪一個或哪幾個調試區的資訊,在驅動程式中則可以根據開發人員的選擇來輸出指定調試區的資訊。這就是調試區大體上的工作原理。 接下來,我們就來看一下調試區的定義,聲明,註冊及使用。 在程式中使用調試區之前必須先定義它們,一個程式的16個調試區編號分別為0-15。代碼範例如下所示: #ifdef DEBUG // // For debug builds, use the real zones. // #define ZONE_TEST DEBUGZONE(0) #define ZONE_PARAMS DEBUGZONE(1) #define ZONE_VERBOSE DEBUGZONE(2) …… #define ZONE_WARN DEBUGZONE(14) #define ZONE_ERROR DEBUGZONE(15)#else // // For retail builds, use forced messages based on the zones turned on below. // #define ZONE_TEST 0 #define ZONE_PARAMS 0 #define ZONE_VERBOSE 0 …… #define ZONE_WARN 0 #define ZONE_ERROR 0 #endif 這樣,就可以程式的DEBUG版本中使用調試區了,而在RELEASE版本中則將其全部定義為0,調試資訊即不再輸出。 在程式中,除了以上的定義以外,還要聲明幾個專用的調試資訊輸出函數,這些函數與OutputDebugString函數的區別就在於在調用時需要指定對應的調試區,這些函數以及以上用到的DEBUGZONE宏的定義都在DbgApi.h標頭檔中,因此只要在來源程式中包含此標頭檔即可。除此以外,還需要一個全域的DEBPARAM類型的變數命名為dpCurSettings,以供整合式開發環境和調試資訊輸出函數使用。其代碼範例如下: #ifdef DEBUG DBGPARAM dpCurSettings = { TEXT("WaveDriver"), { TEXT("Test") // 0 ,TEXT("Params") // 1 ,TEXT("Verbose") // 2 ,TEXT("Interrupt") // 3 ,TEXT("WODM") // 4 ,TEXT("WIDM") // 5 ,TEXT("PDD") // 6 ,TEXT("MDD") // 7 ,TEXT("Regs") // 8 ,TEXT("Misc") // 9 ,TEXT("Init") // 10 ,TEXT("IOcontrol") // 11 ,TEXT("Alloc") // 12 ,TEXT("Function") // 13 ,TEXT("Warning") // 14 ,TEXT("Error") // 15 } , (1 << 15) // Errors | (1 << 14) // Warnings }; #endif 此例中還把ERROR和WARN調試區作為預設被開發人員選中的調試區。 要想使用調試區,還需要做的最後一件準備的事情就是在程式中進行註冊,也就是在程式啟動時通知整合式開發環境本程式中要使用調試區,這個註冊很簡單,只要在程式的入口處使用DEBUGREGISTER宏即可,範例如下: DllEntry ( HANDLE hinstDLL, DWORD Op, LPVOID lpvReserved ) { switch (Op) { case DLL_PROCESS_ATTACH : DEBUGREGISTER((HINSTANCE)hinstDLL); break; …… 至於調試區的使用,完全是幾個宏的使用而已,我想做程式的人都會用的,常用的宏如下: DEBUGMSG(),DEBUGLED(),RETAILMSG(),RETAILLED(),ERRORMSG(),DEBUGCHK() 好了,調試區就概要的說了這麼多,如此複雜的機制在自己的程式中寫起來是煩瑣了點,不過如果你需要的話,可以從CE現有的常式序中複製過來,這樣就省了很多麻煩事,也不會出錯。是在PB中使用調試區的,當選中某一個調試區後,如果該調試區有調試資訊則會在DEBUG視窗輸出的。自己試試吧!
|