📄 xllp_logmessage.c
字号:
/*
** INTEL CONFIDENTIAL
** Copyright 2005 Intel Corporation All Rights Reserved.
**
** The source code contained or described herein and all documents
** related to the source code (Material) are owned by Intel Corporation
** or its suppliers or licensors. Title to the Material remains with
** Intel Corporation or its suppliers and licensors. The Material contains
** trade secrets and proprietary and confidential information of Intel
** or its suppliers and licensors. The Material is protected by worldwide
** copyright and trade secret laws and treaty provisions. No part of the
** Material may be used, copied, reproduced, modified, published, uploaded,
** posted, transmitted, distributed, or disclosed in any way without Intel抯
** prior express written permission.
**
** No license under any patent, copyright, trade secret or other intellectual
** property right is granted to or conferred upon you by disclosure or
** delivery of the Materials, either expressly, by implication, inducement,
** estoppel or otherwise. Any license under such intellectual property rights
** must be express and approved by Intel in writing.
*/
//************************************************************************************************************
//
// Formatting and Message logging functions.
//
// The code in this module performs printf-like formatting.
// It is somewhat simplistic and doesn't handle many traditional format options.
// The intent is just to provide an implementation that accommodates common devloper usage.
// Format specifications supported are...
// x : 32-bit hex number
// X : 32-bit hex number
// h : 16-bit hex number
// H : 16-bit hex number
// b : 8-bit hex number
// B : 8-bit hex number
// u : unsigned decimal
// d : signed decimal
// c : 8 bit ASCII character
// s : string
// Format specifications like %#04x are supported to some extent.
// The 'h' and 'b' options exist to enable this module to be a drop-in replacement for
// similar functions in EBOOT if that becomes desirable.
//
// The functions in this module accept and produce 8 bit ascii messages.
// They can generate messages up to a maximum size (currently 128-4 bytes)
// and protect against buffer overflow due to longer messages.
// Actual output (eg. via a serial port) is likely to be OS dependent.
// OS dependence is handled by requiring a simple string output function be provided by the host environment.
// An implementation of that function could be as simple as 'printf("%s", pMsg)'
extern void OSD_LogMessage(unsigned char *pMsg);
#include "xllp_logmessage.h"
#define XLLP_LOGMESSAGE_MAX_BYTES 128
typedef struct
{
unsigned long max_bytes;
unsigned long current_bytes;
unsigned char *p;
} BUFFER_DESCRIPTOR;
typedef int bool;
static unsigned long PutByte(unsigned char c, BUFFER_DESCRIPTOR *pBD)
{
if (pBD->current_bytes >= pBD->max_bytes)
return(0);
pBD->p[pBD->current_bytes++] = c;
return(1);
}
static const unsigned char HexCharsLC[] = "0123456789abcdef";
static const unsigned char HexCharsUC[] = "0123456789ABCDEF";
static void PutHex(unsigned long n, unsigned long out_chars, bool upcase, unsigned char fill, BUFFER_DESCRIPTOR *pBD)
{
unsigned char tb[8];
const unsigned char *phc;
int i;
phc = upcase ? HexCharsUC : HexCharsLC;
// put significant digits in temp buffer (from right to left)
i = sizeof(tb)-1;
while(1)
{
tb[i] = phc[n & 0xf];
n >>= 4;
if (n == 0)
break;
if (i > 0)
i--;
else
break;
}
// i now points to the first non-zero hex char in hb[]
if (out_chars != 0)
{
int z;
if (out_chars > sizeof(tb))
out_chars = sizeof(tb);
if (fill == '\0')
fill = '0';
// calulate number of leading zeroes required
z = out_chars - (sizeof(tb) - i);
// output leading zeroes
while (z-- > 0)
PutByte(fill, pBD);
}
// output the hex chars
while (i < sizeof(tb))
PutByte(tb[i++], pBD);
return;
}
static void PutDecimal(unsigned long n, unsigned long out_chars, unsigned char fill, BUFFER_DESCRIPTOR *pBD)
{
unsigned char tb[10];
int i;
// put significant digits in temp buffer (from right to left)
i = sizeof(tb)-1;
while(1)
{
tb[i] = (unsigned char)('0' + (n % 10));
n /= 10;
if (n == 0)
break;
if (i > 0)
i--;
else
break;
}
// i now points to the first non-zero decimal char in hb[]
if (out_chars != 0)
{
int z;
if (out_chars > sizeof(tb))
out_chars = sizeof(tb);
if (fill == '\0')
fill = ' ';
// calulate number of leading fill chars required
z = out_chars - (sizeof(tb) - i);
// output leading fill
while (z-- > 0)
PutByte(fill, pBD);
}
// output the decimal chars
while (i < sizeof(tb))
PutByte(tb[i++], pBD);
return;
}
static unsigned long PutString(const unsigned char *s, BUFFER_DESCRIPTOR *pBD)
{
unsigned long idcb = pBD->current_bytes;
while (*s)
{
if (PutByte(*s++, pBD) == 0)
break;
}
return(pBD->current_bytes - idcb);
}
unsigned long xllp_vsnprintf(unsigned char *pBuf, unsigned long max_bytes, const unsigned char *pFormat, va_list ap)
{
unsigned char c;
unsigned char fill_c;
unsigned long width;
const unsigned char *pf = pFormat;
va_list valist = ap;
BUFFER_DESCRIPTOR BD;
BUFFER_DESCRIPTOR *pBD = &BD;
pBD->current_bytes = 0;
pBD->max_bytes = max_bytes - 4; // leave room for '\0' and overflow markers.
pBD->p = pBuf;
while (*pf)
{
if (pBD->current_bytes >= pBD->max_bytes)
break;
c = *pf++;
switch (c)
{
case '%':
width = 0;
fill_c = '\0';
c = *pf++;
// # spec is currently not implemented but recognized and silently ignored
if (c == '#')
c = *pf++;
if (c == '0')
{
fill_c = c;
c = *pf++;
}
// Leading zero and width spec is implemented only for x, u, & d formats.
// It is recognized but silently ignored for other formats.
while ((c >= '0') && (c <= '9'))
{
width = (width*10) + (c & 0xf);
c = *pf++;
}
switch (c)
{
case 'x':
PutHex(va_arg(valist, unsigned long), width, 0, fill_c, pBD);
break;
case 'X':
PutHex(va_arg(valist, unsigned long), width, 1, fill_c, pBD);
break;
case 'b':
PutHex(va_arg(valist, unsigned long), 2, 0, fill_c, pBD);
break;
case 'B':
PutHex(va_arg(valist, unsigned long), 2, 1, fill_c, pBD);
break;
case 'h':
PutHex(va_arg(valist, unsigned long), 4, 0, fill_c, pBD);
break;
case 'H':
PutHex(va_arg(valist, unsigned long), 4, 1, fill_c, pBD);
break;
case 'd':
{
long d;
d = va_arg(valist, long);
if (d < 0)
{
PutByte('-', pBD);
d = d * -1;
}
else
if (width != 0)
PutByte(' ', pBD);
PutDecimal((unsigned long)d, width, fill_c, pBD);
}
break;
case 'u':
PutDecimal(va_arg(valist, unsigned long), width, fill_c, pBD);
break;
case 's':
PutString(va_arg(valist, char *), pBD);
break;
case '%':
PutByte('%', pBD);
break;
case 'c':
c = va_arg(valist, unsigned char);
PutByte(c, pBD);
break;
default:
PutByte('%', pBD);
PutByte(c, pBD);
// ignore the value argument too so any remaining items aren't messed up
va_arg(valist, unsigned long);
break;
}
break;
default:
PutByte(c, pBD);
break;
}
}
if (pBD->current_bytes == pBD->max_bytes)
{
pBD->p[pBD->current_bytes++] = '>';
pBD->p[pBD->current_bytes++] = '\r';
pBD->p[pBD->current_bytes++] = '\n';
}
pBD->p[pBD->current_bytes] = '\0';
return(pBD->current_bytes);
} // xllp_vsnprintf
unsigned long xllp_snprintf(unsigned char *pBuf, unsigned long max_bytes, const unsigned char *pFormat, ...)
{
va_list valist;
unsigned long ret;
va_start(valist, pFormat);
ret = xllp_vsnprintf(pBuf, max_bytes, pFormat, valist);
va_end(valist);
return(ret);
} // xllp_snprintf
unsigned long xllp_LogMessage(const unsigned char *pFormat, ...)
{
unsigned char MsgBuf[XLLP_LOGMESSAGE_MAX_BYTES + 4];
va_list valist;
unsigned long ret;
va_start(valist, pFormat);
ret = xllp_vsnprintf(MsgBuf, sizeof(MsgBuf), pFormat, valist);
OSD_LogMessage(MsgBuf);
va_end(valist);
return(ret);
} // xllp_LogMessage
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -