Step to UEFI (170)Application 中使用 DEBUG 宏

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 无关。

运行结果:

完整代码下载:

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注