在WinCE系统启动最开始,也就是EBoot部分,会完成一定串口的初始化,以便在后面的工作中可以在串口中显示很多信息。这也是串口打印的最开始部分。<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
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);
}
{
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);
}
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);
}
{
NKDbgPrintfW(fmt);
}
RETAILMSG、DEBUGMSG
这两个函数是在BSP中最常见的了,在文件
\WINCEROOT \PUBLIC\COMMON\SDK\INC\dbgapi.h
中实现,两者的实现是一摸一样的,只是在不同的编译条件下实现的效果不同而已,都是通过上面的
NKDbgPrintfW()
函数来实现的。具体实现如下:
#define DEBUGMSG(cond,printf_exp) \
((void)((cond)?(NKDbgPrintfW printf_exp),1:0))
#define RETAILMSG(cond,printf_exp)\
((cond)?(NKDbgPrintfW printf_exp),1:0)
((void)((cond)?(NKDbgPrintfW printf_exp),1:0))
#define RETAILMSG(cond,printf_exp)\
((cond)?(NKDbgPrintfW printf_exp),1:0)
转载于:https://blog.51cto.com/jazka/593717