DEBUG 是我们在代码中常见的宏,本文介绍如何在编写的 UEFI Shell Application 中使用它。
首先编写一个测试的 Application,其中使用了2次 DEBUG宏:
#include <Uefi.h>
#include <Library/UefiLib.h>
#include <Library/DebugLib.h>
#include <Library/ShellCEntryLib.h>
/**
UEFI application entry point which has an interface similar to a
standard C main function.
The ShellCEntryLib library instance wrappers the actual UEFI application
entry point and calls this ShellAppMain function.
@param ImageHandle The image handle of the UEFI Application.
@param SystemTable A pointer to the EFI System Table.
@retval 0 The application exited normally.
@retval Other An error occurred.
**/
INTN
EFIAPI
ShellAppMain (
IN UINTN Argc,
IN CHAR16 **Argv
)
{
DEBUG ((DEBUG_ERROR, "DEBUG_ERROR OUTPUT\n"));
DEBUG ((DEBUG_INFO, "DEBUG_INFO OUTPUT\n"));
return EFI_SUCCESS;
}
具体的 DEBUG宏定义可以在 \MdePkg\Include\Library\DebugLib.h 看到:
/**
Macro that calls DebugPrint().
If MDEPKG_NDEBUG is not defined and the DEBUG_PROPERTY_DEBUG_PRINT_ENABLED
bit of PcdDebugProperyMask is set, then this macro passes Expression to
DebugPrint().
@param Expression Expression containing an error level, a format string,
and a variable argument list based on the format string.
**/
#if !defined(MDEPKG_NDEBUG)
#define DEBUG(Expression) \
do { \
if (DebugPrintEnabled ()) { \
_DEBUG (Expression); \
} \
} while (FALSE)
#else
#define DEBUG(Expression)
#endif
其中用到的 _DEBUG 在同一个文件中:
/**
Internal worker macro that calls DebugPrint().
This macro calls DebugPrint() passing in the debug error level, a format
string, and a variable argument list.
__VA_ARGS__ is not supported by EBC compiler, Microsoft Visual Studio .NET 2003
and Microsoft Windows Server 2003 Driver Development Kit (Microsoft WINDDK) version 3790.1830.
@param Expression Expression containing an error level, a format string,
and a variable argument list based on the format string.
**/
#if !defined(MDE_CPU_EBC) && (!defined (_MSC_VER) || _MSC_VER > 1400)
#define _DEBUG_PRINT(PrintLevel, ...) \
do { \
if (DebugPrintLevelEnabled (PrintLevel)) { \
DebugPrint (PrintLevel, ##__VA_ARGS__); \
} \
} while (FALSE)
#define _DEBUG(Expression) _DEBUG_PRINT Expression
#else
#define _DEBUG(Expression) DebugPrint Expression
#endif
上述都只是头文件,并没有真正“干活”的代码。在编译过程中可以 Link到不同的 C文件来完成。
如果想要让 DEBUG 能够正常输出,需要修改 \AppPkg\AppPkg.dsc 中的下面2行:
1.设置 DEFINE DEBUG_ENABLE_OUTPUT = TRUE # Set to TRUE to enable debug output
设置为 TRUE 之后,编译时,会将需要的DEBUG函数Link 到存在的 *.C 文件上,否则会Link 给一个没有内容的函数。这是一种非常灵活的方法,可以在冗余的DEBUG 版本和干净的 Release 版本之间切换。
设置之后会 Link 到 \MdePkg\Library\UefiDebugLibConOut\DebugLib.c 文件上:
/**
Returns TRUE if DEBUG() macros are enabled.
This function returns TRUE if the DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of
PcdDebugProperyMask is set. Otherwise FALSE is returned.
@retval TRUE The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is set.
@retval FALSE The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is clear.
**/
BOOLEAN
EFIAPI
DebugPrintEnabled (
VOID
)
{
return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_PRINT_ENABLED) != 0);
}
2. 设定 DEFINE DEBUG_PROPERTY_MASK = 2 意思是打开 DEBUG PRINT ENABLED 具体定义如下:
//
// Declare bits for PcdDebugPropertyMask
//
#define DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED 0x01
#define DEBUG_PROPERTY_DEBUG_PRINT_ENABLED 0x02
#define DEBUG_PROPERTY_DEBUG_CODE_ENABLED 0x04
#define DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED 0x08
#define DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED 0x10
#define DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED 0x20
之后, Build 上面的 Application 即可得到 EFI Application,并且这个和使用 –b 选择 RELEASE DEBUG Mode 无关。
运行结果:
完整代码下载: