在WinCE系统启动最开始,也就是EBoot部分,会完成一定串口的初始化,以便在后面的工作中可以在串口中显示很多信息。这也是串口打印的最开始部分。
OEMReadDebugByte、OEMWriteDebugByte、OEMWriteDebugString
在EBoot汇编跳转到C语言的main函数后,在blcommon.c中的BootLoaderMain是第一个C语言函数,这里的初始化部分包含一个OEMDebugInit的函数,实现在main.c文件中,里面调用了OEMInitDebugSerial()函数,实现在\WINCEROOT\PLATFORM\BSPNAME\SRC\OAL\OALLIB\debug.c里,就是它完成了串口的打印实现,包括OEMReadDebugByte()、OEMWriteDebugByte()、OEMWriteDebugString()。
EdbgOutputDebugString、KITLOutputDebugString
在BootLoaderMain实现过程中,还会经常见到两个函数EdbgOutputDebugString()和KITLOutputDebugString(),这两个函数的实现其实是一样的,在\WINCEROOT\PUBLIC\COMMOM\OAK\INC\halether.h文件中有如下定义:
#define EdbgOutputDebugString KITLOutputDebugString
EdbgOutputDebugString()的实现在文件
\WINCEROOT\PUBLIC\COMMOM\OAK\DRIVERS\ETHDBG\EDBGFRMT\format.c中,具体的实现如下,其实和
printf的实现很类似,这里就不做太多介绍了。
void EdbgOutputDebugString (LPCSTR sz, ...)
{
unsigned char c;
va_list vl;
va_start(vl, sz);
while (*sz) {
c = *sz++;
switch (c) {
case '%':
c = *sz++;
switch (c) {
case 'x':
pOutputNumHex(va_arg(vl, unsigned long), 0);
break;
case 'B':
pOutputNumHex(va_arg(vl, unsigned long), 2);
break;
case 'H':
pOutputNumHex(va_arg(vl, unsigned long), 4);
break;
case 'X':
pOutputNumHex(va_arg(vl, unsigned long), 8);
break;
case 'd':
{
long l;
l = va_arg(vl, long);
if (l < 0) {
pOutputByte('-');
l = - l;
}
pOutputNumDecimal((unsigned long)l);
}
break;
case 'u':
pOutputNumDecimal(va_arg(vl, unsigned long));
break;
case 's':
OutputString(va_arg(vl, char *));
break;
case '%':
pOutputByte('%');
break;
case 'c':
c = va_arg(vl, unsigned char);
pOutputByte(c);
break;
default:
pOutputByte(' ');
break;
}
break;
case '\r':
if (*sz == '\n')
sz ++;
c = '\n';
// fall through
case '\n':
pOutputByte('\r');
// fall through
default:
pOutputByte(c);
}
}
va_end(vl);
}
NKDbgPrintfW、OutputDebugStringW
NKDbgPrintfW()函数同样是在文件
\WINCEROOT\PUBLIC\COMMOM\OAK\DRIVERS\ETHDBG\EDBGFRMT\format.c中实现的,实现代码如下:
void NKDbgPrintfW(
const WCHAR *sz, ...)
{
unsigned char c;
va_list vl;
va_start(vl, sz);
while (*sz) {
c = (unsigned char)*sz++;
switch (c) {
case (unsigned char)'%':
c = (unsigned char)*sz++;
switch (c) {
case 'x':
pOutputNumHex(va_arg(vl, unsigned long), 0);
break;
case 'B':
pOutputNumHex(va_arg(vl, unsigned long), 2);
break;
case 'H':
pOutputNumHex(va_arg(vl, unsigned long), 4);
break;
case 'X':
pOutputNumHex(va_arg(vl, unsigned long), 8);
break;
case 'd': {
long l;
l = va_arg(vl, long);
if (l < 0) {
pOutputByte('-');
l = - l;
}
pOutputNumDecimal((unsigned long)l);
}
break;
case 'u':
pOutputNumDecimal(va_arg(vl, unsigned long));
break;
case 's':
OutputStringW(va_arg(vl, WCHAR *));
break;
case '%':
pOutputByte('%');
break;
case 'c':
c = va_arg(vl, unsigned char);
pOutputByte(c);
break;
default:
pOutputByte(' ');
break;
}
break;
case '\n':
pOutputByte('\r');
// fall through
default:
pOutputByte(c);
}
}
va_end(vl);
}
OutputDebugStringW()函数其实是直接调用
NKDbgPrintfW()实现的。
void OutputDebugStringW(LPCWSTR fmt)
{
NKDbgPrintfW(fmt);
}
RETAILMSG、DEBUGMSG
这两个函数是在BSP中最常见的了,在文件
NKDbgPrintfW()<span times="" new="" roman';="" mso-bidi-theme-font:="" minor-bidi;="" mso-ansi-language:="" en-us;="" mso-fareast-language:="" zh-cn;="" mso-bidi-language:="" ar-sa"="" style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font-family: 宋体; font-size: 10.5pt; ">函数来实现的。具体实现如下:
<span times="" new="" roman';="" mso-bidi-theme-font:="" minor-bidi;="" mso-ansi-language:="" en-us;="" mso-fareast-language:="" zh-cn;="" mso-bidi-language:="" ar-sa"="" style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; color: rgb(85, 85, 85); font-size: 10.5pt; line-height: 28px; font-family: 宋体; ">
#define DEBUGMSG(cond,printf_exp) \
((void)((cond)?(NKDbgPrintfW printf_exp),1:0))
#define RETAILMSG(cond,printf_exp)\
((cond)?(NKDbgPrintfW printf_exp),1:0)
本文出自 “飞雪待剑” 博客,请务必保留此出处http://jazka.blog.51cto.com/809003/593717