window of Visual Studio. If KITL is not available, the debug information is transferred from the target device to the development computer over a serial port configured and used by the OEM adaptation layer (OAL).
Macros for Debug Messages
To generate debug information, Windows Embedded CE provides several debugging macros that generally fall into two categories, debug macros and retail macros. Debug macros output information only if the code is compiled in the debug build configuration (environment variable WINCEDEBUG=debug), while retail macros generate information in both debug and retail build configurations (WINCEDEBUG=retail) unless you build the run- time image in ship configuration (WINCESHIP=1). In ship configuration, all debugging macros are disabled.
Table 4-1 summarizes the debugging macros that you can insert in your code to generate debug information.
Table 4-1 Windows Embedded CE macros to output debugging messages
Macro | Description |
---|---|
DEBUGMSG | Conditionally prints a printf-style debug message to the default output stream (that is, the Output window in Visual Studio or a specified file) if the run-time image is compiled in debug build configuration. |
RETAILMSG | Conditionally prints a printf-style debug message to the default output stream (that is, the Output window in Visual Studio or a specified file) if the run-time image is compiled in debug or release build configuration, yet not in ship build configuration. |
ERRORMSG | Conditionally prints additional printf-style debug information to the default output stream (that is, the Output window in Visual Studio or a specified file) if the run-time image is compiled in debug or release build configuration, yet not in ship build configuration. This error information includes the name of the source code file and the line number, which can help to quickly locate the line of code that generated the message. |
ASSERTMSG | Conditionally prints a printf-style debug message to the default output stream (that is, the Output window in Visual Studio or a specified file) and then breaks into the debugger, if the run-time image is compiled in debug configuration. In fact, ASSERTMSG calls DEBUGMSG followed by DBGCHK. |
DEBUGLED | Conditionally passes a WORD value to the WriteDebugLED function, if the run- time image is compiled in debug build configuration. This macro is useful on devices that provide only light-emitting diodes (LEDs) to indicate the system status and requires an implementation of the OEMWriteDebugLED function in the OAL. |
RETAILLED | Conditionally passes a WORD value to the WriteDebugLED function, if the run- time image is compiled in debug or release build configuration. This macro is useful on devices that provide only LEDs to indicate the system status and requires an implementation of the OEMWriteDebugLED function in the OAL. |
Debug Zones
Debug messages are particularly useful tools to analyze multi-threaded processes, especially thread synchronization and other timing issues that are difficult to detect by stepping through the code. However, the number of debug messages generated on a target device can be overwhelming if you heavily use debugging macros in your code. To control the amount of information generated, debugging macros enable you to specify a conditional expression. For example, the following code outputs an error message if the dwCurrentIteration value is greater than the maximum possible value.
ERRORMSG(dwCurrentIteration > dwMaxIteration,
(TEXT('Iteration error: the counter reached %u, when max allowed is %u
'),
dwCurrentIteration, dwMaxIteration));
In the example above, ERRORMSG outputs debugging information whenever dwCurrentIteration is greater than dwMaxIteration. You can also control debugging messages by using debug zones in the conditional statement. This is particularly useful if you want to use the DEBUGMSG macro to examine code execution in a module (that is, an executable file or a DLL) at varying levels without changing and recompiling the source code each time. First, you must enable debug zones in your executable file or DLL, and register a global DBGPARAM variable with the Debug Message service to specify which zones are active. You can then specify the current default zone programmatically or through registry settings on the development workstation or the target device. It is also possible to control debug zones dynamically for a module in Platform Builder via CE Debug Zones on the Target menu or in the Target Control window.
You can bypass debug zones in drivers and applications if you pass a Boolean variable to the DEBUGMSG and RETAILMSG macros that you can set to TRUE or FALSE when you rebuild the run-time image.
Zones Registration
To use debug zones, you must define a global DBGPARAM variable with three fields that specify the module name, the names of the debug zones you want to register, and a field for the current zone mask, as summarized in